Done !
| Server IP : 46.105.57.169 / Your IP : 216.73.217.35 Web Server : Apache System : Linux webm002.cluster120.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64 User : verseaumee ( 152031) PHP Version : 8.5.7 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/verseaumee/123click/assets/ |
Upload File : |
updatenotification/updatenotification.xml 0000604 00000003076 15075053024 0015053 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>plg_system_updatenotification</name>
<author>Joomla! Project</author>
<creationDate>May 2015</creationDate>
<copyright>(C) 2015 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.5.0</version>
<description>PLG_SYSTEM_UPDATENOTIFICATION_XML_DESCRIPTION</description>
<files>
<filename plugin="updatenotification">updatenotification.php</filename>
</files>
<languages folder="language">
<language tag="en-GB">language/en-GB/plg_system_updatenotification.ini</language>
<language tag="en-GB">language/en-GB/plg_system_updatenotification.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="email"
type="text"
label="PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_LBL"
description="PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_DESC"
default=""
size="40"
/>
<field
name="language_override"
type="language"
label="PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_LBL"
description="PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_DESC"
default=""
client="administrator"
>
<option value="">PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_NONE</option>
</field>
<field
name="lastrun"
type="hidden"
default="0"
size="15"
/>
</fieldset>
</fields>
</config>
</extension>
updatenotification/updatenotification.php 0000604 00000026520 15075053024 0015041 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.updatenotification
*
* @copyright (C) 2015 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\Access\Access;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Extension\ExtensionHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Mail\Exception\MailDisabledException;
use Joomla\CMS\Mail\MailTemplate;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Updater\Updater;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Version;
use Joomla\Database\ParameterType;
use PHPMailer\PHPMailer\Exception as phpMailerException;
// Uncomment the following line to enable debug mode (update notification email sent every single time)
// define('PLG_SYSTEM_UPDATENOTIFICATION_DEBUG', 1);
/**
* Joomla! Update Notification plugin
*
* Sends out an email to all Super Users or a predefined list of email addresses of Super Users when a new
* Joomla! version is available.
*
* This plugin is a direct adaptation of the corresponding plugin in Akeeba Ltd's Admin Tools. The author has
* consented to relicensing their plugin's code under GPLv2 or later (the original version was licensed under
* GPLv3 or later) to allow its inclusion in the Joomla! CMS.
*
* @since 3.5
*/
class PlgSystemUpdatenotification extends CMSPlugin
{
/**
* Application object
*
* @var \Joomla\CMS\Application\CMSApplication
* @since 4.0.0
*/
protected $app;
/**
* Database driver
*
* @var \Joomla\Database\DatabaseInterface
* @since 4.0.0
*/
protected $db;
/**
* Load plugin language files automatically
*
* @var boolean
* @since 3.6.3
*/
protected $autoloadLanguage = true;
/**
* The update check and notification email code is triggered after the page has fully rendered.
*
* @return void
*
* @since 3.5
*/
public function onAfterRender()
{
// Get the timeout for Joomla! updates, as configured in com_installer's component parameters
$component = ComponentHelper::getComponent('com_installer');
/** @var \Joomla\Registry\Registry $params */
$params = $component->getParams();
$cache_timeout = (int) $params->get('cachetimeout', 6);
$cache_timeout = 3600 * $cache_timeout;
// 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 (!defined('PLG_SYSTEM_UPDATENOTIFICATION_DEBUG') && (abs($now - $last) < $cache_timeout))
{
return;
}
// Update last run status
// If I have the time of the last run, I can update, otherwise insert
$this->params->set('lastrun', $now);
$db = $this->db;
$paramsJson = $this->params->toString('JSON');
$query = $db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('params') . ' = :params')
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
->where($db->quoteName('element') . ' = ' . $db->quote('updatenotification'))
->bind(':params', $paramsJson);
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(['com_plugins']);
}
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;
}
// This is the extension ID for Joomla! itself
$eid = ExtensionHelper::getExtensionRecord('joomla', 'file')->extension_id;
// Get any available updates
$updater = Updater::getInstance();
$results = $updater->findUpdates([$eid], $cache_timeout);
// If there are no updates our job is done. We need BOTH this check AND the one below.
if (!$results)
{
return;
}
// Get the update model and retrieve the Joomla! core updates
$model = $this->app->bootComponent('com_installer')
->getMVCFactory()->createModel('Update', 'Administrator', ['ignore_request' => true]);
$model->setState('filter.extension_id', $eid);
$updates = $model->getItems();
// If there are no updates we don't have to notify anyone about anything. This is NOT a duplicate check.
if (empty($updates))
{
return;
}
// Get the available update
$update = array_pop($updates);
// Check the available version. If it's the same or less than the installed version we have no updates to notify about.
if (version_compare($update->version, JVERSION, 'le'))
{
return;
}
// If we're here, we have updates. First, get a link to the Joomla! Update component.
$baseURL = Uri::base();
$baseURL = rtrim($baseURL, '/');
$baseURL .= (substr($baseURL, -13) !== 'administrator') ? '/administrator/' : '/';
$baseURL .= 'index.php?option=com_joomlaupdate';
$uri = new Uri($baseURL);
/**
* Some third party security solutions require a secret query parameter to allow log in to the administrator
* backend of the site. The link generated above will be invalid and could probably block the user out of their
* site, confusing them (they can't understand the third party security solution is not part of Joomla! proper).
* So, we're calling the onBuildAdministratorLoginURL system plugin event to let these third party solutions
* add any necessary secret query parameters to the URL. The plugins are supposed to have a method with the
* signature:
*
* public function onBuildAdministratorLoginURL(Uri &$uri);
*
* The plugins should modify the $uri object directly and return null.
*/
$this->app->triggerEvent('onBuildAdministratorLoginURL', [&$uri]);
// Let's find out the email addresses to notify
$superUsers = [];
$specificEmail = $this->params->get('email', '');
if (!empty($specificEmail))
{
$superUsers = $this->getSuperUsers($specificEmail);
}
if (empty($superUsers))
{
$superUsers = $this->getSuperUsers();
}
if (empty($superUsers))
{
return;
}
/*
* Load the appropriate language. We try to load English (UK), the current user's language and the forced
* language preference, in this order. This ensures that we'll never end up with untranslated strings in the
* update email which would make Joomla! seem bad. So, please, if you don't fully understand what the
* following code does DO NOT TOUCH IT. It makes the difference between a hobbyist CMS and a professional
* solution!
*/
$jLanguage = $this->app->getLanguage();
$jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, 'en-GB', true, true);
$jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, null, true, false);
// Then try loading the preferred (forced) language
$forcedLanguage = $this->params->get('language_override', '');
if (!empty($forcedLanguage))
{
$jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, $forcedLanguage, true, false);
}
// Replace merge codes with their values
$newVersion = $update->version;
$jVersion = new Version;
$currentVersion = $jVersion->getShortVersion();
$sitename = $this->app->get('sitename');
$substitutions = [
'newversion' => $newVersion,
'curversion' => $currentVersion,
'sitename' => $sitename,
'url' => Uri::base(),
'link' => $uri->toString(),
'releasenews' => 'https://www.joomla.org/announcements/release-news/',
];
// Send the emails to the Super Users
foreach ($superUsers as $superUser)
{
try
{
$mailer = new MailTemplate('plg_system_updatenotification.mail', $jLanguage->getTag());
$mailer->addRecipient($superUser->email);
$mailer->addTemplateData($substitutions);
$mailer->send();
}
catch (MailDisabledException | phpMailerException $exception)
{
try
{
Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror');
}
catch (\RuntimeException $exception)
{
$this->app->enqueueMessage(Text::_($exception->errorMessage()), 'warning');
}
}
}
}
/**
* Returns the Super Users email information. If you provide a comma separated $email list
* we will check that these emails do belong to Super Users and that they have not blocked
* system emails.
*
* @param null|string $email A list of Super Users to email
*
* @return array The list of Super User emails
*
* @since 3.5
*/
private function getSuperUsers($email = null)
{
$db = $this->db;
$emails = [];
// Convert the email list to an array
if (!empty($email))
{
$temp = explode(',', $email);
foreach ($temp as $entry)
{
$emails[] = trim($entry);
}
$emails = array_unique($emails);
}
// Get a list of groups which have Super User privileges
$ret = [];
try
{
$rootId = Table::getInstance('Asset')->getRootId();
$rules = Access::getAssetRules($rootId)->getData();
$rawGroups = $rules['core.admin']->getData();
$groups = [];
if (empty($rawGroups))
{
return $ret;
}
foreach ($rawGroups as $g => $enabled)
{
if ($enabled)
{
$groups[] = $g;
}
}
if (empty($groups))
{
return $ret;
}
}
catch (Exception $exc)
{
return $ret;
}
// Get the user IDs of users belonging to the SA groups
try
{
$query = $db->getQuery(true)
->select($db->quoteName('user_id'))
->from($db->quoteName('#__user_usergroup_map'))
->whereIn($db->quoteName('group_id'), $groups);
$db->setQuery($query);
$userIDs = $db->loadColumn(0);
if (empty($userIDs))
{
return $ret;
}
}
catch (Exception $exc)
{
return $ret;
}
// Get the user information for the Super Administrator users
try
{
$query = $db->getQuery(true)
->select($db->quoteName(['id', 'username', 'email']))
->from($db->quoteName('#__users'))
->whereIn($db->quoteName('id'), $userIDs)
->where($db->quoteName('block') . ' = 0')
->where($db->quoteName('sendEmail') . ' = 1');
if (!empty($emails))
{
$lowerCaseEmails = array_map('strtolower', $emails);
$query->whereIn('LOWER(' . $db->quoteName('email') . ')', $lowerCaseEmails, ParameterType::STRING);
}
$db->setQuery($query);
$ret = $db->loadObjectList();
}
catch (Exception $exc)
{
return $ret;
}
return $ret;
}
/**
* 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
*
* @return void
*
* @since 3.5
*/
private function clearCacheGroups(array $clearGroups)
{
foreach ($clearGroups as $group)
{
try
{
$options = [
'defaultgroup' => $group,
'cachebase' => $this->app->get('cache_path', JPATH_CACHE),
];
$cache = Cache::getInstance('callback', $options);
$cache->clean();
}
catch (Exception $e)
{
// Ignore it
}
}
}
}
updatenotification/postinstall/updatecachetime.php 0000604 00000003003 15075053024 0016640 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.updatenotification
*
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Table\Table;
/**
* Checks if the com_installer config for the cache Hours are eq 0 and the updatenotification Plugin is enabled
*
* @return boolean
*
* @since 3.6.3
*/
function updatecachetime_postinstall_condition()
{
$cacheTimeout = (int) ComponentHelper::getComponent('com_installer')->params->get('cachetimeout', 6);
// Check if cachetimeout is eq zero
if ($cacheTimeout === 0 && PluginHelper::isEnabled('system', 'updatenotification'))
{
return true;
}
return false;
}
/**
* Sets the cachetimeout back to the default (6 hours)
*
* @return void
*
* @since 3.6.3
*/
function updatecachetime_postinstall_action()
{
$installer = ComponentHelper::getComponent('com_installer');
// Sets the cachetimeout back to the default (6 hours)
$installer->params->set('cachetimeout', 6);
// Save the new parameters back to com_installer
$table = Table::getInstance('extension');
$table->load($installer->id);
$table->bind(array('params' => $installer->params->toString()));
// Store the changes
if (!$table->store())
{
// If there is an error show it to the admin
Factory::getApplication()->enqueueMessage($table->getError(), 'error');
}
}
k2/k2.xml 0000604 00000001465 15075053024 0006121 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="2.5" type="plugin" group="system" method="upgrade">
<name>System - K2</name>
<author>JoomlaWorks</author>
<creationDate>September 21st, 2018</creationDate>
<copyright>Copyright (c) 2006 - 2018 JoomlaWorks Ltd. All rights reserved.</copyright>
<authorEmail>please-use-the-contact-form@joomlaworks.net</authorEmail>
<authorUrl>www.joomlaworks.net</authorUrl>
<version>2.9.0</version>
<license>http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL</license>
<description>K2_THE_K2_SYSTEM_PLUGIN_IS_USED_TO_ASSIST_THE_PROPER_FUNCTIONALITY_OF_THE_K2_COMPONENT_SITE_WIDE_MAKE_SURE_ITS_ALWAYS_PUBLISHED_WHEN_THE_K2_COMPONENT_IS_INSTALLED</description>
<files>
<filename plugin="k2">k2.php</filename>
</files>
</extension>
k2/k2.php 0000604 00000112740 15075053024 0006107 0 ustar 00 <?php
/**
* @version 2.9.x
* @package K2
* @author JoomlaWorks https://www.joomlaworks.net
* @copyright Copyright (c) 2006 - 2018 JoomlaWorks Ltd. All rights reserved.
* @license GNU/GPL license: http://www.gnu.org/copyleft/gpl.html
*/
// no direct access
defined('_JEXEC') or die;
jimport('joomla.plugin.plugin');
class plgSystemK2 extends JPlugin
{
public function onAfterInitialise()
{
// Determine Joomla version
if (version_compare(JVERSION, '3.0', 'ge')) {
define('K2_JVERSION', '30');
} elseif (version_compare(JVERSION, '2.5', 'ge')) {
define('K2_JVERSION', '25');
} else {
define('K2_JVERSION', '15');
}
// Define K2 version & build here
define('K2_CURRENT_VERSION', '2.9.0');
define('K2_BUILD', ''); // Use '' for stable or ' [Dev Build YYYYMMDD]' for the developer build
// Define the DS constant (for backwards compatibility with old template overrides & 3rd party K2 extensions)
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
// Import Joomla classes
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
jimport('joomla.application.component.controller');
jimport('joomla.application.component.model');
jimport('joomla.application.component.view');
// Get application & K2 component params
$application = JFactory::getApplication();
$params = JComponentHelper::getParams('com_k2');
// Load the K2 classes
JLoader::register('K2Table', JPATH_ADMINISTRATOR.'/components/com_k2/tables/table.php');
JLoader::register('K2Controller', JPATH_BASE.'/components/com_k2/controllers/controller.php');
JLoader::register('K2Model', JPATH_ADMINISTRATOR.'/components/com_k2/models/model.php');
if ($application->isSite()) {
K2Model::addIncludePath(JPATH_SITE.'/components/com_k2/models');
} else {
// Fix warning under Joomla 1.5 caused by conflict in model names
if (K2_JVERSION != '15' || (K2_JVERSION == '15' && JRequest::getCmd('option') != 'com_users')) {
K2Model::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_k2/models');
}
}
JLoader::register('K2View', JPATH_ADMINISTRATOR.'/components/com_k2/views/view.php');
JLoader::register('K2HelperHTML', JPATH_ADMINISTRATOR.'/components/com_k2/helpers/html.php');
JLoader::register('K2HelperUtilities', JPATH_SITE.'/components/com_k2/helpers/utilities.php');
// Define the default Itemid for users and tags (to be removed)
//define('K2_USERS_ITEMID', $params->get('defaultUsersItemid'));
//define('K2_TAGS_ITEMID', $params->get('defaultTagsItemid'));
// Custom HTTP headers
$user = JFactory::getUser();
if (!$user->guest) {
JResponse::setHeader('X-Logged-In', 'True', true);
} else {
JResponse::setHeader('X-Logged-In', 'False', true);
}
JResponse::setHeader('X-Content-Powered-By', 'K2 v'.K2_CURRENT_VERSION.' (by JoomlaWorks)', true);
// Define JoomFish compatibility version.
if (JFile::exists(JPATH_ADMINISTRATOR.'/components/com_joomfish/joomfish.php')) {
if (K2_JVERSION == '15') {
$db = JFactory::getDbo();
$config = JFactory::getConfig();
$prefix = $config->getValue('config.dbprefix');
if (array_key_exists($prefix.'_jf_languages_ext', $db->getTableList())) {
define('K2_JF_ID', 'lang_id');
} else {
define('K2_JF_ID', 'id');
}
} else {
define('K2_JF_ID', 'lang_id');
}
}
// Backend only
if (!$application->isAdmin()) {
return;
}
// K2 Metrics
if ($application->isAdmin() && $params->get('gatherStatistics', 1)) {
$option = JRequest::getCmd('option');
$view = JRequest::getCmd('view');
$viewsToRun = array('items', 'categories', 'tags', 'comments', 'users', 'usergroups', 'extrafields', 'extrafieldsgroups', '');
if ($option == 'com_k2' && in_array($view, $viewsToRun)) {
require_once(JPATH_ADMINISTRATOR.'/components/com_k2/helpers/stats.php');
if (K2HelperStats::shouldLog()) {
K2HelperStats::getScripts();
}
}
}
// --- JoomFish integration [start] ---
if ((int)K2_JVERSION < 25) {
$option = JRequest::getCmd('option');
$task = JRequest::getCmd('task');
$type = JRequest::getCmd('catid');
} else {
$option = JFactory::getApplication()->input->get('option');
$task = JFactory::getApplication()->input->get('task');
$type = JRequest::getCmd('catid');
}
if ($option == 'com_joomfish') {
JPlugin::loadLanguage('com_k2', JPATH_ADMINISTRATOR);
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_k2/tables');
if (($task == 'translate.apply' || $task == 'translate.save') && $type == 'k2_items') {
$language_id = JRequest::getInt('select_language_id');
$reference_id = JRequest::getInt('reference_id');
$objects = array();
$variables = JRequest::get('post');
foreach ($variables as $key => $value) {
if (( bool )JString::stristr($key, 'K2ExtraField_')) {
$object = new JObject;
$object->set('id', JString::substr($key, 13));
$object->set('value', $value);
unset($object->_errors);
$objects[] = $object;
}
}
$extra_fields = json_encode($objects);
$extra_fields_search = '';
foreach ($objects as $object) {
$extra_fields_search .= $this->getSearchValue($object->id, $object->value);
$extra_fields_search .= ' ';
}
$user = JFactory::getUser();
$db = JFactory::getDbo();
$query = "SELECT COUNT(*) FROM #__jf_content WHERE reference_field = 'extra_fields' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_items'";
$db->setQuery($query);
$result = $db->loadResult();
if ($result > 0) {
$query = "UPDATE #__jf_content SET value=".$db->Quote($extra_fields)." WHERE reference_field = 'extra_fields' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_items'";
$db->setQuery($query);
$db->query();
} else {
$modified = date("Y-m-d H:i:s");
$modified_by = $user->id;
$published = JRequest::getVar('published', 0);
$query = "INSERT INTO #__jf_content (`id`, `language_id`, `reference_id`, `reference_table`, `reference_field` ,`value`, `original_value`, `original_text`, `modified`, `modified_by`, `published`) VALUES (NULL, {$language_id}, {$reference_id}, 'k2_items', 'extra_fields', ".$db->Quote($extra_fields).", '','', ".$db->Quote($modified).", {$modified_by}, {$published} )";
$db->setQuery($query);
$db->query();
}
$query = "SELECT COUNT(*) FROM #__jf_content WHERE reference_field = 'extra_fields_search' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_items'";
$db->setQuery($query);
$result = $db->loadResult();
if ($result > 0) {
$query = "UPDATE #__jf_content SET value=".$db->Quote($extra_fields_search)." WHERE reference_field = 'extra_fields_search' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_items'";
$db->setQuery($query);
$db->query();
} else {
$modified = date("Y-m-d H:i:s");
$modified_by = $user->id;
$published = JRequest::getVar('published', 0);
$query = "INSERT INTO #__jf_content (`id`, `language_id`, `reference_id`, `reference_table`, `reference_field` ,`value`, `original_value`, `original_text`, `modified`, `modified_by`, `published`) VALUES (NULL, {$language_id}, {$reference_id}, 'k2_items', 'extra_fields_search', ".$db->Quote($extra_fields_search).", '','', ".$db->Quote($modified).", {$modified_by}, {$published} )";
$db->setQuery($query);
$db->query();
}
}
if (($task == 'translate.edit' || $task == 'translate.apply') && $type == 'k2_items') {
if ($task == 'translate.edit') {
$cid = JRequest::getVar('cid');
$array = explode('|', $cid[0]);
$reference_id = $array[1];
}
if ($task == 'translate.apply') {
$reference_id = JRequest::getInt('reference_id');
}
$item = JTable::getInstance('K2Item', 'Table');
$item->load($reference_id);
$category_id = $item->catid;
$language_id = JRequest::getInt('select_language_id');
$category = JTable::getInstance('K2Category', 'Table');
$category->load($category_id);
$group = $category->extraFieldsGroup;
$db = JFactory::getDbo();
$query = "SELECT * FROM #__k2_extra_fields WHERE `group`=".$db->Quote($group)." AND published=1 ORDER BY ordering";
$db->setQuery($query);
$extraFields = $db->loadObjectList();
$output = '';
if (count($extraFields)) {
$output .= '<h1>'.JText::_('K2_EXTRA_FIELDS').'</h1>';
$output .= '<h2>'.JText::_('K2_ORIGINAL').'</h2>';
foreach ($extraFields as $extrafield) {
$extraField = json_decode($extrafield->value);
$output .= trim($this->renderOriginal($extrafield, $reference_id));
}
}
if (count($extraFields)) {
$output .= '<h2>'.JText::_('K2_TRANSLATION').'</h2>';
foreach ($extraFields as $extrafield) {
$extraField = json_decode($extrafield->value);
$output .= trim($this->renderTranslated($extrafield, $reference_id));
}
}
$pattern = '/\r\n|\r|\n/';
// Load CSS & JS
if (K2_JVERSION == '15') {
JHTML::_('behavior.mootools');
} else {
JHTML::_('behavior.framework');
}
$document = JFactory::getDocument();
$document->addScriptDeclaration("
window.addEvent('domready', function(){
var target = $$('table.adminform');
target.setProperty('id', 'adminform');
var div = new Element('div', {'id': 'K2ExtraFields'}).setHTML('".preg_replace($pattern, '', $output)."').injectInside($('adminform'));
});
");
}
if (($task == 'translate.apply' || $task == 'translate.save') && $type == 'k2_extra_fields') {
$language_id = JRequest::getInt('select_language_id');
$reference_id = JRequest::getInt('reference_id');
$extraFieldType = JRequest::getVar('extraFieldType');
$objects = array();
$values = JRequest::getVar('option_value');
$names = JRequest::getVar('option_name');
$target = JRequest::getVar('option_target');
for ($i = 0; $i < sizeof($values); $i++) {
$object = new JObject;
$object->set('name', $names[$i]);
if ($extraFieldType == 'select' || $extraFieldType == 'multipleSelect' || $extraFieldType == 'radio') {
$object->set('value', $i + 1);
} elseif ($extraFieldType == 'link') {
if (substr($values[$i], 0, 7) == 'http://') {
$values[$i] = $values[$i];
} else {
$values[$i] = 'http://'.$values[$i];
}
$object->set('value', $values[$i]);
} else {
$object->set('value', $values[$i]);
}
$object->set('target', $target[$i]);
unset($object->_errors);
$objects[] = $object;
}
$value = json_encode($objects);
$user = JFactory::getUser();
$db = JFactory::getDbo();
$query = "SELECT COUNT(*) FROM #__jf_content WHERE reference_field = 'value' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_extra_fields'";
$db->setQuery($query);
$result = $db->loadResult();
if ($result > 0) {
$query = "UPDATE #__jf_content SET value=".$db->Quote($value)." WHERE reference_field = 'value' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_extra_fields'";
$db->setQuery($query);
$db->query();
} else {
$modified = date("Y-m-d H:i:s");
$modified_by = $user->id;
$published = JRequest::getVar('published', 0);
$query = "INSERT INTO #__jf_content (`id`, `language_id`, `reference_id`, `reference_table`, `reference_field` ,`value`, `original_value`, `original_text`, `modified`, `modified_by`, `published`) VALUES (NULL, {$language_id}, {$reference_id}, 'k2_extra_fields', 'value', ".$db->Quote($value).", '','', ".$db->Quote($modified).", {$modified_by}, {$published} )";
$db->setQuery($query);
$db->query();
}
}
if (($task == 'translate.edit' || $task == 'translate.apply') && $type == 'k2_extra_fields') {
if ($task == 'translate.edit') {
$cid = JRequest::getVar('cid');
$array = explode('|', $cid[0]);
$reference_id = $array[1];
}
if ($task == 'translate.apply') {
$reference_id = JRequest::getInt('reference_id');
}
$extraField = JTable::getInstance('K2ExtraField', 'Table');
$extraField->load($reference_id);
$language_id = JRequest::getInt('select_language_id');
if ($extraField->type == 'multipleSelect' || $extraField->type == 'select' || $extraField->type == 'radio') {
$subheader = '<strong>'.JText::_('K2_OPTIONS').'</strong>';
} else {
$subheader = '<strong>'.JText::_('K2_DEFAULT_VALUE').'</strong>';
}
$objects = json_decode($extraField->value);
$output = '<input type="hidden" value="'.$extraField->type.'" name="extraFieldType" />';
if (count($objects)) {
$output .= '<h1>'.JText::_('K2_EXTRA_FIELDS').'</h1>';
$output .= '<h2>'.JText::_('K2_ORIGINAL').'</h2>';
$output .= $subheader.'<br />';
foreach ($objects as $object) {
$output .= '<p>'.$object->name.'</p>';
if ($extraField->type == 'textfield' || $extraField->type == 'textarea') {
$output .= '<p>'.$object->value.'</p>';
}
}
}
$db = JFactory::getDbo();
$query = "SELECT `value` FROM #__jf_content WHERE reference_field = 'value' AND language_id = {$language_id} AND reference_id = {$reference_id} AND reference_table='k2_extra_fields'";
$db->setQuery($query);
$result = $db->loadResult();
$translatedObjects = json_decode($result);
if (count($objects)) {
$output .= '<h2>'.JText::_('K2_TRANSLATION').'</h2>';
$output .= $subheader.'<br />';
foreach ($objects as $key => $value) {
if (isset($translatedObjects[$key])) {
$value = $translatedObjects[$key];
}
if ($extraField->type == 'textarea') {
$output .= '<p><textarea name="option_name[]" cols="30" rows="15"> '.$value->name.'</textarea></p>';
} else {
$output .= '<p><input type="text" name="option_name[]" value="'.$value->name.'" /></p>';
}
$output .= '<p><input type="hidden" name="option_value[]" value="'.$value->value.'" /></p>';
$output .= '<p><input type="hidden" name="option_target[]" value="'.$value->target.'" /></p>';
}
}
$pattern = '/\r\n|\r|\n/';
// Load CSS & JS
if (K2_JVERSION == '15') {
JHTML::_('behavior.mootools');
} else {
JHtml::_('behavior.framework');
}
$document = JFactory::getDocument();
$document->addScriptDeclaration("
window.addEvent('domready', function(){
var target = $$('table.adminform');
target.setProperty('id', 'adminform');
var div = new Element('div', {'id': 'K2ExtraFields'}).setHTML('".preg_replace($pattern, '', $output)."').injectInside($('adminform'));
});
");
}
}
// --- JoomFish integration [finish] ---
return;
}
public function onAfterRoute()
{
$application = JFactory::getApplication();
$document = JFactory::getDocument();
$user = JFactory::getUser();
$params = JComponentHelper::getParams('com_k2');
$basepath = ($application->isSite()) ? JPATH_SITE : JPATH_ADMINISTRATOR;
JPlugin::loadLanguage('com_k2', $basepath);
if (K2_JVERSION != '15') {
JPlugin::loadLanguage('com_k2.dates', JPATH_ADMINISTRATOR, null, true);
}
if ($application->isAdmin() || (JRequest::getCmd('option') == 'com_k2' && (JRequest::getCmd('task') == 'add' || JRequest::getCmd('task') == 'edit'))) {
return;
}
// Load required CSS & JS
K2HelperHTML::loadHeadIncludes();
}
public function onAfterDispatch()
{
$application = JFactory::getApplication();
if ($application->isAdmin()) {
return;
}
$params = JComponentHelper::getParams('com_k2');
if (!$params->get('K2UserProfile')) {
return;
}
$document = JFactory::getDocument();
$option = JRequest::getCmd('option');
$view = JRequest::getCmd('view');
$task = JRequest::getCmd('task');
$layout = JRequest::getCmd('layout');
$user = JFactory::getUser();
if (K2_JVERSION != '15') {
$active = JFactory::getApplication()->getMenu()->getActive();
if (isset($active->query['layout'])) {
$layout = $active->query['layout'];
}
}
// Extend user forms with K2 fields
if (($option == 'com_user' && $view == 'register') || ($option == 'com_users' && $view == 'registration')) {
if ($params->get('recaptchaOnRegistration') && $params->get('recaptcha_public_key')) {
if ($params->get('recaptchaV2')) {
$document->addScript('https://www.google.com/recaptcha/api.js?onload=onK2RecaptchaLoaded&render=explicit');
$document->addScriptDeclaration('
/* K2 - Google reCAPTCHA */
function onK2RecaptchaLoaded(){
grecaptcha.render("recaptcha", {"sitekey": "'.$params->get('recaptcha_public_key').'"});
}
');
$recaptchaClass = 'k2-recaptcha-v2';
} else {
$document->addScript('https://www.google.com/recaptcha/api/js/recaptcha_ajax.js');
$document->addScriptDeclaration('
function showRecaptcha(){
Recaptcha.create("'.$params->get('recaptcha_public_key').'", "recaptcha", {
theme: "'.$params->get('recaptcha_theme', 'clean').'"
});
}
$K2(document).ready(function() {
showRecaptcha();
});
');
$recaptchaClass = 'k2-recaptcha-v1';
}
}
if (!$user->guest) {
$application->enqueueMessage(JText::_('K2_YOU_ARE_ALREADY_REGISTERED_AS_A_MEMBER'), 'notice');
$application->redirect(JURI::root());
$application->close();
}
if (K2_JVERSION != '15') {
require_once(JPATH_SITE.'/components/com_users/controller.php');
$controller = new UsersController;
} else {
require_once(JPATH_SITE.'/components/com_user/controller.php');
$controller = new UserController;
}
$view = $controller->getView($view, 'html');
$view->addTemplatePath(JPATH_SITE.'/components/com_k2/templates');
$view->addTemplatePath(JPATH_SITE.'/templates/'.$application->getTemplate().'/html/com_k2/templates');
$view->addTemplatePath(JPATH_SITE.'/templates/'.$application->getTemplate().'/html/com_k2');
// Allow temporary template loading with ?template=
$template = JRequest::getCmd('template');
if (isset($template)) {
$view->addTemplatePath(JPATH_SITE.'/templates/'.$template.'/html/com_k2');
}
$view->setLayout('register');
$K2User = new JObject;
$K2User->description = '';
$K2User->gender = 'm';
$K2User->image = '';
$K2User->url = '';
$K2User->plugins = '';
$wysiwyg = JFactory::getEditor();
$editor = $wysiwyg->display('description', $K2User->description, '100%', '250px', '', '', false);
$view->assignRef('editor', $editor);
$lists = array();
$genderOptions[] = JHTML::_('select.option', 'm', JText::_('K2_MALE'));
$genderOptions[] = JHTML::_('select.option', 'f', JText::_('K2_FEMALE'));
$lists['gender'] = JHTML::_('select.radiolist', $genderOptions, 'gender', '', 'value', 'text', $K2User->gender);
$view->assignRef('lists', $lists);
$view->assignRef('K2Params', $params);
$view->assignRef('recaptchaClass', $recaptchaClass);
JPluginHelper::importPlugin('k2');
$dispatcher = JDispatcher::getInstance();
$K2Plugins = $dispatcher->trigger('onRenderAdminForm', array(
&$K2User,
'user'
));
$view->assignRef('K2Plugins', $K2Plugins);
$view->assignRef('K2User', $K2User);
if (K2_JVERSION != '15') {
$view->assignRef('user', $user);
}
$pathway = $application->getPathway();
$pathway->setPathway(null);
$nameFieldName = K2_JVERSION != '15' ? 'jform[name]' : 'name';
$view->assignRef('nameFieldName', $nameFieldName);
$usernameFieldName = K2_JVERSION != '15' ? 'jform[username]' : 'username';
$view->assignRef('usernameFieldName', $usernameFieldName);
$emailFieldName = K2_JVERSION != '15' ? 'jform[email1]' : 'email';
$view->assignRef('emailFieldName', $emailFieldName);
$passwordFieldName = K2_JVERSION != '15' ? 'jform[password1]' : 'password';
$view->assignRef('passwordFieldName', $passwordFieldName);
$passwordVerifyFieldName = K2_JVERSION != '15' ? 'jform[password2]' : 'password2';
$view->assignRef('passwordVerifyFieldName', $passwordVerifyFieldName);
$optionValue = K2_JVERSION != '15' ? 'com_users' : 'com_user';
$view->assignRef('optionValue', $optionValue);
$taskValue = K2_JVERSION != '15' ? 'registration.register' : 'register_save';
$view->assignRef('taskValue', $taskValue);
ob_start();
$view->display();
$contents = ob_get_clean();
$document->setBuffer($contents, 'component');
}
if (($option == 'com_user' && $view == 'user' && ($task == 'edit' || $layout == 'form')) || ($option == 'com_users' && $view == 'profile' && ($layout == 'edit' || $task == 'profile.edit'))) {
if ($user->guest) {
$uri = JFactory::getURI();
if (K2_JVERSION != '15') {
$url = 'index.php?option=com_users&view=login&return='.base64_encode($uri->toString());
} else {
$url = 'index.php?option=com_user&view=login&return='.base64_encode($uri->toString());
}
$application->enqueueMessage(JText::_('K2_YOU_NEED_TO_LOGIN_FIRST'), 'notice');
$application->redirect(JRoute::_($url, false));
}
if (K2_JVERSION != '15') {
require_once(JPATH_SITE.'/components/com_users/controller.php');
$controller = new UsersController;
} else {
require_once(JPATH_SITE.'/components/com_user/controller.php');
$controller = new UserController;
}
$view = $controller->getView($view, 'html');
$view->addTemplatePath(JPATH_SITE.'/components/com_k2/templates');
$view->addTemplatePath(JPATH_SITE.'/templates/'.$application->getTemplate().'/html/com_k2/templates');
$view->addTemplatePath(JPATH_SITE.'/templates/'.$application->getTemplate().'/html/com_k2');
// Allow temporary template loading with ?template=
$template = JRequest::getCmd('template');
if (isset($template)) {
$view->addTemplatePath(JPATH_SITE.'/templates/'.$template.'/html/com_k2');
}
$view->setLayout('profile');
$model = K2Model::getInstance('Itemlist', 'K2Model');
$K2User = $model->getUserProfile($user->id);
if (!is_object($K2User)) {
$K2User = new Jobject;
$K2User->description = '';
$K2User->gender = 'm';
$K2User->url = '';
$K2User->image = null;
}
if (K2_JVERSION == '15') {
JFilterOutput::objectHTMLSafe($K2User);
} else {
JFilterOutput::objectHTMLSafe($K2User, ENT_QUOTES, array(
'params',
'plugins'
));
}
$wysiwyg = JFactory::getEditor();
$editor = $wysiwyg->display('description', $K2User->description, '100%', '250px', '', '', false);
$view->assignRef('editor', $editor);
$lists = array();
$genderOptions[] = JHTML::_('select.option', 'm', JText::_('K2_MALE'));
$genderOptions[] = JHTML::_('select.option', 'f', JText::_('K2_FEMALE'));
$lists['gender'] = JHTML::_('select.radiolist', $genderOptions, 'gender', '', 'value', 'text', $K2User->gender);
$view->assignRef('lists', $lists);
JPluginHelper::importPlugin('k2');
$dispatcher = JDispatcher::getInstance();
$K2Plugins = $dispatcher->trigger('onRenderAdminForm', array(
&$K2User,
'user'
));
$view->assignRef('K2Plugins', $K2Plugins);
$view->assignRef('K2User', $K2User);
// Asssign some variables depending on Joomla version
$nameFieldName = K2_JVERSION != '15' ? 'jform[name]' : 'name';
$view->assignRef('nameFieldName', $nameFieldName);
$emailFieldName = K2_JVERSION != '15' ? 'jform[email1]' : 'email';
$view->assignRef('emailFieldName', $emailFieldName);
$passwordFieldName = K2_JVERSION != '15' ? 'jform[password1]' : 'password';
$view->assignRef('passwordFieldName', $passwordFieldName);
$passwordVerifyFieldName = K2_JVERSION != '15' ? 'jform[password2]' : 'password2';
$view->assignRef('passwordVerifyFieldName', $passwordVerifyFieldName);
$usernameFieldName = K2_JVERSION != '15' ? 'jform[username]' : 'username';
$view->assignRef('usernameFieldName', $usernameFieldName);
$idFieldName = K2_JVERSION != '15' ? 'jform[id]' : 'id';
$view->assignRef('idFieldName', $idFieldName);
$optionValue = K2_JVERSION != '15' ? 'com_users' : 'com_user';
$view->assignRef('optionValue', $optionValue);
$taskValue = K2_JVERSION != '15' ? 'profile.save' : 'save';
$view->assignRef('taskValue', $taskValue);
ob_start();
if (K2_JVERSION != '15') {
$active = JFactory::getApplication()->getMenu()->getActive();
if (isset($active->query['layout']) && $active->query['layout'] != 'profile') {
$active->query['layout'] = 'profile';
}
$view->assignRef('user', $user);
$view->display();
} else {
$view->_displayForm();
}
$contents = ob_get_clean();
$document->setBuffer($contents, 'component');
}
}
public function onAfterRender()
{
$application = JFactory::getApplication();
$params = JComponentHelper::getParams('com_k2');
// Fix OpenGraph meta tags
if ($application->isSite() && $params->get('facebookMetatags', 1)) {
$response = JResponse::getBody();
$searches = array(
'<meta name="og:url"',
'<meta name="og:title"',
'<meta name="og:type"',
'<meta name="og:image"',
'<meta name="og:description"'
);
$replacements = array(
'<meta property="og:url"',
'<meta property="og:title"',
'<meta property="og:type"',
'<meta property="og:image"',
'<meta property="og:description"'
);
if (JString::strpos($response, 'prefix="og: http://ogp.me/ns#"') === false) {
$searches[] = '<html ';
$searches[] = '<html>';
$replacements[] = '<html prefix="og: http://ogp.me/ns#" ';
$replacements[] = '<html prefix="og: http://ogp.me/ns#">';
}
$response = JString::str_ireplace($searches, $replacements, $response);
JResponse::setBody($response);
}
}
/* ============================================ */
/* ============= Helper Functions ============= */
/* ============================================ */
public function getSearchValue($id, $currentValue)
{
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_k2/tables');
$row = JTable::getInstance('K2ExtraField', 'Table');
$row->load($id);
$jsonObject = json_decode($row->value);
$value = '';
if ($row->type == 'textfield' || $row->type == 'textarea') {
$value = $currentValue;
} elseif ($row->type == 'multipleSelect' || $row->type == 'link') {
foreach ($jsonObject as $option) {
if (@in_array($option->value, $currentValue)) {
$value .= $option->name.' ';
}
}
} else {
foreach ($jsonObject as $option) {
if ($option->value == $currentValue) {
$value .= $option->name;
}
}
}
return $value;
}
public function renderOriginal($extraField, $itemID)
{
$application = JFactory::getApplication();
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_k2/tables');
$item = JTable::getInstance('K2Item', 'Table');
$item->load($itemID);
$defaultValues = json_decode($extraField->value);
foreach ($defaultValues as $value) {
if ($extraField->type == 'textfield' || $extraField->type == 'textarea') {
$active = $value->value;
} elseif ($extraField->type == 'link') {
$active[0] = $value->name;
$active[1] = $value->value;
$active[2] = $value->target;
} else {
$active = '';
}
}
if (isset($item)) {
$currentValues = json_decode($item->extra_fields);
if (count($currentValues)) {
foreach ($currentValues as $value) {
if ($value->id == $extraField->id) {
$active = $value->value;
}
}
}
}
$output = '';
switch ($extraField->type) {
case 'textfield':
$output = '<div><strong>'.$extraField->name.'</strong><br /><input type="text" disabled="disabled" name="OriginalK2ExtraField_'.$extraField->id.'" value="'.$active.'" /></div><br /><br />';
break;
case 'textarea':
$output = '<div><strong>'.$extraField->name.'</strong><br /><textarea disabled="disabled" name="OriginalK2ExtraField_'.$extraField->id.'" rows="10" cols="40">'.$active.'</textarea></div><br /><br />';
break;
case 'link':
$output = '<div><strong>'.$extraField->name.'</strong><br /><input disabled="disabled" type="text" name="OriginalK2ExtraField_'.$extraField->id.'[]" value="'.$active[0].'" /></div><br /><br />';
break;
}
return $output;
}
public function renderTranslated($extraField, $itemID)
{
$application = JFactory::getApplication();
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_k2/tables');
$item = JTable::getInstance('K2Item', 'Table');
$item->load($itemID);
$defaultValues = json_decode($extraField->value);
foreach ($defaultValues as $value) {
if ($extraField->type == 'textfield' || $extraField->type == 'textarea') {
$active = $value->value;
} elseif ($extraField->type == 'link') {
$active[0] = $value->name;
$active[1] = $value->value;
$active[2] = $value->target;
} else {
$active = '';
}
}
if (isset($item)) {
$currentValues = json_decode($item->extra_fields);
if (count($currentValues)) {
foreach ($currentValues as $value) {
if ($value->id == $extraField->id) {
$active = $value->value;
}
}
}
}
$language_id = JRequest::getInt('select_language_id');
$db = JFactory::getDbo();
$query = "SELECT `value` FROM #__jf_content WHERE reference_field = 'extra_fields' AND language_id = {$language_id} AND reference_id = {$itemID} AND reference_table='k2_items'";
$db->setQuery($query);
$result = $db->loadResult();
$currentValues = json_decode($result);
if (count($currentValues)) {
foreach ($currentValues as $value) {
if ($value->id == $extraField->id) {
$active = $value->value;
}
}
}
$output = '';
switch ($extraField->type) {
case 'textfield':
$output = '<div><strong>'.$extraField->name.'</strong><br /><input type="text" name="K2ExtraField_'.$extraField->id.'" value="'.$active.'" /></div><br /><br />';
break;
case 'textarea':
$output = '<div><strong>'.$extraField->name.'</strong><br /><textarea name="K2ExtraField_'.$extraField->id.'" rows="10" cols="40">'.$active.'</textarea></div><br /><br />';
break;
case 'select':
$output = '<div style="display:none;">'.JHTML::_('select.genericlist', $defaultValues, 'K2ExtraField_'.$extraField->id, '', 'value', 'name', $active).'</div>';
break;
case 'multipleSelect':
$output = '<div style="display:none;">'.JHTML::_('select.genericlist', $defaultValues, 'K2ExtraField_'.$extraField->id.'[]', 'multiple="multiple"', 'value', 'name', $active).'</div>';
break;
case 'radio':
$output = '<div style="display:none;">'.JHTML::_('select.radiolist', $defaultValues, 'K2ExtraField_'.$extraField->id, '', 'value', 'name', $active).'</div>';
break;
case 'link':
$output = '<div><strong>'.$extraField->name.'</strong><br /><input type="text" name="K2ExtraField_'.$extraField->id.'[]" value="'.$active[0].'" /><br /><input type="hidden" name="K2ExtraField_'.$extraField->id.'[]" value="'.$active[1].'" /><br /><input type="hidden" name="K2ExtraField_'.$extraField->id.'[]" value="'.$active[2].'" /></div><br /><br />';
break;
}
return $output;
}
}
log/log.xml 0000604 00000002160 15075053024 0006624 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>plg_system_log</name>
<author>Joomla! Project</author>
<creationDate>April 2007</creationDate>
<copyright>(C) 2007 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.0.0</version>
<description>PLG_LOG_XML_DESCRIPTION</description>
<files>
<filename plugin="log">log.php</filename>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_system_log.ini</language>
<language tag="en-GB">language/en-GB/plg_system_log.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="log_username"
type="radio"
layout="joomla.form.field.radio.switcher"
label="PLG_SYSTEM_LOG_FIELD_LOG_USERNAME_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
</fields>
</config>
</extension>
log/log.php 0000604 00000003154 15075053024 0006617 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.log
*
* @copyright (C) 2007 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\Authentication\Authentication;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin;
/**
* Joomla! System Logging Plugin.
*
* @since 1.5
*/
class PlgSystemLog extends CMSPlugin
{
/**
* Called if user fails to be logged in.
*
* @param array $response Array of response data.
*
* @return void
*
* @since 1.5
*/
public function onUserLoginFailure($response)
{
$errorlog = array();
switch ($response['status'])
{
case Authentication::STATUS_SUCCESS:
$errorlog['status'] = $response['type'] . ' CANCELED: ';
$errorlog['comment'] = $response['error_message'];
break;
case Authentication::STATUS_FAILURE:
$errorlog['status'] = $response['type'] . ' FAILURE: ';
if ($this->params->get('log_username', 0))
{
$errorlog['comment'] = $response['error_message'] . ' ("' . $response['username'] . '")';
}
else
{
$errorlog['comment'] = $response['error_message'];
}
break;
default:
$errorlog['status'] = $response['type'] . ' UNKNOWN ERROR: ';
$errorlog['comment'] = $response['error_message'];
break;
}
Log::addLogger(array(), Log::INFO);
try
{
Log::add($errorlog['comment'], Log::INFO, $errorlog['status']);
}
catch (Exception $e)
{
// If the log file is unwriteable during login then we should not go to the error page
return;
}
}
}
languagefilter/languagefilter.xml 0000604 00000006627 15075053024 0013260 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>plg_system_languagefilter</name>
<author>Joomla! Project</author>
<creationDate>July 2010</creationDate>
<copyright>(C) 2010 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.0.0</version>
<description>PLG_SYSTEM_LANGUAGEFILTER_XML_DESCRIPTION</description>
<files>
<filename plugin="languagefilter">languagefilter.php</filename>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_system_languagefilter.ini</language>
<language tag="en-GB">language/en-GB/plg_system_languagefilter.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="detect_browser"
type="list"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_DETECT_BROWSER_LABEL"
default="0"
filter="integer"
validate="options"
>
<option value="0">PLG_SYSTEM_LANGUAGEFILTER_SITE_LANGUAGE</option>
<option value="1">PLG_SYSTEM_LANGUAGEFILTER_BROWSER_SETTINGS</option>
</field>
<field
name="automatic_change"
type="radio"
layout="joomla.form.field.radio.switcher"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_AUTOMATIC_CHANGE_LABEL"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="item_associations"
type="radio"
layout="joomla.form.field.radio.switcher"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_ITEM_ASSOCIATIONS_LABEL"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="alternate_meta"
type="radio"
layout="joomla.form.field.radio.switcher"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_ALTERNATE_META_LABEL"
default="1"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="xdefault"
type="radio"
layout="joomla.form.field.radio.switcher"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LABEL"
default="1"
filter="integer"
showon="alternate_meta:1"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="xdefault_language"
type="contentlanguage"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LANGUAGE_LABEL"
default="default"
showon="alternate_meta:1[AND]xdefault:1"
>
<option value="default">PLG_SYSTEM_LANGUAGEFILTER_OPTION_DEFAULT_LANGUAGE</option>
</field>
<field
name="remove_default_prefix"
type="radio"
layout="joomla.form.field.radio.switcher"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_LABEL"
default="0"
filter="integer"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="lang_cookie"
type="list"
label="PLG_SYSTEM_LANGUAGEFILTER_FIELD_COOKIE_LABEL"
default="0"
filter="integer"
validate="options"
>
<option value="1">PLG_SYSTEM_LANGUAGEFILTER_OPTION_YEAR</option>
<option value="0">PLG_SYSTEM_LANGUAGEFILTER_OPTION_SESSION</option>
</field>
</fieldset>
</fields>
</config>
</extension>
languagefilter/languagefilter.php 0000604 00000062400 15075053024 0013236 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.languagefilter
*
* @copyright (C) 2010 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\Application\ApplicationHelper;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Application\CMSApplicationInterface;
use Joomla\CMS\Association\AssociationServiceInterface;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Language\Associations;
use Joomla\CMS\Language\Language;
use Joomla\CMS\Language\LanguageHelper;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Router\Router;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
use Joomla\Registry\Registry;
use Joomla\String\StringHelper;
/**
* Joomla! Language Filter Plugin.
*
* @since 1.6
*/
class PlgSystemLanguageFilter extends CMSPlugin
{
/**
* The routing mode.
*
* @var boolean
* @since 2.5
*/
protected $mode_sef;
/**
* Available languages by sef.
*
* @var array
* @since 1.6
*/
protected $sefs;
/**
* Available languages by language codes.
*
* @var array
* @since 2.5
*/
protected $lang_codes;
/**
* The current language code.
*
* @var string
* @since 3.4.2
*/
protected $current_lang;
/**
* The default language code.
*
* @var string
* @since 2.5
*/
protected $default_lang;
/**
* The logged user language code.
*
* @var string
* @since 3.3.1
*/
private $user_lang_code;
/**
* Application object.
*
* @var CMSApplicationInterface
* @since 3.3
*/
protected $app;
/**
* Constructor.
*
* @param object &$subject The object to observe
* @param array $config An optional associative array of configuration settings.
*
* @since 1.6
*/
public function __construct(&$subject, $config)
{
parent::__construct($subject, $config);
// Setup language data.
$this->mode_sef = $this->app->get('sef', 0);
$this->sefs = LanguageHelper::getLanguages('sef');
$this->lang_codes = LanguageHelper::getLanguages('lang_code');
$this->default_lang = ComponentHelper::getParams('com_languages')->get('site', 'en-GB');
// If language filter plugin is executed in a site page.
if ($this->app->isClient('site'))
{
$levels = $this->app->getIdentity()->getAuthorisedViewLevels();
foreach ($this->sefs as $sef => $language)
{
// @todo: In Joomla 2.5.4 and earlier access wasn't set. Non modified Content Languages got 0 as access value
// we also check if frontend language exists and is enabled
if (($language->access && !in_array($language->access, $levels))
|| (!array_key_exists($language->lang_code, LanguageHelper::getInstalledLanguages(0))))
{
unset($this->lang_codes[$language->lang_code], $this->sefs[$language->sef]);
}
}
}
// If language filter plugin is executed in an admin page (ex: Route site).
else
{
// Set current language to default site language, fallback to en-GB if there is no content language for the default site language.
$this->current_lang = isset($this->lang_codes[$this->default_lang]) ? $this->default_lang : 'en-GB';
foreach ($this->sefs as $sef => $language)
{
if (!array_key_exists($language->lang_code, LanguageHelper::getInstalledLanguages(0)))
{
unset($this->lang_codes[$language->lang_code]);
unset($this->sefs[$language->sef]);
}
}
}
}
/**
* After initialise.
*
* @return void
*
* @since 1.6
*/
public function onAfterInitialise()
{
$this->app->item_associations = $this->params->get('item_associations', 0);
// We need to make sure we are always using the site router, even if the language plugin is executed in admin app.
$router = CMSApplication::getInstance('site')->getRouter('site');
// Attach build rules for language SEF.
$router->attachBuildRule(array($this, 'preprocessBuildRule'), Router::PROCESS_BEFORE);
if ($this->mode_sef)
{
$router->attachBuildRule(array($this, 'buildRule'), Router::PROCESS_BEFORE);
$router->attachBuildRule(array($this, 'postprocessSEFBuildRule'), Router::PROCESS_AFTER);
}
else
{
$router->attachBuildRule(array($this, 'postprocessNonSEFBuildRule'), Router::PROCESS_AFTER);
}
// Attach parse rule.
$router->attachParseRule(array($this, 'parseRule'), Router::PROCESS_BEFORE);
}
/**
* After route.
*
* @return void
*
* @since 3.4
*/
public function onAfterRoute()
{
// Add custom site name.
if ($this->app->isClient('site') && isset($this->lang_codes[$this->current_lang]) && $this->lang_codes[$this->current_lang]->sitename)
{
$this->app->set('sitename', $this->lang_codes[$this->current_lang]->sitename);
}
}
/**
* Add build preprocess rule to router.
*
* @param Router &$router Router object.
* @param Uri &$uri Uri object.
*
* @return void
*
* @since 3.4
*/
public function preprocessBuildRule(&$router, &$uri)
{
$lang = $uri->getVar('lang', $this->current_lang);
if (isset($this->sefs[$lang]))
{
$lang = $this->sefs[$lang]->lang_code;
}
$uri->setVar('lang', $lang);
}
/**
* Add build rule to router.
*
* @param Router &$router Router object.
* @param Uri &$uri Uri object.
*
* @return void
*
* @since 1.6
*/
public function buildRule(&$router, &$uri)
{
$lang = $uri->getVar('lang');
if (isset($this->lang_codes[$lang]))
{
$sef = $this->lang_codes[$lang]->sef;
}
else
{
$sef = $this->lang_codes[$this->current_lang]->sef;
}
if (!$this->params->get('remove_default_prefix', 0)
|| $lang !== $this->default_lang
|| $lang !== $this->current_lang)
{
$uri->setPath($uri->getPath() . '/' . $sef . '/');
}
}
/**
* postprocess build rule for SEF URLs
*
* @param Router &$router Router object.
* @param Uri &$uri Uri object.
*
* @return void
*
* @since 3.4
*/
public function postprocessSEFBuildRule(&$router, &$uri)
{
$uri->delVar('lang');
}
/**
* postprocess build rule for non-SEF URLs
*
* @param Router &$router Router object.
* @param Uri &$uri Uri object.
*
* @return void
*
* @since 3.4
*/
public function postprocessNonSEFBuildRule(&$router, &$uri)
{
$lang = $uri->getVar('lang');
if (isset($this->lang_codes[$lang]))
{
$uri->setVar('lang', $this->lang_codes[$lang]->sef);
}
}
/**
* Add parse rule to router.
*
* @param Router &$router Router object.
* @param Uri &$uri Uri object.
*
* @return void
*
* @since 1.6
*/
public function parseRule(&$router, &$uri)
{
// Did we find the current and existing language yet?
$found = false;
// Are we in SEF mode or not?
if ($this->mode_sef)
{
$path = $uri->getPath();
$parts = explode('/', $path);
$sef = StringHelper::strtolower($parts[0]);
// Do we have a URL Language Code ?
if (!isset($this->sefs[$sef]))
{
// Check if remove default URL language code is set
if ($this->params->get('remove_default_prefix', 0))
{
if ($parts[0])
{
// We load a default site language page
$lang_code = $this->default_lang;
}
else
{
// We check for an existing language cookie
$lang_code = $this->getLanguageCookie();
}
}
else
{
$lang_code = $this->getLanguageCookie();
}
// No language code. Try using browser settings or default site language
if (!$lang_code && $this->params->get('detect_browser', 0) == 1)
{
$lang_code = LanguageHelper::detectLanguage();
}
if (!$lang_code)
{
$lang_code = $this->default_lang;
}
if ($lang_code === $this->default_lang && $this->params->get('remove_default_prefix', 0))
{
$found = true;
}
}
else
{
// We found our language
$found = true;
$lang_code = $this->sefs[$sef]->lang_code;
// If we found our language, but it's the default language and we don't want a prefix for that, we are on a wrong URL.
// Or we try to change the language back to the default language. We need a redirect to the proper URL for the default language.
if ($lang_code === $this->default_lang && $this->params->get('remove_default_prefix', 0))
{
// Create a cookie.
$this->setLanguageCookie($lang_code);
$found = false;
array_shift($parts);
$path = implode('/', $parts);
}
// We have found our language and the first part of our URL is the language prefix
if ($found)
{
array_shift($parts);
// Empty parts array when "index.php" is the only part left.
if (count($parts) === 1 && $parts[0] === 'index.php')
{
$parts = array();
}
$uri->setPath(implode('/', $parts));
}
}
}
// We are not in SEF mode
else
{
$lang_code = $this->getLanguageCookie();
if (!$lang_code && $this->params->get('detect_browser', 1))
{
$lang_code = LanguageHelper::detectLanguage();
}
if (!isset($this->lang_codes[$lang_code]))
{
$lang_code = $this->default_lang;
}
}
$lang = $uri->getVar('lang', $lang_code);
if (isset($this->sefs[$lang]))
{
// We found our language
$found = true;
$lang_code = $this->sefs[$lang]->lang_code;
}
// We are called via POST or the nolangfilter url parameter was set. We don't care about the language
// and simply set the default language as our current language.
if ($this->app->input->getMethod() === 'POST'
|| $this->app->input->get('nolangfilter', 0) == 1
|| count($this->app->input->post) > 0
|| count($this->app->input->files) > 0)
{
$found = true;
if (!isset($lang_code))
{
$lang_code = $this->getLanguageCookie();
}
if (!$lang_code && $this->params->get('detect_browser', 1))
{
$lang_code = LanguageHelper::detectLanguage();
}
if (!isset($this->lang_codes[$lang_code]))
{
$lang_code = $this->default_lang;
}
}
// We have not found the language and thus need to redirect
if (!$found)
{
// Lets find the default language for this user
if (!isset($lang_code) || !isset($this->lang_codes[$lang_code]))
{
$lang_code = false;
if ($this->params->get('detect_browser', 1))
{
$lang_code = LanguageHelper::detectLanguage();
if (!isset($this->lang_codes[$lang_code]))
{
$lang_code = false;
}
}
if (!$lang_code)
{
$lang_code = $this->default_lang;
}
}
if ($this->mode_sef)
{
// Use the current language sef or the default one.
if ($lang_code !== $this->default_lang
|| !$this->params->get('remove_default_prefix', 0))
{
$path = $this->lang_codes[$lang_code]->sef . '/' . $path;
}
$uri->setPath($path);
if (!$this->app->get('sef_rewrite'))
{
$uri->setPath('index.php/' . $uri->getPath());
}
$redirectUri = $uri->base() . $uri->toString(array('path', 'query', 'fragment'));
}
else
{
$uri->setVar('lang', $this->lang_codes[$lang_code]->sef);
$redirectUri = $uri->base() . 'index.php?' . $uri->getQuery();
}
// Set redirect HTTP code to "302 Found".
$redirectHttpCode = 302;
// If selected language is the default language redirect code is "301 Moved Permanently".
if ($lang_code === $this->default_lang)
{
$redirectHttpCode = 301;
// We cannot cache this redirect in browser. 301 is cacheable by default so we need to force to not cache it in browsers.
$this->app->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true);
$this->app->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
$this->app->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
$this->app->setHeader('Pragma', 'no-cache');
$this->app->sendHeaders();
}
// Redirect to language.
$this->app->redirect($redirectUri, $redirectHttpCode);
}
// We have found our language and now need to set the cookie and the language value in our system
$array = array('lang' => $lang_code);
$this->current_lang = $lang_code;
// Set the request var.
$this->app->input->set('language', $lang_code);
$this->app->set('language', $lang_code);
$language = $this->app->getLanguage();
if ($language->getTag() !== $lang_code)
{
$language_new = Language::getInstance($lang_code, (bool) $this->app->get('debug_lang'));
foreach ($language->getPaths() as $extension => $files)
{
if (strpos($extension, 'plg_system') !== false)
{
$extension_name = substr($extension, 11);
$language_new->load($extension, JPATH_ADMINISTRATOR)
|| $language_new->load($extension, JPATH_PLUGINS . '/system/' . $extension_name);
continue;
}
$language_new->load($extension);
}
Factory::$language = $language_new;
$this->app->loadLanguage($language_new);
}
// Create a cookie.
if ($this->getLanguageCookie() !== $lang_code)
{
$this->setLanguageCookie($lang_code);
}
return $array;
}
/**
* Reports the privacy related capabilities for this plugin to site administrators.
*
* @return array
*
* @since 3.9.0
*/
public function onPrivacyCollectAdminCapabilities()
{
$this->loadLanguage();
return array(
Text::_('PLG_SYSTEM_LANGUAGEFILTER') => array(
Text::_('PLG_SYSTEM_LANGUAGEFILTER_PRIVACY_CAPABILITY_LANGUAGE_COOKIE'),
),
);
}
/**
* Before store user method.
*
* Method is called before user data is stored in the database.
*
* @param array $user Holds the old user data.
* @param boolean $isnew True if a new user is stored.
* @param array $new Holds the new user data.
*
* @return void
*
* @since 1.6
*/
public function onUserBeforeSave($user, $isnew, $new)
{
if (array_key_exists('params', $user) && $this->params->get('automatic_change', 1) == 1)
{
$registry = new Registry($user['params']);
$this->user_lang_code = $registry->get('language');
if (empty($this->user_lang_code))
{
$this->user_lang_code = $this->current_lang;
}
}
}
/**
* After store user method.
*
* Method is called after user data is stored in the database.
*
* @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 void
*
* @since 1.6
*/
public function onUserAfterSave($user, $isnew, $success, $msg): void
{
if ($success && array_key_exists('params', $user) && $this->params->get('automatic_change', 1) == 1)
{
$registry = new Registry($user['params']);
$lang_code = $registry->get('language');
if (empty($lang_code))
{
$lang_code = $this->current_lang;
}
if ($lang_code === $this->user_lang_code || !isset($this->lang_codes[$lang_code]))
{
if ($this->app->isClient('site'))
{
$this->app->setUserState('com_users.edit.profile.redirect', null);
}
}
else
{
if ($this->app->isClient('site'))
{
$this->app->setUserState('com_users.edit.profile.redirect', 'index.php?Itemid='
. $this->app->getMenu()->getDefault($lang_code)->id . '&lang=' . $this->lang_codes[$lang_code]->sef
);
// Create a cookie.
$this->setLanguageCookie($lang_code);
}
}
}
}
/**
* Method to handle any login logic and report back to the subject.
*
* @param array $user Holds the user data.
* @param array $options Array holding options (remember, autoregister, group).
*
* @return boolean True on success.
*
* @since 1.5
*/
public function onUserLogin($user, $options = array())
{
if ($this->app->isClient('site'))
{
$menu = $this->app->getMenu();
if ($this->params->get('automatic_change', 1))
{
$assoc = Associations::isEnabled();
$lang_code = $user['language'];
// If no language is specified for this user, we set it to the site default language
if (empty($lang_code))
{
$lang_code = $this->default_lang;
}
// The language has been deleted/disabled or the related content language does not exist/has been unpublished
// or the related home page does not exist/has been unpublished
if (!array_key_exists($lang_code, $this->lang_codes)
|| !array_key_exists($lang_code, Multilanguage::getSiteHomePages())
|| !Folder::exists(JPATH_SITE . '/language/' . $lang_code))
{
$lang_code = $this->current_lang;
}
// Try to get association from the current active menu item
$active = $menu->getActive();
$foundAssociation = false;
/**
* Looking for associations.
* If the login menu item form contains an internal URL redirection,
* This will override the automatic change to the user preferred site language.
* In that case we use the redirect as defined in the menu item.
* Otherwise we redirect, when available, to the user preferred site language.
*/
if ($active && !$active->getParams()->get('login_redirect_url'))
{
if ($assoc)
{
$associations = MenusHelper::getAssociations($active->id);
}
// Retrieves the Itemid from a login form.
$uri = new Uri($this->app->getUserState('users.login.form.return'));
if ($uri->getVar('Itemid'))
{
// The login form contains a menu item redirection. Try to get associations from that menu item.
// If any association set to the user preferred site language, redirect to that page.
if ($assoc)
{
$associations = MenusHelper::getAssociations($uri->getVar('Itemid'));
}
if (isset($associations[$lang_code]) && $menu->getItem($associations[$lang_code]))
{
$associationItemid = $associations[$lang_code];
$this->app->setUserState('users.login.form.return', 'index.php?Itemid=' . $associationItemid);
$foundAssociation = true;
}
}
elseif (isset($associations[$lang_code]) && $menu->getItem($associations[$lang_code]))
{
/**
* The login form does not contain a menu item redirection.
* The active menu item has associations.
* We redirect to the user preferred site language associated page.
*/
$associationItemid = $associations[$lang_code];
$this->app->setUserState('users.login.form.return', 'index.php?Itemid=' . $associationItemid);
$foundAssociation = true;
}
elseif ($active->home)
{
// We are on a Home page, we redirect to the user preferred site language Home page.
$item = $menu->getDefault($lang_code);
if ($item && $item->language !== $active->language && $item->language !== '*')
{
$this->app->setUserState('users.login.form.return', 'index.php?Itemid=' . $item->id);
$foundAssociation = true;
}
}
}
if ($foundAssociation && $lang_code !== $this->current_lang)
{
// Change language.
$this->current_lang = $lang_code;
// Create a cookie.
$this->setLanguageCookie($lang_code);
// Change the language code.
Factory::getContainer()->get(\Joomla\CMS\Language\LanguageFactoryInterface::class)->createLanguage($lang_code);
}
}
else
{
if ($this->app->getUserState('users.login.form.return'))
{
$this->app->setUserState('users.login.form.return', Route::_($this->app->getUserState('users.login.form.return'), false));
}
}
}
}
/**
* Method to add alternative meta tags for associated menu items.
*
* @return void
*
* @since 1.7
*/
public function onAfterDispatch()
{
$doc = $this->app->getDocument();
if ($this->app->isClient('site') && $this->params->get('alternate_meta', 1) && $doc->getType() === 'html')
{
$languages = $this->lang_codes;
$homes = Multilanguage::getSiteHomePages();
$menu = $this->app->getMenu();
$active = $menu->getActive();
$levels = $this->app->getIdentity()->getAuthorisedViewLevels();
$remove_default_prefix = $this->params->get('remove_default_prefix', 0);
$server = Uri::getInstance()->toString(array('scheme', 'host', 'port'));
$is_home = false;
$currentInternalUrl = 'index.php?' . http_build_query($this->app->getRouter()->getVars());
if ($active)
{
$active_link = Route::_($active->link . '&Itemid=' . $active->id);
$current_link = Route::_($currentInternalUrl);
// Load menu associations
if ($active_link === $current_link)
{
$associations = MenusHelper::getAssociations($active->id);
}
// Check if we are on the home page
$is_home = ($active->home
&& ($active_link === $current_link || $active_link === $current_link . 'index.php' || $active_link . '/' === $current_link));
}
// Load component associations.
$option = $this->app->input->get('option');
$component = $this->app->bootComponent($option);
if ($component instanceof AssociationServiceInterface)
{
$cassociations = $component->getAssociationsExtension()->getAssociationsForItem();
}
else
{
$cName = ucfirst(substr($option, 4)) . 'HelperAssociation';
JLoader::register($cName, JPath::clean(JPATH_SITE . '/components/' . $option . '/helpers/association.php'));
if (class_exists($cName) && is_callable(array($cName, 'getAssociations')))
{
$cassociations = call_user_func(array($cName, 'getAssociations'));
}
}
// For each language...
foreach ($languages as $i => $language)
{
switch (true)
{
// Language without frontend UI || Language without specific home menu || Language without authorized access level
case !array_key_exists($i, LanguageHelper::getInstalledLanguages(0)):
case !isset($homes[$i]):
case isset($language->access) && $language->access && !in_array($language->access, $levels):
unset($languages[$i]);
break;
// Home page
case $is_home:
$language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $homes[$i]->id);
break;
// Current language link
case $i === $this->current_lang:
$language->link = Route::_($currentInternalUrl);
break;
// Component association
case isset($cassociations[$i]):
$language->link = Route::_($cassociations[$i]);
break;
// Menu items association
// Heads up! "$item = $menu" here below is an assignment, *NOT* comparison
case isset($associations[$i]) && ($item = $menu->getItem($associations[$i])):
$language->link = Route::_('index.php?Itemid=' . $item->id . '&lang=' . $language->sef);
break;
// Too bad...
default:
unset($languages[$i]);
}
}
// If there are at least 2 of them, add the rel="alternate" links to the <head>
if (count($languages) > 1)
{
// Remove the sef from the default language if "Remove URL Language Code" is on
if ($remove_default_prefix && isset($languages[$this->default_lang]))
{
$languages[$this->default_lang]->link
= preg_replace('|/' . $languages[$this->default_lang]->sef . '/|', '/', $languages[$this->default_lang]->link, 1);
}
foreach ($languages as $i => $language)
{
$doc->addHeadLink($server . $language->link, 'alternate', 'rel', array('hreflang' => $i));
}
// Add x-default language tag
if ($this->params->get('xdefault', 1))
{
$xdefault_language = $this->params->get('xdefault_language', $this->default_lang);
$xdefault_language = ($xdefault_language === 'default') ? $this->default_lang : $xdefault_language;
if (isset($languages[$xdefault_language]))
{
// Use a custom tag because addHeadLink is limited to one URI per tag
$doc->addCustomTag('<link href="' . $server . $languages[$xdefault_language]->link . '" rel="alternate" hreflang="x-default">');
}
}
}
}
}
/**
* Set the language cookie
*
* @param string $languageCode The language code for which we want to set the cookie
*
* @return void
*
* @since 3.4.2
*/
private function setLanguageCookie($languageCode)
{
// If is set to use language cookie for a year in plugin params, save the user language in a new cookie.
if ((int) $this->params->get('lang_cookie', 0) === 1)
{
// Create a cookie with one year lifetime.
$this->app->input->cookie->set(
ApplicationHelper::getHash('language'),
$languageCode,
time() + 365 * 86400,
$this->app->get('cookie_path', '/'),
$this->app->get('cookie_domain', ''),
$this->app->isHttpsForced(),
true
);
}
// If not, set the user language in the session (that is already saved in a cookie).
else
{
$this->app->getSession()->set('plg_system_languagefilter.language', $languageCode);
}
}
/**
* Get the language cookie
*
* @return string
*
* @since 3.4.2
*/
private function getLanguageCookie()
{
// Is is set to use a year language cookie in plugin params, get the user language from the cookie.
if ((int) $this->params->get('lang_cookie', 0) === 1)
{
$languageCode = $this->app->input->cookie->get(ApplicationHelper::getHash('language'));
}
// Else get the user language from the session.
else
{
$languageCode = $this->app->getSession()->get('plg_system_languagefilter.language');
}
// Let's be sure we got a valid language code. Fallback to null.
if (!array_key_exists($languageCode, $this->lang_codes))
{
$languageCode = null;
}
return $languageCode;
}
}
sessiongc/sessiongc.xml 0000604 00000004342 15075053024 0011260 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>plg_system_sessiongc</name>
<author>Joomla! Project</author>
<creationDate>February 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.8.6</version>
<description>PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION</description>
<files>
<filename plugin="sessiongc">sessiongc.php</filename>
</files>
<languages folder="language">
<language tag="en-GB">en-GB/en-GB.plg_system_sessiongc.ini</language>
<language tag="en-GB">en-GB/en-GB.plg_system_sessiongc.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="enable_session_gc"
type="radio"
label="PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL"
description="PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC"
layout="joomla.form.field.radio.switcher"
default="1"
filter="uint"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="enable_session_metadata_gc"
type="radio"
label="PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_LABEL"
description="PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC"
layout="joomla.form.field.radio.switcher"
default="1"
filter="uint"
>
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
<field
name="gc_probability"
type="number"
label="PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_LABEL"
description="PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC"
filter="uint"
validate="number"
min="1"
default="1"
showon="enable_session_gc:1[OR]enable_session_metadata_gc:1"
/>
<field
name="gc_divisor"
type="number"
label="PLG_SYSTEM_SESSIONGC_GC_DIVISOR_LABEL"
description="PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC"
filter="uint"
validate="number"
min="1"
default="100"
showon="enable_session_gc:1[OR]enable_session_metadata_gc:1"
/>
</fieldset>
</fields>
</config>
</extension>
sessiongc/sessiongc.php 0000604 00000003377 15075053024 0011256 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.sessiongc
*
* @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\Application\CMSApplication;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Session\MetadataManager;
/**
* Garbage collection handler for session related data
*
* @since 3.8.6
*/
class PlgSystemSessionGc extends CMSPlugin
{
/**
* Application object
*
* @var CMSApplication
* @since 3.8.6
*/
protected $app;
/**
* Database driver
*
* @var JDatabaseDriver
* @since 3.8.6
*/
protected $db;
/**
* Runs after the HTTP response has been sent to the client and performs garbage collection tasks
*
* @return void
*
* @since 3.8.6
*/
public function onAfterRespond()
{
if ($this->params->get('enable_session_gc', 1))
{
$probability = $this->params->get('gc_probability', 1);
$divisor = $this->params->get('gc_divisor', 100);
$random = $divisor * lcg_value();
if ($probability > 0 && $random < $probability)
{
$this->app->getSession()->gc();
}
}
if ($this->app->get('session_handler', 'none') !== 'database' && $this->params->get('enable_session_metadata_gc', 1))
{
$probability = $this->params->get('gc_probability', 1);
$divisor = $this->params->get('gc_divisor', 100);
$random = $divisor * lcg_value();
if ($probability > 0 && $random < $probability)
{
/** @var MetadataManager $metadataManager */
$metadataManager = Factory::getContainer()->get(MetadataManager::class);
$metadataManager->deletePriorTo(time() - $this->app->getSession()->getExpire());
}
}
}
}
sef/sef.xml 0000604 00000002044 15075053024 0006615 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>plg_system_sef</name>
<author>Joomla! Project</author>
<creationDate>December 2007</creationDate>
<copyright>(C) 2007 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.0.0</version>
<description>PLG_SEF_XML_DESCRIPTION</description>
<files>
<filename plugin="sef">sef.php</filename>
</files>
<languages>
<language tag="en-GB">language/en-GB/plg_system_sef.ini</language>
<language tag="en-GB">language/en-GB/plg_system_sef.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="domain"
type="url"
label="PLG_SEF_DOMAIN_LABEL"
description="PLG_SEF_DOMAIN_DESCRIPTION"
hint="https://www.example.com"
filter="url"
validate="url"
/>
</fieldset>
</fields>
</config>
</extension>
sef/sef.php 0000604 00000015413 15075053024 0006610 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.sef
*
* @copyright (C) 2007 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\Plugin\CMSPlugin;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
/**
* Joomla! SEF Plugin.
*
* @since 1.5
*/
class PlgSystemSef extends CMSPlugin
{
/**
* Application object.
*
* @var JApplicationCms
* @since 3.5
*/
protected $app;
/**
* Add the canonical uri to the head.
*
* @return void
*
* @since 3.5
*/
public function onAfterDispatch()
{
$doc = $this->app->getDocument();
if (!$this->app->isClient('site') || $doc->getType() !== 'html')
{
return;
}
$sefDomain = $this->params->get('domain', false);
// Don't add a canonical html tag if no alternative domain has added in SEF plugin domain field.
if (empty($sefDomain))
{
return;
}
// Check if a canonical html tag already exists (for instance, added by a component).
$canonical = '';
foreach ($doc->_links as $linkUrl => $link)
{
if (isset($link['relation']) && $link['relation'] === 'canonical')
{
$canonical = $linkUrl;
break;
}
}
// If a canonical html tag already exists get the canonical and change it to use the SEF plugin domain field.
if (!empty($canonical))
{
// Remove current canonical link.
unset($doc->_links[$canonical]);
// Set the current canonical link but use the SEF system plugin domain field.
$canonical = $sefDomain . Uri::getInstance($canonical)->toString(array('path', 'query', 'fragment'));
}
// If a canonical html doesn't exists already add a canonical html tag using the SEF plugin domain field.
else
{
$canonical = $sefDomain . Uri::getInstance()->toString(array('path', 'query', 'fragment'));
}
// Add the canonical link.
$doc->addHeadLink(htmlspecialchars($canonical), 'canonical');
}
/**
* Convert the site URL to fit to the HTTP request.
*
* @return void
*/
public function onAfterRender()
{
if (!$this->app->isClient('site'))
{
return;
}
// Replace src links.
$base = Uri::base(true) . '/';
$buffer = $this->app->getBody();
// For feeds we need to search for the URL with domain.
$prefix = $this->app->getDocument()->getType() === 'feed' ? Uri::root() : '';
// Replace index.php URI by SEF URI.
if (strpos($buffer, 'href="' . $prefix . 'index.php?') !== false)
{
preg_match_all('#href="' . $prefix . 'index.php\?([^"]+)"#m', $buffer, $matches);
foreach ($matches[1] as $urlQueryString)
{
$buffer = str_replace(
'href="' . $prefix . 'index.php?' . $urlQueryString . '"',
'href="' . trim($prefix, '/') . Route::_('index.php?' . $urlQueryString) . '"',
$buffer
);
}
$this->checkBuffer($buffer);
}
// Check for all unknown protocols (a protocol must contain at least one alphanumeric character followed by a ":").
$protocols = '[a-zA-Z0-9\-]+:';
$attributes = array('href=', 'src=', 'poster=');
foreach ($attributes as $attribute)
{
if (strpos($buffer, $attribute) !== false)
{
$regex = '#\s' . $attribute . '"(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
$buffer = preg_replace($regex, ' ' . $attribute . '"' . $base . '$1"', $buffer);
$this->checkBuffer($buffer);
}
}
if (strpos($buffer, 'srcset=') !== false)
{
$regex = '#\s+srcset="([^"]+)"#m';
$buffer = preg_replace_callback(
$regex,
function ($match) use ($base, $protocols)
{
preg_match_all('#(?:[^\s]+)\s*(?:[\d\.]+[wx])?(?:\,\s*)?#i', $match[1], $matches);
foreach ($matches[0] as &$src)
{
$src = preg_replace('#^(?!/|' . $protocols . '|\#|\')(.+)#', $base . '$1', $src);
}
return ' srcset="' . implode($matches[0]) . '"';
},
$buffer
);
$this->checkBuffer($buffer);
}
// Replace all unknown protocols in javascript window open events.
if (strpos($buffer, 'window.open(') !== false)
{
$regex = '#onclick="window.open\(\'(?!/|' . $protocols . '|\#)([^/]+[^\']*?\')#m';
$buffer = preg_replace($regex, 'onclick="window.open(\'' . $base . '$1', $buffer);
$this->checkBuffer($buffer);
}
// Replace all unknown protocols in onmouseover and onmouseout attributes.
$attributes = array('onmouseover=', 'onmouseout=');
foreach ($attributes as $attribute)
{
if (strpos($buffer, $attribute) !== false)
{
$regex = '#' . $attribute . '"this.src=([\']+)(?!/|' . $protocols . '|\#|\')([^"]+)"#m';
$buffer = preg_replace($regex, $attribute . '"this.src=$1' . $base . '$2"', $buffer);
$this->checkBuffer($buffer);
}
}
// Replace all unknown protocols in CSS background image.
if (strpos($buffer, 'style=') !== false)
{
$regex_url = '\s*url\s*\(([\'\"]|\&\#0?3[49];)?(?!/|\&\#0?3[49];|' . $protocols . '|\#)([^\)\'\"]+)([\'\"]|\&\#0?3[49];)?\)';
$regex = '#style=\s*([\'\"])(.*):' . $regex_url . '#m';
$buffer = preg_replace($regex, 'style=$1$2: url($3' . $base . '$4$5)', $buffer);
$this->checkBuffer($buffer);
}
// Replace all unknown protocols in OBJECT param tag.
if (strpos($buffer, '<param') !== false)
{
// OBJECT <param name="xx", value="yy"> -- fix it only inside the <param> tag.
$regex = '#(<param\s+)name\s*=\s*"(movie|src|url)"[^>]\s*value\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
$buffer = preg_replace($regex, '$1name="$2" value="' . $base . '$3"', $buffer);
$this->checkBuffer($buffer);
// OBJECT <param value="xx", name="yy"> -- fix it only inside the <param> tag.
$regex = '#(<param\s+[^>]*)value\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"\s*name\s*=\s*"(movie|src|url)"#m';
$buffer = preg_replace($regex, '<param value="' . $base . '$2" name="$3"', $buffer);
$this->checkBuffer($buffer);
}
// Replace all unknown protocols in OBJECT tag.
if (strpos($buffer, '<object') !== false)
{
$regex = '#(<object\s+[^>]*)data\s*=\s*"(?!/|' . $protocols . '|\#|\')([^"]*)"#m';
$buffer = preg_replace($regex, '$1data="' . $base . '$2"', $buffer);
$this->checkBuffer($buffer);
}
// Use the replaced HTML body.
$this->app->setBody($buffer);
}
/**
* Check the buffer.
*
* @param string $buffer Buffer to be checked.
*
* @return void
*/
private function checkBuffer($buffer)
{
if ($buffer === null)
{
switch (preg_last_error())
{
case PREG_BACKTRACK_LIMIT_ERROR:
$message = 'PHP regular expression limit reached (pcre.backtrack_limit)';
break;
case PREG_RECURSION_LIMIT_ERROR:
$message = 'PHP regular expression limit reached (pcre.recursion_limit)';
break;
case PREG_BAD_UTF8_ERROR:
$message = 'Bad UTF8 passed to PCRE function';
break;
default:
$message = 'Unknown PCRE error calling PCRE function';
}
throw new RuntimeException($message);
}
}
}
stats/field/uniqueid.php 0000644 00000001355 15075053024 0011326 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JLoader::register('PlgSystemStatsFormFieldBase', __DIR__ . '/base.php');
/**
* Unique ID Field class for the Stats Plugin.
*
* @since 3.5
*/
class PlgSystemStatsFormFieldUniqueid extends PlgSystemStatsFormFieldBase
{
/**
* The form field type.
*
* @var string
* @since 3.5
*/
protected $type = 'Uniqueid';
/**
* Name of the layout being used to render the field
*
* @var string
* @since 3.5
*/
protected $layout = 'field.uniqueid';
}
stats/field/data.php 0000644 00000002261 15075053024 0010411 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
JLoader::register('PlgSystemStatsFormFieldBase', __DIR__ . '/base.php');
/**
* Unique ID Field class for the Stats Plugin.
*
* @since 3.5
*/
class PlgSystemStatsFormFieldData extends PlgSystemStatsFormFieldBase
{
/**
* The form field type.
*
* @var string
* @since 3.5
*/
protected $type = 'Data';
/**
* Name of the layout being used to render the field
*
* @var string
* @since 3.5
*/
protected $layout = 'field.data';
/**
* Method to get the data to be passed to the layout for rendering.
*
* @return array
*
* @since 3.5
*/
protected function getLayoutData()
{
$data = parent::getLayoutData();
$dispatcher = JEventDispatcher::getInstance();
JPluginHelper::importPlugin('system', 'stats');
$result = $dispatcher->trigger('onGetStatsData', array('stats.field.data'));
$data['statsData'] = $result ? reset($result) : array();
return $data;
}
}
stats/field/base.php 0000644 00000001366 15075053024 0010417 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
/**
* Base field for the Stats Plugin.
*
* @since 3.5
*/
abstract class PlgSystemStatsFormFieldBase extends JFormField
{
/**
* Get the layouts paths
*
* @return array
*
* @since 3.5
*/
protected function getLayoutPaths()
{
$template = JFactory::getApplication()->getTemplate();
return array(
JPATH_ADMINISTRATOR . '/templates/' . $template . '/html/layouts/plugins/system/stats',
dirname(__DIR__) . '/layouts',
JPATH_SITE . '/layouts'
);
}
}
stats/stats.php 0000604 00000035513 15075053024 0007555 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright (C) 2015 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\Http\HttpFactory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\User\UserHelper;
// Uncomment the following line to enable debug mode for testing purposes. Note: statistics will be sent on every page load
// define('PLG_SYSTEM_STATS_DEBUG', 1);
/**
* Statistics system plugin. This sends anonymous data back to the Joomla! Project about the
* PHP, SQL, Joomla and OS versions
*
* @since 3.5
*/
class PlgSystemStats extends CMSPlugin
{
/**
* Indicates sending statistics is always allowed.
*
* @var integer
* @since 3.5
*/
const MODE_ALLOW_ALWAYS = 1;
/**
* Indicates sending statistics is only allowed one time.
*
* @var integer
* @since 3.5
*/
const MODE_ALLOW_ONCE = 2;
/**
* Indicates sending statistics is never allowed.
*
* @var integer
* @since 3.5
*/
const MODE_ALLOW_NEVER = 3;
/**
* Application object
*
* @var JApplicationCms
* @since 3.5
*/
protected $app;
/**
* Database object
*
* @var JDatabaseDriver
* @since 3.5
*/
protected $db;
/**
* URL to send the statistics.
*
* @var string
* @since 3.5
*/
protected $serverUrl = 'https://developer.joomla.org/stats/submit';
/**
* Unique identifier for this site
*
* @var string
* @since 3.5
*/
protected $uniqueId;
/**
* Listener for the `onAfterInitialise` event
*
* @return void
*
* @since 3.5
*/
public function onAfterInitialise()
{
if (!$this->app->isClient('administrator') || !$this->isAllowedUser())
{
return;
}
if (!$this->isDebugEnabled() && !$this->isUpdateRequired())
{
return;
}
if (Uri::getInstance()->getVar('tmpl') === 'component')
{
return;
}
// Load plugin language files only when needed (ex: they are not needed in site client).
$this->loadLanguage();
}
/**
* Listener for the `onAfterDispatch` event
*
* @return void
*
* @since 4.0.0
*/
public function onAfterDispatch()
{
if (!$this->app->isClient('administrator') || !$this->isAllowedUser())
{
return;
}
if (!$this->isDebugEnabled() && !$this->isUpdateRequired())
{
return;
}
if (Uri::getInstance()->getVar('tmpl') === 'component')
{
return;
}
if ($this->app->getDocument()->getType() !== 'html')
{
return;
}
$this->app->getDocument()->getWebAssetManager()
->registerAndUseScript('plg_system_stats.message', 'plg_system_stats/stats-message.js', [], ['defer' => true], ['core']);
}
/**
* User selected to always send data
*
* @return void
*
* @since 3.5
*
* @throws Exception If user is not allowed.
* @throws RuntimeException If there is an error saving the params or sending the data.
*/
public function onAjaxSendAlways()
{
if (!$this->isAllowedUser() || !$this->isAjaxRequest())
{
throw new Exception(Text::_('JGLOBAL_AUTH_ACCESS_DENIED'), 403);
}
$this->params->set('mode', static::MODE_ALLOW_ALWAYS);
if (!$this->saveParams())
{
throw new RuntimeException('Unable to save plugin settings', 500);
}
echo json_encode(['sent' => (int) $this->sendStats()]);
}
/**
* User selected to never send data.
*
* @return void
*
* @since 3.5
*
* @throws Exception If user is not allowed.
* @throws RuntimeException If there is an error saving the params.
*/
public function onAjaxSendNever()
{
if (!$this->isAllowedUser() || !$this->isAjaxRequest())
{
throw new Exception(Text::_('JGLOBAL_AUTH_ACCESS_DENIED'), 403);
}
$this->params->set('mode', static::MODE_ALLOW_NEVER);
if (!$this->saveParams())
{
throw new RuntimeException('Unable to save plugin settings', 500);
}
if (!$this->disablePlugin())
{
throw new RuntimeException('Unable to disable the statistics plugin', 500);
}
echo json_encode(['sent' => 0]);
}
/**
* User selected to send data once.
*
* @return void
*
* @since 3.5
*
* @throws Exception If user is not allowed.
* @throws RuntimeException If there is an error saving the params, disabling the plugin or sending the data.
*/
public function onAjaxSendOnce()
{
if (!$this->isAllowedUser() || !$this->isAjaxRequest())
{
throw new Exception(Text::_('JGLOBAL_AUTH_ACCESS_DENIED'), 403);
}
$this->params->set('mode', static::MODE_ALLOW_ONCE);
if (!$this->saveParams())
{
throw new RuntimeException('Unable to save plugin settings', 500);
}
$this->sendStats();
if (!$this->disablePlugin())
{
throw new RuntimeException('Unable to disable the statistics plugin', 500);
}
echo json_encode(['sent' => 1]);
}
/**
* Send the stats to the server.
* On first load | on demand mode it will show a message asking users to select mode.
*
* @return void
*
* @since 3.5
*
* @throws Exception If user is not allowed.
* @throws RuntimeException If there is an error saving the params, disabling the plugin or sending the data.
*/
public function onAjaxSendStats()
{
if (!$this->isAllowedUser() || !$this->isAjaxRequest())
{
throw new Exception(Text::_('JGLOBAL_AUTH_ACCESS_DENIED'), 403);
}
// User has not selected the mode. Show message.
if ((int) $this->params->get('mode') !== static::MODE_ALLOW_ALWAYS)
{
$data = [
'sent' => 0,
'html' => $this->getRenderer('message')->render($this->getLayoutData()),
];
echo json_encode($data);
return;
}
if (!$this->saveParams())
{
throw new RuntimeException('Unable to save plugin settings', 500);
}
echo json_encode(['sent' => (int) $this->sendStats()]);
}
/**
* Get the data through events
*
* @param string $context Context where this will be called from
*
* @return array
*
* @since 3.5
*/
public function onGetStatsData($context)
{
return $this->getStatsData();
}
/**
* Debug a layout of this plugin
*
* @param string $layoutId Layout identifier
* @param array $data Optional data for the layout
*
* @return string
*
* @since 3.5
*/
public function debug($layoutId, $data = [])
{
$data = array_merge($this->getLayoutData(), $data);
return $this->getRenderer($layoutId)->debug($data);
}
/**
* Get the data for the layout
*
* @return array
*
* @since 3.5
*/
protected function getLayoutData()
{
return [
'plugin' => $this,
'pluginParams' => $this->params,
'statsData' => $this->getStatsData(),
];
}
/**
* Get the layout paths
*
* @return array
*
* @since 3.5
*/
protected function getLayoutPaths()
{
$template = Factory::getApplication()->getTemplate();
return [
JPATH_ADMINISTRATOR . '/templates/' . $template . '/html/layouts/plugins/' . $this->_type . '/' . $this->_name,
__DIR__ . '/layouts',
];
}
/**
* Get the plugin renderer
*
* @param string $layoutId Layout identifier
*
* @return JLayout
*
* @since 3.5
*/
protected function getRenderer($layoutId = 'default')
{
$renderer = new FileLayout($layoutId);
$renderer->setIncludePaths($this->getLayoutPaths());
return $renderer;
}
/**
* Get the data that will be sent to the stats server.
*
* @return array
*
* @since 3.5
*/
private function getStatsData()
{
$data = [
'unique_id' => $this->getUniqueId(),
'php_version' => PHP_VERSION,
'db_type' => $this->db->name,
'db_version' => $this->db->getVersion(),
'cms_version' => JVERSION,
'server_os' => php_uname('s') . ' ' . php_uname('r'),
];
// Check if we have a MariaDB version string and extract the proper version from it
if (preg_match('/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i', $data['db_version'], $versionParts))
{
$data['db_version'] = $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch'];
}
return $data;
}
/**
* Get the unique id. Generates one if none is set.
*
* @return integer
*
* @since 3.5
*/
private function getUniqueId()
{
if (null === $this->uniqueId)
{
$this->uniqueId = $this->params->get('unique_id', hash('sha1', UserHelper::genRandomPassword(28) . time()));
}
return $this->uniqueId;
}
/**
* Check if current user is allowed to send the data
*
* @return boolean
*
* @since 3.5
*/
private function isAllowedUser()
{
return Factory::getUser()->authorise('core.admin');
}
/**
* Check if the debug is enabled
*
* @return boolean
*
* @since 3.5
*/
private function isDebugEnabled()
{
return defined('PLG_SYSTEM_STATS_DEBUG');
}
/**
* Check if last_run + interval > now
*
* @return boolean
*
* @since 3.5
*/
private function isUpdateRequired()
{
$last = (int) $this->params->get('lastrun', 0);
$interval = (int) $this->params->get('interval', 12);
$mode = (int) $this->params->get('mode', 0);
if ($mode === static::MODE_ALLOW_NEVER)
{
return false;
}
// Never updated or debug enabled
if (!$last || $this->isDebugEnabled())
{
return true;
}
return abs(time() - $last) > $interval * 3600;
}
/**
* Check valid AJAX request
*
* @return boolean
*
* @since 3.5
*/
private function isAjaxRequest()
{
return strtolower($this->app->input->server->get('HTTP_X_REQUESTED_WITH', '')) === 'xmlhttprequest';
}
/**
* Render a layout of this plugin
*
* @param string $layoutId Layout identifier
* @param array $data Optional data for the layout
*
* @return string
*
* @since 3.5
*/
public function render($layoutId, $data = [])
{
$data = array_merge($this->getLayoutData(), $data);
return $this->getRenderer($layoutId)->render($data);
}
/**
* Save the plugin parameters
*
* @return boolean
*
* @since 3.5
*/
private function saveParams()
{
// Update params
$this->params->set('lastrun', time());
$this->params->set('unique_id', $this->getUniqueId());
$interval = (int) $this->params->get('interval', 12);
$this->params->set('interval', $interval ?: 12);
$paramsJson = $this->params->toString('JSON');
$db = $this->db;
$query = $db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('params') . ' = :params')
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
->where($db->quoteName('element') . ' = ' . $db->quote('stats'))
->bind(':params', $paramsJson);
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 false;
}
try
{
// Update the plugin parameters
$result = $db->setQuery($query)->execute();
$this->clearCacheGroups(['com_plugins']);
}
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;
}
return $result;
}
/**
* Send the stats to the stats server
*
* @return boolean
*
* @since 3.5
*
* @throws RuntimeException If there is an error sending the data and debug mode enabled.
*/
private function sendStats()
{
$error = false;
try
{
// Don't let the request take longer than 2 seconds to avoid page timeout issues
$response = HttpFactory::getHttp()->post($this->serverUrl, $this->getStatsData(), [], 2);
if (!$response)
{
$error = 'Could not send site statistics to remote server: No response';
}
elseif ($response->code !== 200)
{
$data = json_decode($response->body);
$error = 'Could not send site statistics to remote server: ' . $data->message;
}
}
catch (UnexpectedValueException $e)
{
// There was an error sending stats. Should we do anything?
$error = 'Could not send site statistics to remote server: ' . $e->getMessage();
}
catch (RuntimeException $e)
{
// There was an error connecting to the server or in the post request
$error = 'Could not connect to statistics server: ' . $e->getMessage();
}
catch (Exception $e)
{
// An unexpected error in processing; don't let this failure kill the site
$error = 'Unexpected error connecting to statistics server: ' . $e->getMessage();
}
if ($error !== false)
{
// Log any errors if logging enabled.
Log::add($error, Log::WARNING, 'jerror');
// If Stats debug mode enabled, or Global Debug mode enabled, show error to the user.
if ($this->isDebugEnabled() || $this->app->get('debug'))
{
throw new RuntimeException($error, 500);
}
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
*
* @return void
*
* @since 3.5
*/
private function clearCacheGroups(array $clearGroups)
{
foreach ($clearGroups as $group)
{
try
{
$options = [
'defaultgroup' => $group,
'cachebase' => $this->app->get('cache_path', JPATH_CACHE),
];
$cache = Cache::getInstance('callback', $options);
$cache->clean();
}
catch (Exception $e)
{
// Ignore it
}
}
}
/**
* Disable this plugin, if user selects once or never, to stop Joomla loading the plugin on every page load and
* therefore regaining a tiny bit of performance
*
* @since 4.0.0
*
* @return boolean
*/
private function disablePlugin()
{
$db = $this->db;
$query = $db->getQuery(true)
->update($db->quoteName('#__extensions'))
->set($db->quoteName('enabled') . ' = 0')
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
->where($db->quoteName('folder') . ' = ' . $db->quote('system'))
->where($db->quoteName('element') . ' = ' . $db->quote('stats'));
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 false;
}
try
{
// Update the plugin parameters
$result = $db->setQuery($query)->execute();
$this->clearCacheGroups(['com_plugins']);
}
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;
}
return $result;
}
}
stats/stats.xml 0000604 00000003453 15075053024 0007564 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>plg_system_stats</name>
<author>Joomla! Project</author>
<creationDate>November 2013</creationDate>
<copyright>(C) 2013 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.5.0</version>
<description>PLG_SYSTEM_STATS_XML_DESCRIPTION</description>
<namespace path="src">Joomla\Plugin\System\Stats</namespace>
<files>
<folder>field</folder>
<folder>layouts</folder>
<filename plugin="stats">stats.php</filename>
</files>
<languages folder="language">
<language tag="en-GB">en-GB/en-GB.plg_system_stats.ini</language>
<language tag="en-GB">en-GB/en-GB.plg_system_stats.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic" addfieldprefix="Joomla\Plugin\System\Stats\Field">
<field
name="data"
type="data"
label=""
/>
<field
name="unique_id"
type="uniqueid"
label="PLG_SYSTEM_STATS_UNIQUE_ID_LABEL"
size="10"
/>
<field
name="interval"
type="number"
label="PLG_SYSTEM_STATS_INTERVAL_LABEL"
filter="integer"
default="12"
/>
<field
name="mode"
type="list"
label="PLG_SYSTEM_STATS_MODE_LABEL"
default="1"
validate="options"
>
<option value="1">PLG_SYSTEM_STATS_MODE_OPTION_ALWAYS_SEND</option>
<option value="2">PLG_SYSTEM_STATS_MODE_OPTION_ON_DEMAND</option>
<option value="3">PLG_SYSTEM_STATS_MODE_OPTION_NEVER_SEND</option>
</field>
<field
name="lastrun"
type="hidden"
default="0"
size="15"
/>
</fieldset>
</fields>
</config>
</extension>
stats/layouts/stats.php 0000604 00000002351 15075053024 0011247 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright (C) 2016 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\Language\Text;
extract($displayData);
/**
* Layout variables
* -----------------
* @var array $statsData Array containing the data that will be sent to the stats server
*/
$versionFields = array('php_version', 'db_version', 'cms_version');
?>
<table class="table mb-3 d-none" id="js-pstats-data-details">
<caption class="visually-hidden">
<?php echo Text::_('PLG_SYSTEM_STATS_STATISTICS'); ?>
</caption>
<thead>
<tr>
<th scope="col" class="w-15">
<?php echo Text::_('PLG_SYSTEM_STATS_SETTING'); ?>
</th>
<th scope="col">
<?php echo Text::_('PLG_SYSTEM_STATS_VALUE'); ?>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($statsData as $key => $value) : ?>
<tr>
<th scope="row"><?php echo Text::_('PLG_SYSTEM_STATS_LABEL_' . strtoupper($key)); ?></th>
<td><?php echo in_array($key, $versionFields) ? (preg_match('/\d+(?:\.\d+)+/', $value, $matches) ? $matches[0] : $value) : $value; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
stats/layouts/message.php 0000604 00000003402 15075053024 0011533 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright (C) 2015 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\Language\Text;
use Joomla\Registry\Registry;
extract($displayData);
/**
* Layout variables
* -----------------
* @var PlgSystemStats $plugin Plugin rendering this layout
* @var Registry $pluginParams Plugin parameters
* @var array $statsData Array containing the data that will be sent to the stats server
*/
?>
<joomla-alert type="info" dismiss class="js-pstats-alert hidden" role="alertdialog" close-text="<?php echo Text::_('JCLOSE'); ?>" aria-labelledby="alert-stats-heading">
<div class="alert-heading"><?php echo Text::_('PLG_SYSTEM_STATS_LABEL_MESSAGE_TITLE'); ?></div>
<div>
<div class="alert-message">
<p>
<?php echo Text::_('PLG_SYSTEM_STATS_MSG_JOOMLA_WANTS_TO_SEND_DATA'); ?>
<a href="#" class="js-pstats-btn-details alert-link"><?php echo Text::_('PLG_SYSTEM_STATS_MSG_WHAT_DATA_WILL_BE_SENT'); ?></a>
</p>
<?php
echo $plugin->render('stats', compact('statsData'));
?>
<p><?php echo Text::_('PLG_SYSTEM_STATS_MSG_ALLOW_SENDING_DATA'); ?></p>
<p class="actions">
<button type="button" class="btn btn-primary js-pstats-btn-allow-always"><?php echo Text::_('PLG_SYSTEM_STATS_BTN_SEND_ALWAYS'); ?></button>
<button type="button" class="btn btn-primary js-pstats-btn-allow-once"><?php echo Text::_('PLG_SYSTEM_STATS_BTN_SEND_NOW'); ?></button>
<button type="button" class="btn btn-primary js-pstats-btn-allow-never"><?php echo Text::_('PLG_SYSTEM_STATS_BTN_NEVER_SEND'); ?></button>
</p>
</div>
</div>
</joomla-alert>
stats/layouts/field/data.php 0000604 00000005000 15075053024 0012077 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright (C) 2016 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\Language\Text;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->registerAndUseScript('plg_system_stats.stats', 'plg_system_stats/stats.js', [], ['defer' => true], ['core']);
extract($displayData);
/**
* Layout variables
* -----------------
* @var string $autocomplete Autocomplete attribute for the field.
* @var boolean $autofocus Is autofocus enabled?
* @var string $class Classes for the input.
* @var string $description Description of the field.
* @var boolean $disabled Is this field disabled?
* @var string $group Group the field belongs to. <fields> section in form XML.
* @var boolean $hidden Is this field hidden in the form?
* @var string $hint Placeholder for the field.
* @var string $id DOM id of the field.
* @var string $label Label of the field.
* @var string $labelclass Classes to apply to the label.
* @var boolean $multiple Does this field support multiple values?
* @var string $name Name of the input field.
* @var string $onchange Onchange attribute for the field.
* @var string $onclick Onclick attribute for the field.
* @var string $pattern Pattern (Reg Ex) of value of the form field.
* @var boolean $readonly Is this field read only?
* @var boolean $repeat Allows extensions to duplicate elements.
* @var boolean $required Is this field required?
* @var integer $size Size attribute of the input.
* @var boolean $spellcheck Spellcheck state for the form field.
* @var string $validate Validation rules to apply.
* @var string $value Value attribute of the field.
* @var array $options Options available for this field.
* @var array $statsData Statistics that will be sent to the stats server
*/
?>
<?php if (count($statsData)): ?>
<a href="#" id="js-pstats-data-details-toggler"><?php echo Text::_('PLG_SYSTEM_STATS_MSG_WHAT_DATA_WILL_BE_SENT'); ?></a>
<?php echo $field->render('stats', compact('statsData')); ?>
<?php endif; ?>
stats/layouts/field/uniqueid.php 0000604 00000004372 15075053024 0013024 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage System.stats
*
* @copyright (C) 2016 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\Language\Text;
extract($displayData);
/**
* Layout variables
* -----------------
* @var string $autocomplete Autocomplete attribute for the field.
* @var boolean $autofocus Is autofocus enabled?
* @var string $class Classes for the input.
* @var string $description Description of the field.
* @var boolean $disabled Is this field disabled?
* @var string $group Group the field belongs to. <fields> section in form XML.
* @var boolean $hidden Is this field hidden in the form?
* @var string $hint Placeholder for the field.
* @var string $id DOM id of the field.
* @var string $label Label of the field.
* @var string $labelclass Classes to apply to the label.
* @var boolean $multiple Does this field support multiple values?
* @var string $name Name of the input field.
* @var string $onchange Onchange attribute for the field.
* @var string $onclick Onclick attribute for the field.
* @var string $pattern Pattern (Reg Ex) of value of the form field.
* @var boolean $readonly Is this field read only?
* @var boolean $repeat Allows extensions to duplicate elements.
* @var boolean $required Is this field required?
* @var integer $size Size attribute of the input.
* @var boolean $spellcheck Spellcheck state for the form field.
* @var string $validate Validation rules to apply.
* @var string $value Value attribute of the field.
* @var array $options Options available for this field.
*/
?>
<input type="hidden" name="<?php echo $name; ?>" id="<?php echo $id; ?>" value="<?php echo htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); ?>">
<button class="btn btn-secondary" type="button" id="js-pstats-reset-uid">
<span class="icon-sync"></span> <?php echo Text::_('PLG_SYSTEM_STATS_RESET_UNIQUE_ID'); ?>
</button>
akeebaupdatecheck/akeebaupdatecheck.php 0000604 00000015631 15075053024 0014302 0 ustar 00 <?php
/**
* @package akeebabackup
* @copyright Copyright (c)2006-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
use FOF30\Date\Date;
defined('_JEXEC') or die();
// PHP version check
if (!version_compare(PHP_VERSION, '5.6.0', '>='))
{
return;
}
JLoader::import('joomla.application.plugin');
class plgSystemAkeebaupdatecheck extends JPlugin
{
/**
* Constructor
*
* @param object $subject The object to observe
* @param array $config An array that holds the plugin configuration
*
* @since 2.5
*/
public function __construct(& $subject, $config)
{
/**
* I know that this piece of code cannot possibly be executed since I have already returned BEFORE declaring
* the class when eAccelerator is detected. However, eAccelerator is a GINORMOUS, STINKY PILE OF BULL CRAP. The
* stupid thing will return above BUT it will also declare the class EVEN THOUGH according to how PHP works
* this part of the code should be unreachable o_O Therefore I have to define this constant and exit the
* constructor when we have already determined that this class MUST NOT be defined. Because screw you
* eAccelerator, that's why.
*/
if (defined('AKEEBA_EACCELERATOR_IS_SO_BORKED_IT_DOES_NOT_EVEN_RETURN'))
{
return;
}
parent::__construct($subject, $config);
}
public function onAfterInitialise()
{
// Make sure Akeeba Backup is installed
if (!file_exists(JPATH_ADMINISTRATOR . '/components/com_akeeba'))
{
return;
}
// Make sure Akeeba Backup is enabled
JLoader::import('joomla.application.component.helper');
if ( !JComponentHelper::isEnabled('com_akeeba'))
{
return;
}
// Load FOF. Required for the Date class.
if (!defined('FOF30_INCLUDED') && !@include_once(JPATH_LIBRARIES . '/fof30/include.php'))
{
throw new RuntimeException('FOF 3.0 is not installed', 500);
}
// Do we have to run (at most once per 3 hours)?
JLoader::import('joomla.html.parameter');
JLoader::import('joomla.application.component.helper');
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->qn('lastupdate'))
->from($db->qn('#__ak_storage'))
->where($db->qn('tag') . ' = ' . $db->q('akeebaupdatecheck_lastrun'));
$last = $db->setQuery($query)->loadResult();
if (intval($last))
{
$last = new Date($last);
$last = $last->toUnix();
}
else
{
$last = 0;
}
$now = time();
if (!defined('AKEEBAUPDATECHECK_DEBUG') && (abs($now - $last) < 86400))
{
return;
}
// Use a 20% chance of running; this allows multiple concurrent page
// requests to not cause double update emails being sent out.
$random = rand(1, 5);
if (!defined('AKEEBAUPDATECHECK_DEBUG') && ($random != 3))
{
return;
}
$now = new Date($now);
// Update last run status
// If I have the time of the last run, I can update, otherwise insert
if ($last)
{
$query = $db->getQuery(true)
->update($db->qn('#__ak_storage'))
->set($db->qn('lastupdate') . ' = ' . $db->q($now->toSql()))
->where($db->qn('tag') . ' = ' . $db->q('akeebaupdatecheck_lastrun'));
}
else
{
$query = $db->getQuery(true)
->insert($db->qn('#__ak_storage'))
->columns(array($db->qn('tag'), $db->qn('lastupdate')))
->values($db->q('akeebaupdatecheck_lastrun') . ', ' . $db->q($now->toSql()));
}
try
{
$result = $db->setQuery($query)->execute();
}
catch (Exception $exc)
{
$result = false;
}
if (!$result)
{
return;
}
// Load the container
$container = FOF30\Container\Container::getInstance('com_akeeba');
/** @var \Akeeba\Backup\Admin\Model\Updates $model */
$model = $container->factory->model('Updates')->tmpInstance();
$updateInfo = $model->getUpdates();
if (!$updateInfo['hasUpdate'])
{
return;
}
$superAdmins = array();
$superAdminEmail = $this->params->get('email', '');
if (!empty($superAdminEmail))
{
$superAdmins = $this->getSuperUsers($superAdminEmail);
}
if (empty($superAdmins))
{
$superAdmins = $this->getSuperUsers();
}
if (empty($superAdmins))
{
return;
}
foreach ($superAdmins as $sa)
{
$model->sendNotificationEmail($updateInfo['version'], $sa->email);
}
}
/**
* Returns the Super Users' email information. If you provide a comma separated $email list we will check that these
* emails do belong to Super Users and that they have not blocked reception of system emails.
*
* @param null|string $email A list of Super Users to email
*
* @return array The list of Super User emails
*/
private function getSuperUsers($email = null)
{
// Get a reference to the database object
$db = JFactory::getDbo();
// Convert the email list to an array
if (!empty($email))
{
$temp = explode(',', $email);
$emails = array();
foreach ($temp as $entry)
{
$entry = trim($entry);
$emails[] = $db->q($entry);
}
$emails = array_unique($emails);
}
else
{
$emails = array();
}
// Get a list of groups which have Super User privileges
$ret = array();
// Get a list of groups with core.admin (Super User) permissions
try
{
$query = $db->getQuery(true)
->select($db->qn('rules'))
->from($db->qn('#__assets'))
->where($db->qn('parent_id') . ' = ' . $db->q(0));
$db->setQuery($query, 0, 1);
$rulesJSON = $db->loadResult();
$rules = json_decode($rulesJSON, true);
$rawGroups = $rules['core.admin'];
$groups = array();
if (empty($rawGroups))
{
return $ret;
}
foreach ($rawGroups as $g => $enabled)
{
if ($enabled)
{
$groups[] = $db->q($g);
}
}
if (empty($groups))
{
return $ret;
}
}
catch (Exception $exc)
{
return $ret;
}
// Get the user IDs of users belonging to the groups with the core.admin (Super User) privilege
try
{
$query = $db->getQuery(true)
->select($db->qn('user_id'))
->from($db->qn('#__user_usergroup_map'))
->where($db->qn('group_id') . ' IN(' . implode(',', $groups) . ')' );
$db->setQuery($query);
$rawUserIDs = $db->loadColumn(0);
if (empty($rawUserIDs))
{
return $ret;
}
$userIDs = array();
foreach ($rawUserIDs as $id)
{
$userIDs[] = $db->q($id);
}
}
catch (Exception $exc)
{
return $ret;
}
// Get the user information for the Super Users
try
{
$query = $db->getQuery(true)
->select(array(
$db->qn('id'),
$db->qn('username'),
$db->qn('email'),
))->from($db->qn('#__users'))
->where($db->qn('id') . ' IN(' . implode(',', $userIDs) . ')')
->where($db->qn('sendEmail') . ' = ' . $db->q('1'));
if (!empty($emails))
{
$query->where($db->qn('email') . 'IN(' . implode(',', $emails) . ')');
}
$db->setQuery($query);
$ret = $db->loadObjectList();
}
catch (Exception $exc)
{
return $ret;
}
return $ret;
}
}
akeebaupdatecheck/akeebaupdatecheck.xml 0000604 00000002636 15075053024 0014314 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<!--
~ @package akeebabackup
~ @copyright Copyright (c)2006-2019 Nicholas K. Dionysopoulos / Akeeba Ltd
~ @license GNU General Public License version 3, or later
-->
<extension version="2.5.0" type="plugin" group="system" method="upgrade">
<name>PLG_SYSTEM_AKEEBAUPDATECHECK</name>
<author>Nicholas K. Dionysopoulos</author>
<authorEmail>nicholas@dionysopoulos.me</authorEmail>
<authorUrl>http://www.akeebabackup.com</authorUrl>
<copyright>Copyright (c)2006-2019 Nicholas K. Dionysopoulos</copyright>
<license>GNU General Public License version 3, or later</license>
<creationDate>2019-03-18</creationDate>
<version>6.4.2.1</version>
<description>PLG_AKEEBAUPDATECHECK_XML_DESCRIPTION</description>
<files>
<filename plugin="akeebaupdatecheck">akeebaupdatecheck.php</filename>
<filename>.htaccess</filename>
<filename>web.config</filename>
</files>
<languages folder="language">
<language tag="en-GB">en-GB/en-GB.plg_system_akeebaupdatecheck.ini</language>
<language tag="en-GB">en-GB/en-GB.plg_system_akeebaupdatecheck.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field name="email" type="text" default="" size="40" label="PLG_SYSTEM_AKEEBAUPDATECHECK_EMAIL_LBL" description="PLG_SYSTEM_AKEEBAUPDATECHECK_EMAIL_DESC" />
</fieldset>
</fields>
</config>
<scriptfile>script.php</scriptfile>
</extension>