primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,302 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Controller;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Application\CMSWebApplicationInterface;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
use Joomla\Input\Input;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Controller for global configuration
*
* @since 1.5
*/
class ApplicationController extends BaseController
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
* Recognized key values include 'name', 'default_task', 'model_path', and
* 'view_path' (this list is not meant to be comprehensive).
* @param ?MVCFactoryInterface $factory The factory.
* @param ?CMSApplication $app The Application for the dispatcher
* @param ?Input $input Input
*
* @since 3.0
*/
public function __construct($config = [], ?MVCFactoryInterface $factory = null, $app = null, $input = null)
{
parent::__construct($config, $factory, $app, $input);
// Map the apply task to the save method.
$this->registerTask('apply', 'save');
}
/**
* Cancel operation.
*
* @return void
*
* @since 3.0.0
*/
public function cancel()
{
$this->setRedirect(Route::_('index.php?option=com_cpanel'));
}
/**
* Saves the form
*
* @return void|boolean Void on success. Boolean false on fail.
*
* @since 4.0.0
*/
public function save()
{
// Check for request forgeries.
$this->checkToken();
// Check if the user is authorized to do this.
if (!$this->app->getIdentity()->authorise('core.admin')) {
$this->setRedirect('index.php', Text::_('JERROR_ALERTNOAUTHOR'), 'error');
return false;
}
$this->app->setUserState('com_config.config.global.data', null);
/** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */
$model = $this->getModel('Application', 'Administrator');
$data = $this->input->post->get('jform', [], 'array');
// Complete data array if needed
$oldData = $model->getData();
$data = array_replace($oldData, $data);
// Get request type
$saveFormat = $this->app->getDocument()->getType();
// Handle service requests
if ($saveFormat == 'json') {
$form = $model->getForm();
$return = $model->validate($form, $data);
if ($return === false) {
$this->app->setHeader('Status', 422, true);
return false;
}
return $model->save($return);
}
// Must load after serving service-requests
$form = $model->getForm();
// Validate the posted data.
$return = $model->validate($form, $data);
// Check for validation errors.
if ($return === false) {
// Get the validation messages.
$errors = $model->getErrors();
// Push up to three validation messages out to the user.
for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
if ($errors[$i] instanceof \Exception) {
$this->app->enqueueMessage($errors[$i]->getMessage(), CMSWebApplicationInterface::MSG_ERROR);
} else {
$this->app->enqueueMessage($errors[$i], CMSWebApplicationInterface::MSG_ERROR);
}
}
// Save the posted data in the session.
$this->app->setUserState('com_config.config.global.data', $data);
// Redirect back to the edit screen.
$this->setRedirect(Route::_('index.php?option=com_config', false));
return false;
}
// Validate database connection data.
$data = $return;
$return = $model->validateDbConnection($data);
// Check for validation errors.
if ($return === false) {
/*
* The validateDbConnection method enqueued all messages for us.
*/
// Save the posted data in the session.
$this->app->setUserState('com_config.config.global.data', $data);
// Redirect back to the edit screen.
$this->setRedirect(Route::_('index.php?option=com_config', false));
return false;
}
// Save the validated data in the session.
$this->app->setUserState('com_config.config.global.data', $return);
// Attempt to save the configuration.
$data = $return;
$return = $model->save($data);
// Check the return value.
if ($return === false) {
/*
* The save method enqueued all messages for us, so we just need to redirect back.
*/
// Save failed, go back to the screen and display a notice.
$this->setRedirect(Route::_('index.php?option=com_config', false));
return false;
}
// Set the success message.
$this->app->enqueueMessage(Text::_('COM_CONFIG_SAVE_SUCCESS'), 'message');
// Set the redirect based on the task.
switch ($this->input->getCmd('task')) {
case 'apply':
$this->setRedirect(Route::_('index.php?option=com_config', false));
break;
case 'save':
default:
$this->setRedirect(Route::_('index.php', false));
break;
}
}
/**
* Method to remove root in global configuration.
*
* @return boolean
*
* @since 3.2
*/
public function removeroot()
{
// Check for request forgeries.
if (!Session::checkToken('get')) {
$this->setRedirect('index.php', Text::_('JINVALID_TOKEN'), 'error');
return false;
}
// Check if the user is authorized to do this.
if (!$this->app->getIdentity()->authorise('core.admin')) {
$this->setRedirect('index.php', Text::_('JERROR_ALERTNOAUTHOR'), 'error');
return false;
}
// Initialise model.
/** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */
$model = $this->getModel('Application', 'Administrator');
// Attempt to save the configuration and remove root.
try {
$model->removeroot();
} catch (\RuntimeException $e) {
// Save failed, go back to the screen and display a notice.
$this->setRedirect('index.php', Text::_('JERROR_SAVE_FAILED', $e->getMessage()), 'error');
return false;
}
// Set the redirect based on the task.
$this->setRedirect(Route::_('index.php'), Text::_('COM_CONFIG_SAVE_SUCCESS'));
return true;
}
/**
* Method to send the test mail.
*
* @return void
*
* @since 3.5
*/
public function sendtestmail()
{
// Send json mime type.
$this->app->mimeType = 'application/json';
$this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet);
$this->app->sendHeaders();
// Check if user token is valid.
if (!Session::checkToken()) {
$this->app->enqueueMessage(Text::_('JINVALID_TOKEN'), 'error');
echo new JsonResponse();
$this->app->close();
}
// Check if the user is authorized to do this.
if (!$this->app->getIdentity()->authorise('core.admin')) {
$this->app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error');
echo new JsonResponse();
$this->app->close();
}
/** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */
$model = $this->getModel('Application', 'Administrator');
echo new JsonResponse($model->sendTestMail());
$this->app->close();
}
/**
* Method to GET permission value and give it to the model for storing in the database.
*
* @return void
*
* @since 3.5
*/
public function store()
{
// Send json mime type.
$this->app->mimeType = 'application/json';
$this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet);
$this->app->sendHeaders();
// Check if user token is valid.
if (!Session::checkToken('get')) {
$this->app->enqueueMessage(Text::_('JINVALID_TOKEN'), 'error');
echo new JsonResponse();
$this->app->close();
}
/** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */
$model = $this->getModel('Application', 'Administrator');
echo new JsonResponse($model->storePermissions());
$this->app->close();
}
}

View File

@ -0,0 +1,213 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Controller;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\FormController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Input\Input;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Note: this view is intended only to be opened in a popup
*
* @since 1.5
*/
class ComponentController extends FormController
{
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
* Recognized key values include 'name', 'default_task', 'model_path', and
* 'view_path' (this list is not meant to be comprehensive).
* @param ?MVCFactoryInterface $factory The factory.
* @param ?CMSApplication $app The Application for the dispatcher
* @param ?Input $input Input
*
* @since 3.0
*/
public function __construct($config = [], ?MVCFactoryInterface $factory = null, $app = null, $input = null)
{
parent::__construct($config, $factory, $app, $input);
// Map the apply task to the save method.
$this->registerTask('apply', 'save');
}
/**
* Method to save component configuration.
*
* @param string $key The name of the primary key of the URL variable.
* @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
*
* @return boolean
*
* @since 3.2
*/
public function save($key = null, $urlVar = null)
{
// Check for request forgeries.
$this->checkToken();
$data = $this->input->get('jform', [], 'ARRAY');
$id = $this->input->get('id', null, 'INT');
$option = $this->input->get('component');
$user = $this->app->getIdentity();
$context = "$this->option.edit.$this->context.$option";
/** @var \Joomla\Component\Config\Administrator\Model\ComponentModel $model */
$model = $this->getModel('Component', 'Administrator');
$model->setState('component.option', $option);
$form = $model->getForm();
// Make sure com_joomlaupdate and com_privacy can only be accessed by SuperUser
if (\in_array(strtolower($option), ['com_joomlaupdate', 'com_privacy'], true) && !$user->authorise('core.admin')) {
$this->setRedirect(Route::_('index.php', false), Text::_('JERROR_ALERTNOAUTHOR'), 'error');
}
// Check if the user is authorised to do this.
if (!$user->authorise('core.admin', $option) && !$user->authorise('core.options', $option)) {
$this->setRedirect(Route::_('index.php', false), Text::_('JERROR_ALERTNOAUTHOR'), 'error');
}
// Remove the permissions rules data if user isn't allowed to edit them.
if (!$user->authorise('core.admin', $option) && isset($data['params']) && isset($data['params']['rules'])) {
unset($data['params']['rules']);
}
$returnUri = $this->input->post->get('return', null, 'base64');
$redirect = '';
if (!empty($returnUri)) {
$redirect = '&return=' . urlencode($returnUri);
}
// Validate the posted data.
$return = $model->validate($form, $data);
// Check for validation errors.
if ($return === false) {
// Save the data in the session.
$this->app->setUserState($context . '.data', $data);
// Redirect back to the edit screen.
$this->setRedirect(
Route::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false),
$model->getError(),
'error'
);
return false;
}
// Attempt to save the configuration.
$data = [
'params' => $return,
'id' => $id,
'option' => $option,
];
try {
$model->save($data);
} catch (\RuntimeException $e) {
// Save the data in the session.
$this->app->setUserState($context . '.data', $data);
// Save failed, go back to the screen and display a notice.
$this->setRedirect(
Route::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false),
Text::_('JERROR_SAVE_FAILED', $e->getMessage()),
'error'
);
return false;
}
// Clear session data.
$this->app->setUserState($context . '.data', null);
// Set the redirect based on the task.
switch ($this->input->get('task')) {
case 'apply':
$this->setRedirect(
Route::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false),
Text::_('COM_CONFIG_SAVE_SUCCESS'),
'message'
);
break;
case 'save':
$this->setMessage(Text::_('COM_CONFIG_SAVE_SUCCESS'), 'message');
// No break
default:
$redirect = 'index.php?option=' . $option;
if (!empty($returnUri)) {
$redirect = base64_decode($returnUri);
}
// Don't redirect to an external URL.
if (!Uri::isInternal($redirect)) {
$redirect = Uri::base();
}
$this->setRedirect(Route::_($redirect, false));
}
return true;
}
/**
* Method to cancel global configuration component.
*
* @param string $key The name of the primary key of the URL variable.
*
* @return boolean
*
* @since 3.2
*/
public function cancel($key = null)
{
$component = $this->input->get('component');
// Clear session data.
$this->app->setUserState("$this->option.edit.$this->context.$component.data", null);
// Calculate redirect URL
$returnUri = $this->input->post->get('return', null, 'base64');
$redirect = 'index.php?option=' . $component;
if (!empty($returnUri)) {
$redirect = base64_decode($returnUri);
}
// Don't redirect to an external URL.
if (!Uri::isInternal($redirect)) {
$redirect = Uri::base();
}
$this->setRedirect(Route::_($redirect, false));
return true;
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Router\Route;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Controller for global configuration
*
* @since 1.5
*/
class DisplayController extends BaseController
{
/**
* The default view.
*
* @var string
* @since 1.6
*/
protected $default_view = 'application';
/**
* Typical view method for MVC based architecture
*
* This function is provide as a default implementation, in most cases
* you will need to override it in your own controllers.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe url parameters and their variable types.
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
*
* @return static A \JControllerLegacy object to support chaining.
*
* @since 3.0
* @throws \Exception
*/
public function display($cachable = false, $urlparams = [])
{
$component = $this->input->get('component', '');
// Make sure com_joomlaupdate and com_privacy can only be accessed by SuperUser
if (
\in_array(strtolower($component), ['com_joomlaupdate', 'com_privacy'])
&& !$this->app->getIdentity()->authorise('core.admin')
) {
$this->setRedirect(Route::_('index.php'), Text::_('JERROR_ALERTNOAUTHOR'), 'error');
}
return parent::display($cachable, $urlparams);
}
}

View File

@ -0,0 +1,95 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Requests from the frontend
*
* @since 4.0.0
*/
class RequestController extends BaseController
{
/**
* Execute the controller.
*
* @return mixed A rendered view or false
*
* @since 3.2
*/
public function getJson()
{
$componentFolder = $this->input->getWord('option', 'com_config');
if ($this->app->isClient('administrator')) {
$viewName = $this->input->getWord('view', 'application');
} else {
$viewName = $this->input->getWord('view', 'config');
}
// Register the layout paths for the view
$paths = new \SplPriorityQueue();
if ($this->app->isClient('administrator')) {
$paths->insert(JPATH_ADMINISTRATOR . '/components/' . $componentFolder . '/view/' . $viewName . '/tmpl', 1);
} else {
$paths->insert(JPATH_BASE . '/components/' . $componentFolder . '/view/' . $viewName . '/tmpl', 1);
}
$model = new \Joomla\Component\Config\Administrator\Model\ApplicationModel();
$component = $model->getState()->get('component.option');
// Access check.
if (
!$this->app->getIdentity()->authorise('core.admin', $component)
&& !$this->app->getIdentity()->authorise('core.options', $component)
) {
$this->app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error');
return false;
}
try {
$data = $model->getData();
} catch (\Exception $e) {
$this->app->enqueueMessage($e->getMessage(), 'error');
return false;
}
// Required data
$requiredData = [
'sitename' => null,
'offline' => null,
'access' => null,
'list_limit' => null,
'MetaDesc' => null,
'MetaRights' => null,
'sef' => null,
'sitename_pagetitles' => null,
'debug' => null,
'debug_lang' => null,
'error_reporting' => null,
'mailfrom' => null,
'fromname' => null,
];
$data = array_intersect_key($data, $requiredData);
return json_encode($data);
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Dispatcher;
use Joomla\CMS\Access\Exception\NotAllowed;
use Joomla\CMS\Dispatcher\ComponentDispatcher;
use Joomla\Component\Config\Administrator\Helper\ConfigHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* ComponentDispatcher class for com_config
*
* @since 4.2.9
*/
class Dispatcher extends ComponentDispatcher
{
/**
* Check if the user have the right access to the component config
*
* @return void
*
* @since 4.2.9
*
* @throws \Exception
*/
protected function checkAccess(): void
{
// sendtestmail and store do their own checks, so leave the method to handle the permission and send response itself
if (\in_array($this->input->getCmd('task'), ['application.sendtestmail', 'application.store'], true)) {
return;
}
$task = $this->input->getCmd('task', 'display');
$view = $this->input->getCmd('view');
$component = $this->input->getCmd('component');
if ($component && (substr($task, 0, 10) === 'component.' || $view === 'component')) {
// User is changing component settings, check if he has permission to do that
$canAccess = ConfigHelper::canChangeComponentConfig($component);
} else {
// For everything else, user is required to have global core.admin permission to perform action
$canAccess = $this->app->getIdentity()->authorise('core.admin');
}
if (!$canAccess) {
throw new NotAllowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403);
}
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Extension;
use Joomla\CMS\Component\Router\RouterServiceInterface;
use Joomla\CMS\Component\Router\RouterServiceTrait;
use Joomla\CMS\Extension\MVCComponent;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Component class for com_config
*
* @since 4.0.0
*/
class ConfigComponent extends MVCComponent implements RouterServiceInterface
{
use RouterServiceTrait;
}

View File

@ -0,0 +1,83 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Field;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Field\ListField;
use Joomla\CMS\Language\Text;
use Joomla\Utilities\ArrayHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Text Filters form field.
*
* @since 3.7.0
*/
class ConfigComponentsField extends ListField
{
/**
* The form field type.
*
* @var string
* @since 3.7.0
*/
public $type = 'ConfigComponents';
/**
* Method to get a list of options for a list input.
*
* @return array An array of JHtml options.
*
* @since 3.7.0
*/
protected function getOptions()
{
$db = $this->getDatabase();
$query = $db->getQuery(true)
->select('name AS text, element AS value')
->from('#__extensions')
->where('enabled >= 1')
->where('type =' . $db->quote('component'));
$items = $db->setQuery($query)->loadObjectList();
if ($items) {
$lang = Factory::getLanguage();
foreach ($items as &$item) {
// Load language
$extension = $item->value;
if (is_file(JPATH_ADMINISTRATOR . '/components/' . $extension . '/config.xml')) {
$source = JPATH_ADMINISTRATOR . '/components/' . $extension;
$lang->load("$extension.sys", JPATH_ADMINISTRATOR)
|| $lang->load("$extension.sys", $source);
// Translate component name
$item->text = Text::_($item->text);
} else {
$item = null;
}
}
// Sort by component name
$items = ArrayHelper::sortObjects(array_filter($items), 'text', 1, true, true);
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $items);
return $options;
}
}

View File

@ -0,0 +1,176 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Field;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormField;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Text Filters form field.
*
* @since 1.6
*/
class FiltersField extends FormField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
public $type = 'Filters';
/**
* Method to get the field input markup.
*
* @todo: Add access check.
*
* @return string The field input markup.
*
* @since 1.6
*/
protected function getInput()
{
// Add translation string for notification
Text::script('COM_CONFIG_TEXT_FILTERS_NOTE');
// Add Javascript
Factory::getDocument()->getWebAssetManager()->useScript('com_config.filters');
// Get the available user groups.
$groups = $this->getUserGroups();
// Build the form control.
$html = [];
// Open the table.
$html[] = '<table id="filter-config" class="table">';
$html[] = '<caption class="visually-hidden">' . Text::_('COM_CONFIG_TEXT_FILTERS') . '</caption>';
// The table heading.
$html[] = ' <thead>';
$html[] = ' <tr>';
$html[] = ' <th scope="col">';
$html[] = ' <span class="acl-action">' . Text::_('JGLOBAL_FILTER_GROUPS_LABEL') . '</span>';
$html[] = ' </th>';
$html[] = ' <th scope="col">';
$html[] = ' <span class="acl-action">' . Text::_('JGLOBAL_FILTER_TYPE_LABEL') . '</span>';
$html[] = ' </th>';
$html[] = ' <th scope="col">';
$html[] = ' <span class="acl-action">' . Text::_('JGLOBAL_FILTER_TAGS_LABEL') . '</span>';
$html[] = ' </th>';
$html[] = ' <th scope="col">';
$html[] = ' <span class="acl-action">' . Text::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . '</span>';
$html[] = ' </th>';
$html[] = ' </tr>';
$html[] = ' </thead>';
// The table body.
$html[] = ' <tbody>';
foreach ($groups as $group) {
if (!isset($this->value[$group->value])) {
$this->value[$group->value] = ['filter_type' => 'BL', 'filter_tags' => '', 'filter_attributes' => ''];
}
$group_filter = $this->value[$group->value];
$group_filter['filter_tags'] = !empty($group_filter['filter_tags']) ? $group_filter['filter_tags'] : '';
$group_filter['filter_attributes'] = !empty($group_filter['filter_attributes']) ? $group_filter['filter_attributes'] : '';
$html[] = ' <tr>';
$html[] = ' <th class="acl-groups left" scope="row">';
$html[] = ' ' . LayoutHelper::render('joomla.html.treeprefix', ['level' => $group->level + 1]) . $group->text;
$html[] = ' </th>';
$html[] = ' <td>';
$html[] = ' <label for="' . $this->id . $group->value . '_filter_type" class="visually-hidden">'
. Text::_('JGLOBAL_FILTER_TYPE_LABEL') . '</label>';
$html[] = ' <select'
. ' name="' . $this->name . '[' . $group->value . '][filter_type]"'
. ' id="' . $this->id . $group->value . '_filter_type"'
. ' data-parent="' . ($group->parent) . '" '
. ' data-id="' . ($group->value) . '" '
. ' class="novalidate form-select"'
. '>';
$html[] = ' <option value="BL"' . ($group_filter['filter_type'] == 'BL' ? ' selected="selected"' : '') . '>'
. Text::_('COM_CONFIG_FIELD_FILTERS_DEFAULT_FORBIDDEN_LIST') . '</option>';
$html[] = ' <option value="CBL"' . ($group_filter['filter_type'] == 'CBL' ? ' selected="selected"' : '') . '>'
. Text::_('COM_CONFIG_FIELD_FILTERS_CUSTOM_FORBIDDEN_LIST') . '</option>';
$html[] = ' <option value="WL"' . ($group_filter['filter_type'] == 'WL' ? ' selected="selected"' : '') . '>'
. Text::_('COM_CONFIG_FIELD_FILTERS_ALLOWED_LIST') . '</option>';
$html[] = ' <option value="NH"' . ($group_filter['filter_type'] == 'NH' ? ' selected="selected"' : '') . '>'
. Text::_('COM_CONFIG_FIELD_FILTERS_NO_HTML') . '</option>';
$html[] = ' <option value="NONE"' . ($group_filter['filter_type'] == 'NONE' ? ' selected="selected"' : '') . '>'
. Text::_('COM_CONFIG_FIELD_FILTERS_NO_FILTER') . '</option>';
$html[] = ' </select>';
$html[] = ' </td>';
$html[] = ' <td>';
$html[] = ' <label for="' . $this->id . $group->value . '_filter_tags" class="visually-hidden">'
. Text::_('JGLOBAL_FILTER_TAGS_LABEL') . '</label>';
$html[] = ' <input'
. ' name="' . $this->name . '[' . $group->value . '][filter_tags]"'
. ' type="text"'
. ' id="' . $this->id . $group->value . '_filter_tags" class="novalidate form-control"'
. ' value="' . htmlspecialchars($group_filter['filter_tags'], ENT_QUOTES) . '"'
. '>';
$html[] = ' </td>';
$html[] = ' <td>';
$html[] = ' <label for="' . $this->id . $group->value . '_filter_attributes"'
. ' class="visually-hidden">' . Text::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . '</label>';
$html[] = ' <input'
. ' name="' . $this->name . '[' . $group->value . '][filter_attributes]"'
. ' type="text"'
. ' id="' . $this->id . $group->value . '_filter_attributes" class="novalidate form-control"'
. ' value="' . htmlspecialchars($group_filter['filter_attributes'], ENT_QUOTES) . '"'
. '>';
$html[] = ' </td>';
$html[] = ' </tr>';
}
$html[] = ' </tbody>';
// Close the table.
$html[] = '</table>';
return implode("\n", $html);
}
/**
* A helper to get the list of user groups.
*
* @return array
*
* @since 1.6
*/
protected function getUserGroups()
{
// Get a database object.
$db = $this->getDatabase();
// Get the user groups from the database.
$query = $db->getQuery(true);
$query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level, a.parent_id as parent');
$query->from('#__usergroups AS a');
$query->join('LEFT', '#__usergroups AS b on a.lft > b.lft AND a.rgt < b.rgt');
$query->group('a.id, a.title, a.lft');
$query->order('a.lft ASC');
$db->setQuery($query);
$options = $db->loadObjectList();
return $options;
}
}

View File

@ -0,0 +1,152 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Helper;
use Joomla\CMS\Application\ApplicationHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ContentHelper;
use Joomla\CMS\Language\Text;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Components helper for com_config
*
* @since 3.0
*/
class ConfigHelper extends ContentHelper
{
/**
* Get an array of all enabled components.
*
* @return array
*
* @since 3.0
*/
public static function getAllComponents()
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('element')
->from('#__extensions')
->where('type = ' . $db->quote('component'))
->where('enabled = 1');
$db->setQuery($query);
$result = $db->loadColumn();
return $result;
}
/**
* Returns true if the component has configuration options.
*
* @param string $component Component name
*
* @return boolean
*
* @since 3.0
*/
public static function hasComponentConfig($component)
{
return is_file(JPATH_ADMINISTRATOR . '/components/' . $component . '/config.xml');
}
/**
* Returns true if the current user has permission to access and change configuration options.
*
* @param string $component Component name
*
* @return boolean
*
* @since 4.2.9
*/
public static function canChangeComponentConfig(string $component)
{
$user = Factory::getApplication()->getIdentity();
if (!\in_array(strtolower($component), ['com_joomlaupdate', 'com_privacy'], true)) {
return $user->authorise('core.admin', $component) || $user->authorise('core.options', $component);
}
return $user->authorise('core.admin');
}
/**
* Returns an array of all components with configuration options.
* Optionally return only those components for which the current user has 'core.manage' rights.
*
* @param boolean $authCheck True to restrict to components where current user has 'core.manage' rights.
*
* @return array
*
* @since 3.0
*/
public static function getComponentsWithConfig($authCheck = true)
{
$result = [];
$components = self::getAllComponents();
// Remove com_config from the array as that may have weird side effects
$components = array_diff($components, ['com_config']);
foreach ($components as $component) {
if (self::hasComponentConfig($component) && (!$authCheck || self::canChangeComponentConfig($component))) {
self::loadLanguageForComponent($component);
$result[$component] = ApplicationHelper::stringURLSafe(Text::_($component)) . '_' . $component;
}
}
asort($result);
return array_keys($result);
}
/**
* Load the sys language for the given component.
*
* @param array $components Array of component names.
*
* @return void
*
* @since 3.0
*/
public static function loadLanguageForComponents($components)
{
foreach ($components as $component) {
self::loadLanguageForComponent($component);
}
}
/**
* Load the sys language for the given component.
*
* @param string $component component name.
*
* @return void
*
* @since 3.5
*/
public static function loadLanguageForComponent($component)
{
if (empty($component)) {
return;
}
$lang = Factory::getLanguage();
// Load the core file then
// Load extension-local file.
$lang->load($component . '.sys', JPATH_BASE)
|| $lang->load($component . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,239 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\Model;
use Joomla\CMS\Access\Access;
use Joomla\CMS\Access\Rules;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Model\FormModel;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Table\Table;
use Joomla\Filesystem\Path;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Model for component configuration
*
* @since 3.2
*/
class ComponentModel extends FormModel
{
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @return void
*
* @since 3.2
*/
protected function populateState()
{
$input = Factory::getApplication()->getInput();
// Set the component (option) we are dealing with.
$component = $input->get('component');
$this->state->set('component.option', $component);
// Set an alternative path for the configuration file.
if ($path = $input->getString('path')) {
$path = Path::clean(JPATH_SITE . '/' . $path);
Path::check($path);
$this->state->set('component.path', $path);
}
}
/**
* Method to get a form object.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
*
* @return mixed A Form object on success, false on failure
*
* @since 3.2
*/
public function getForm($data = [], $loadData = true)
{
$state = $this->getState();
$option = $state->get('component.option');
if ($path = $state->get('component.path')) {
// Add the search path for the admin component config.xml file.
Form::addFormPath($path);
} else {
// Add the search path for the admin component config.xml file.
Form::addFormPath(JPATH_ADMINISTRATOR . '/components/' . $option);
}
// Get the form.
$form = $this->loadForm(
'com_config.component',
'config',
['control' => 'jform', 'load_data' => $loadData],
false,
'/config'
);
if (empty($form)) {
return false;
}
$lang = Factory::getLanguage();
$lang->load($option, JPATH_BASE)
|| $lang->load($option, JPATH_BASE . "/components/$option");
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return array The default data is an empty array.
*
* @since 4.0.0
*/
protected function loadFormData()
{
$option = $this->getState()->get('component.option');
// Check the session for previously entered form data.
$data = Factory::getApplication()->getUserState('com_config.edit.component.' . $option . '.data', []);
if (empty($data)) {
return $this->getComponent()->getParams()->toArray();
}
return $data;
}
/**
* Get the component information.
*
* @return object
*
* @since 3.2
*/
public function getComponent()
{
$state = $this->getState();
$option = $state->get('component.option');
// Load common and local language files.
$lang = Factory::getLanguage();
$lang->load($option, JPATH_BASE)
|| $lang->load($option, JPATH_BASE . "/components/$option");
$result = ComponentHelper::getComponent($option);
return $result;
}
/**
* Method to save the configuration data.
*
* @param array $data An array containing all global config data.
*
* @return boolean True on success, false on failure.
*
* @since 3.2
* @throws \RuntimeException
*/
public function save($data)
{
$table = Table::getInstance('extension');
$context = $this->option . '.' . $this->name;
PluginHelper::importPlugin('extension');
// Check super user group.
if (isset($data['params']) && !$this->getCurrentUser()->authorise('core.admin')) {
$form = $this->getForm([], false);
foreach ($form->getFieldsets() as $fieldset) {
foreach ($form->getFieldset($fieldset->name) as $field) {
if (
$field->type === 'UserGroupList' && isset($data['params'][$field->fieldname])
&& (int) $field->getAttribute('checksuperusergroup', 0) === 1
&& Access::checkGroup($data['params'][$field->fieldname], 'core.admin')
) {
throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
}
}
}
}
// Save the rules.
if (isset($data['params']['rules'])) {
if (!$this->getCurrentUser()->authorise('core.admin', $data['option'])) {
throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
}
$rules = new Rules($data['params']['rules']);
$asset = Table::getInstance('asset');
if (!$asset->loadByName($data['option'])) {
$root = Table::getInstance('asset');
$root->loadByName('root.1');
$asset->name = $data['option'];
$asset->title = $data['option'];
$asset->setLocation($root->id, 'last-child');
}
$asset->rules = (string) $rules;
if (!$asset->check() || !$asset->store()) {
throw new \RuntimeException($asset->getError());
}
// We don't need this anymore
unset($data['option']);
unset($data['params']['rules']);
}
// Load the previous Data
if (!$table->load($data['id'])) {
throw new \RuntimeException($table->getError());
}
unset($data['id']);
// Bind the data.
if (!$table->bind($data)) {
throw new \RuntimeException($table->getError());
}
// Check the data.
if (!$table->check()) {
throw new \RuntimeException($table->getError());
}
$result = Factory::getApplication()->triggerEvent('onExtensionBeforeSave', [$context, $table, false]);
// Store the data.
if (\in_array(false, $result, true) || !$table->store()) {
throw new \RuntimeException($table->getError());
}
Factory::getApplication()->triggerEvent('onExtensionAfterSave', [$context, $table, false]);
// Clean the component cache.
$this->cleanCache('_system');
return true;
}
}

View File

@ -0,0 +1,152 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\View\Application;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
use Joomla\Component\Config\Administrator\Helper\ConfigHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* View for the global configuration
*
* @since 3.2
*/
class HtmlView extends BaseHtmlView
{
/**
* The model state
*
* @var \Joomla\Registry\Registry
* @since 3.2
*/
public $state;
/**
* The form object
*
* @var \Joomla\CMS\Form\Form
* @since 3.2
*/
public $form;
/**
* The data to be displayed in the form
*
* @var array
* @since 3.2
*/
public $data;
/**
* Title of the fieldset
*
* @var string
*/
public $name;
/**
* Name of the fields to display
*
* @var string
*/
public $fieldsname;
/**
* CSS class of the form
*
* @var string
*/
public $formclass;
/**
* Description of the fieldset
*
* @var string
*/
public $description;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @see \JViewLegacy::loadTemplate()
* @since 3.0
*/
public function display($tpl = null)
{
try {
// Load Form and Data
$form = $this->get('form');
$data = $this->get('data');
$user = $this->getCurrentUser();
} catch (\Exception $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return;
}
// Bind data
if ($form && $data) {
$form->bind($data);
}
// Get the params for com_users.
$usersParams = ComponentHelper::getParams('com_users');
// Get the params for com_media.
$mediaParams = ComponentHelper::getParams('com_media');
$this->form = &$form;
$this->data = &$data;
$this->usersParams = &$usersParams;
$this->mediaParams = &$mediaParams;
$this->components = ConfigHelper::getComponentsWithConfig();
ConfigHelper::loadLanguageForComponents($this->components);
$this->userIsSuperAdmin = $user->authorise('core.admin');
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 3.2
*/
protected function addToolbar()
{
$toolbar = $this->getDocument()->getToolbar();
ToolbarHelper::title(Text::_('COM_CONFIG_GLOBAL_CONFIGURATION'), 'cog config');
$toolbar->apply('application.apply');
$toolbar->divider();
$toolbar->save('application.save');
$toolbar->divider();
$toolbar->cancel('application.cancel');
$toolbar->divider();
$toolbar->inlinehelp();
$toolbar->help('Site_Global_Configuration');
}
}

View File

@ -0,0 +1,168 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Config\Administrator\View\Component;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
use Joomla\Component\Config\Administrator\Helper\ConfigHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* View for the component configuration
*
* @since 3.2
*/
class HtmlView extends BaseHtmlView
{
/**
* The model state
*
* @var \Joomla\Registry\Registry
* @since 3.2
*/
public $state;
/**
* The form object
*
* @var \Joomla\CMS\Form\Form
* @since 3.2
*/
public $form;
/**
* An object with the information for the component
*
* @var \Joomla\CMS\Component\ComponentRecord
* @since 3.2
*/
public $component;
/**
* List of fieldset objects
*
* @var object[]
*
* @since 5.2.0
*/
public $fieldsets;
/**
* Form control
*
* @var string
*
* @since 5.2.0
*/
public $formControl;
/**
* Base64 encoded return URL
*
* @var string
*
* @since 5.2.0
*/
public $return;
/**
* Execute and display a template script.
*
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
*
* @return void
*
* @see \JViewLegacy::loadTemplate()
* @since 3.2
*/
public function display($tpl = null)
{
try {
$this->component = $this->get('component');
if (!$this->component->enabled) {
return;
}
$this->form = $this->get('Form');
$user = $this->getCurrentUser();
} catch (\Exception $e) {
Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return;
}
$this->fieldsets = $this->form ? $this->form->getFieldsets() : null;
$this->formControl = $this->form ? $this->form->getFormControl() : null;
// Don't show permissions fieldset if not authorised.
if (!$user->authorise('core.admin', $this->component->option) && isset($this->fieldsets['permissions'])) {
unset($this->fieldsets['permissions']);
}
$this->components = ConfigHelper::getComponentsWithConfig();
$this->userIsSuperAdmin = $user->authorise('core.admin');
$this->currentComponent = Factory::getApplication()->getInput()->get('component');
$this->return = Factory::getApplication()->getInput()->get('return', '', 'base64');
$this->addToolbar();
parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 3.2
*/
protected function addToolbar()
{
$toolbar = $this->getDocument()->getToolbar();
ToolbarHelper::title(Text::_($this->component->option . '_configuration'), 'cog config');
$toolbar->apply('component.apply');
$toolbar->divider();
$toolbar->save('component.save');
$toolbar->divider();
$toolbar->cancel('component.cancel');
$toolbar->divider();
$inlinehelp = (string) $this->form->getXml()->config->inlinehelp['button'] === 'show';
$targetClass = (string) $this->form->getXml()->config->inlinehelp['targetclass'] ?: 'hide-aware-inline-help';
if ($inlinehelp) {
$toolbar->inlinehelp($targetClass);
}
$helpUrl = $this->form->getData()->get('helpURL');
$helpKey = (string) $this->form->getXml()->config->help['key'];
// Try with legacy language key
if (!$helpKey) {
$language = Factory::getApplication()->getLanguage();
$languageKey = 'JHELP_COMPONENTS_' . strtoupper($this->currentComponent) . '_OPTIONS';
if ($language->hasKey($languageKey)) {
$helpKey = $languageKey;
}
}
$toolbar->help($helpKey, (bool) $helpUrl, null, $this->currentComponent);
}
}