diff --git a/.gitignore b/.gitignore index 9dca7c2df1542..e54f2b3aaed62 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ .vscode .docker /docker-compose.yml +/nbproject # Local System Files (i.e. cache, logs, etc.) /administrator/cache diff --git a/README.md b/README.md index 48c341afad878..59913300d202d 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ Joomla! CMS™ [![Analytics](https://ga-beacon.appspot.com/UA-544070-3/joomla-cm Build Status --------------------- -| Drone-CI | AppVeyor | -| ------------- | ------------- | -| [![Build Status](https://ci.joomla.org/api/badges/joomla/joomla-cms/status.svg?branch=4.0-dev)](https://ci.joomla.org/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/ru6sxal8jmfckvjc/branch/4.0-dev?svg=true)](https://ci.appveyor.com/project/release-joomla/joomla-cms) | +| Drone-CI | AppVeyor | PHP | Node | npm | +| ------------- | ------------- | ------------- | ------------- | ------------- | +| [![Build Status](https://ci.joomla.org/api/badges/joomla/joomla-cms/status.svg?branch=4.0-dev)](https://ci.joomla.org/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/ru6sxal8jmfckvjc/branch/4.0-dev?svg=true)](https://ci.appveyor.com/project/release-joomla/joomla-cms) | [![PHP](https://img.shields.io/badge/PHP-V7.2.5-green)](https://www.php.net/) | [![node-lts](https://img.shields.io/badge/Node-V12.0-green)](https://nodejs.org/en/) | [![npm](https://img.shields.io/badge/npm-v6.13.4-green)](https://nodejs.org/en/) | Overview --------------------- diff --git a/administrator/components/com_admin/forms/profile.xml b/administrator/components/com_admin/forms/profile.xml deleted file mode 100644 index 6d98d352d30b3..0000000000000 --- a/administrator/components/com_admin/forms/profile.xml +++ /dev/null @@ -1,200 +0,0 @@ - -
-
- - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - -
-
- - diff --git a/administrator/components/com_admin/postinstall/htaccess.php b/administrator/components/com_admin/postinstall/htaccess.php deleted file mode 100644 index 9ae0c85a3fca5..0000000000000 --- a/administrator/components/com_admin/postinstall/htaccess.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @license GNU General Public License version 2 or later; see LICENSE.txt - * - * This file contains post-installation message handling for notifying users of a change - * in the default .htaccess and web.config files. - */ - -defined('_JEXEC') or die; - -/** - * Notifies users of a change in the default .htaccess or web.config file - * - * This check returns true regardless of condition. - * - * @return boolean - * - * @since 3.4 - */ -function admin_postinstall_htaccess_condition() -{ - return true; -} diff --git a/administrator/components/com_admin/postinstall/updatedefaultsettings.php b/administrator/components/com_admin/postinstall/updatedefaultsettings.php deleted file mode 100644 index 86774efe721a1..0000000000000 --- a/administrator/components/com_admin/postinstall/updatedefaultsettings.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @license GNU General Public License version 2 or later; see LICENSE.txt - * - * This file contains post-installation message handling for notifying users of a change - * in various default settings. - */ - -defined('_JEXEC') or die; - -/** - * Notifies users of a change in various default settings - * - * This check returns true regardless of condition. - * - * @return boolean - * - * @since 3.8.8 - */ -function admin_postinstall_updatedefaultsettings_condition() -{ - return true; -} diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index f295caa2a7429..f74f2e68093dc 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -57,7 +57,7 @@ public function preflight($action, $installer) { $manifestValues = json_decode($installer->extension->manifest_cache, true); - if ((array_key_exists('version', $manifestValues))) + if (array_key_exists('version', $manifestValues)) { $this->fromVersion = $manifestValues['version']; @@ -5045,6 +5045,17 @@ public function deleteUnexistingFiles($dryRun = false, $suppressOutput = false) '/templates/cassiopeia/html/layouts/chromes/cardGrey.php', '/templates/cassiopeia/html/layouts/chromes/default.php', '/templates/cassiopeia/scss/vendor/bootstrap/_card.scss', + // Joomla 4.0 Beta 7 + '/media/vendor/skipto/js/dropMenu.js', + '/media/vendor/skipto/css/SkipTo.css', + // Joomla 4.0 Beta 8 + '/administrator/components/com_admin/forms/profile.xml', + '/administrator/components/com_admin/postinstall/htaccess.php', + '/administrator/components/com_admin/postinstall/updatedefaultsettings.php', + '/administrator/components/com_admin/src/Controller/ProfileController.php', + '/administrator/components/com_admin/src/Model/ProfileModel.php', + '/administrator/components/com_admin/src/View/Profile/HtmlView.php', + '/administrator/components/com_admin/tmpl/profile/edit.php', ); $folders = array( @@ -6233,10 +6244,11 @@ public function deleteUnexistingFiles($dryRun = false, $suppressOutput = false) '/libraries/vendor/joomla/controller', // Joomla 4.0 Beta 5 '/plugins/content/imagelazyload', - // Joomla 4.0 Beta 6 - '/media/vendor/skipto/js/skipTo.js', - '/media/vendor/skipto/js/dropMenu.js', - '/media/vendor/skipto/css/SkipTo.css' + // Joomla 4.0 Beta 7 + '/media/vendor/skipto/css', + // Joomla 4.0 Beta 8 + '/administrator/components/com_admin/src/View/Profile', + '/administrator/components/com_admin/tmpl/profile', ); $status['files_checked'] = $files; @@ -7084,6 +7096,11 @@ private function convertBlogLayouts() // Convert to the according CSS class depending on order = "down" or "across". $layout = ($order === 0) ? 'masonry-' : 'columns-'; + if (!isset($params['blog_class'])) + { + $params['blog_class'] = ''; + } + if (strpos($params['blog_class'], $layout) === false) { $params['blog_class'] .= ' ' . $layout . $nColumns; @@ -7105,7 +7122,7 @@ private function convertBlogLayouts() // Update global parameters for com_content. $nColumns = $contentParams->get('num_columns'); - if ($nColumns !== null || true) + if ($nColumns !== null) { $nColumns = (int) $nColumns; $order = (int) $contentParams->get('multi_column_order', '0'); @@ -7153,7 +7170,7 @@ private function convertBlogLayouts() * * @return void * - * @since 4.0.0 + * @since 3.10.0 */ protected function fixFilenameCasing() { diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2021-02-28.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2021-02-28.sql new file mode 100644 index 0000000000000..26fc302a5b0bd --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2021-02-28.sql @@ -0,0 +1,8 @@ +DELETE FROM `#__postinstall_messages` + WHERE `title_key` + IN ('COM_CPANEL_MSG_EACCELERATOR_TITLE', + 'COM_CPANEL_MSG_HTACCESS_TITLE', + 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', + 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE', + 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', + 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2021-02-28.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2021-02-28.sql new file mode 100644 index 0000000000000..07e70403adc9b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2021-02-28.sql @@ -0,0 +1,8 @@ +DELETE FROM "#__postinstall_messages" + WHERE "title_key" + IN ('COM_CPANEL_MSG_EACCELERATOR_TITLE', + 'COM_CPANEL_MSG_HTACCESS_TITLE', + 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', + 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE', + 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', + 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE'); diff --git a/administrator/components/com_admin/src/Controller/ProfileController.php b/administrator/components/com_admin/src/Controller/ProfileController.php deleted file mode 100644 index 15002d7414d2b..0000000000000 --- a/administrator/components/com_admin/src/Controller/ProfileController.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace Joomla\Component\Admin\Administrator\Controller; - -\defined('_JEXEC') or die; - -use Joomla\CMS\MVC\Controller\FormController; -use Joomla\CMS\Router\Route; -use Joomla\CMS\Uri\Uri; - -/** - * User profile controller class. - * - * @since 1.6 - */ -class ProfileController extends FormController -{ - /** - * Method to check if you can edit a record. - * - * Extended classes can override this if necessary. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = [], $key = 'id') - { - return isset($data['id']) && $data['id'] == $this->app->getIdentity()->id; - } - - /** - * Overrides parent save method to check the submitted passwords match. - * - * @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 True if successful, false otherwise. - * - * @since 3.2 - */ - public function save($key = null, $urlVar = null) - { - $result = parent::save(); - - if ($this->getTask() !== 'apply') - { - $return = base64_decode($this->input->get('return', '', 'BASE64')); - - if ($return !== '' && Uri::isInternal($return)) - { - // Redirect to return URL. - $this->setRedirect(Route::_($return, false)); - } - else - { - // Redirect to the main page. - $this->setRedirect(Route::_('index.php', false)); - } - } - - return $result; - } - - /** - * Method to cancel an edit. - * - * @param string $key The name of the primary key of the URL variable. - * - * @return boolean True if access level checks pass, false otherwise. - * - * @since 1.6 - */ - public function cancel($key = null) - { - $result = parent::cancel($key); - $return = base64_decode($this->input->get('return', '', 'BASE64')); - - if ($return !== '' && Uri::isInternal($return)) - { - // Redirect to return URL. - $this->setRedirect(Route::_($return, false)); - } - else - { - // Redirect to the main page. - $this->setRedirect(Route::_('index.php', false)); - } - - return $result; - } -} diff --git a/administrator/components/com_admin/src/Model/ProfileModel.php b/administrator/components/com_admin/src/Model/ProfileModel.php deleted file mode 100644 index f245a48fd6243..0000000000000 --- a/administrator/components/com_admin/src/Model/ProfileModel.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace Joomla\Component\Admin\Administrator\Model; - -\defined('_JEXEC') or die; - -use Joomla\CMS\Component\ComponentHelper; -use Joomla\CMS\Factory; -use Joomla\CMS\Form\Form; -use Joomla\CMS\Language\Multilanguage; -use Joomla\CMS\Plugin\PluginHelper; -use Joomla\Component\Users\Administrator\Model\UserModel; - -/** - * User model. - * - * @since 1.6 - */ -class ProfileModel extends UserModel -{ - /** - * Method to auto-populate the state. - * - * @return void - * - * @note Calling getState in this method will result in recursion. - * @since 4.0.0 - */ - protected function populateState() - { - parent::populateState(); - - $this->setState('user.id', Factory::getApplication()->getIdentity()->id); - } - - /** - * Method to get the record form. - * - * @param array $data An optional array of data for the form to interrogate. - * @param boolean $loadData True if the form is to load its own data (default case), false if not. - * - * @return Form A Form object on success, false on failure - * - * @since 1.6 - */ - public function getForm($data = [], $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_admin.profile', 'profile', ['control' => 'jform', 'load_data' => $loadData]); - - if (empty($form)) - { - return false; - } - - // Check for username compliance and parameter set - $isUsernameCompliant = true; - - if ($this->loadFormData()->username) - { - $username = $this->loadFormData()->username; - $isUsernameCompliant = !(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $username) || strlen(utf8_decode($username)) < 2 - || trim($username) != $username); - } - - $this->setState('user.username.compliant', $isUsernameCompliant); - - if (!ComponentHelper::getParams('com_users')->get('change_login_name') && $isUsernameCompliant) - { - $form->setFieldAttribute('username', 'required', 'false'); - $form->setFieldAttribute('username', 'readonly', 'true'); - $form->setFieldAttribute('username', 'description', 'COM_ADMIN_PROFILE_FIELD_NOCHANGE_USERNAME_DESC'); - } - - // When multilanguage is set, a user's default site language should also be a Content Language - if (Multilanguage::isEnabled()) - { - $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); - } - - // If the user needs to change their password, mark the password fields as required - if (Factory::getUser()->requireReset) - { - $form->setFieldAttribute('password', 'required', 'true'); - $form->setFieldAttribute('password2', 'required', 'true'); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = Factory::getApplication()->getUserState('com_users.edit.user.data', []); - - if (empty($data)) - { - $data = $this->getItem(); - } - - // Load the users plugins. - PluginHelper::importPlugin('user'); - - $this->preprocessData('com_admin.profile', $data); - - return $data; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 1.6 - */ - public function getItem($pk = null) - { - return parent::getItem(Factory::getUser()->id); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $user = Factory::getUser(); - $pk = $user->id; - $data['id'] = $pk; - $data['block'] = $user->block; - $iAmSuperAdmin = $user->authorise('core.admin'); - - if ($iAmSuperAdmin) - { - $data['groups'] = $user->groups; - } - - return parent::save($data); - } -} diff --git a/administrator/components/com_admin/src/View/Profile/HtmlView.php b/administrator/components/com_admin/src/View/Profile/HtmlView.php deleted file mode 100644 index 154419cb24023..0000000000000 --- a/administrator/components/com_admin/src/View/Profile/HtmlView.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -namespace Joomla\Component\Admin\Administrator\View\Profile; - -\defined('_JEXEC') or die; - -use Joomla\CMS\Factory; -use Joomla\CMS\Language\Text; -use Joomla\CMS\MVC\View\GenericDataException; -use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; -use Joomla\CMS\Toolbar\ToolbarHelper; - -/** - * View class to allow users edit their own profile. - * - * @since 1.6 - */ -class HtmlView extends BaseHtmlView -{ - /** - * The form object - * - * @var \Joomla\CMS\Form\Form - * @since 1.6 - */ - protected $form; - - /** - * The item being viewed - * - * @var \Joomla\CMS\Object\CMSObject - * @since 1.6 - */ - protected $item; - - /** - * The model state - * - * @var \Joomla\CMS\Object\CMSObject - * @since 1.6 - */ - protected $state; - - /** - * Configuration forms for all two-factor authentication methods - * - * @var array - * @since 3.10.0 - */ - protected $twofactorform; - - /** - * Returns the one time password (OTP) – a.k.a. two factor authentication – configuration for the user. - * - * @var \stdClass - * @since 4.0.0 - */ - protected $otpConfig; - - /** - * Execute and display a template script. - * - * @param string $tpl The name of the template file to parse; automatically searches through the template paths. - * - * @return mixed A string if successful, otherwise an Error object. - * - * @since 1.6 - */ - public function display($tpl = null) - { - /** @var \Joomla\Component\Admin\Administrator\Model\ProfileModel $model */ - $model = $this->getModel(); - - $this->form = $model->getForm(); - $this->item = $model->getItem(); - $this->state = $model->getState(); - $this->twofactorform = $model->getTwofactorform(); - $this->otpConfig = $model->getOtpConfig(); - - // Check for errors. - if ($errors = $model->getErrors()) - { - throw new GenericDataException(implode("\n", $errors), 500); - } - - $this->form->setValue('password', null); - $this->form->setValue('password2', null); - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - Factory::getApplication()->input->set('hidemainmenu', 1); - - ToolbarHelper::title(Text::_('COM_ADMIN_VIEW_PROFILE_TITLE'), 'user user-profile'); - - ToolbarHelper::apply('profile.apply'); - ToolbarHelper::divider(); - ToolbarHelper::save('profile.save'); - ToolbarHelper::divider(); - ToolbarHelper::cancel('profile.cancel', 'JTOOLBAR_CLOSE'); - ToolbarHelper::divider(); - ToolbarHelper::help('JHELP_ADMIN_USER_PROFILE_EDIT'); - } -} diff --git a/administrator/components/com_admin/tmpl/profile/edit.php b/administrator/components/com_admin/tmpl/profile/edit.php deleted file mode 100644 index 452013a191ca9..0000000000000 --- a/administrator/components/com_admin/tmpl/profile/edit.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -defined('_JEXEC') or die; - -use Joomla\CMS\Factory; -use Joomla\CMS\HTML\HTMLHelper; -use Joomla\CMS\Language\Text; -use Joomla\CMS\Layout\LayoutHelper; -use Joomla\CMS\Router\Route; -use Joomla\Component\Users\Administrator\Helper\UsersHelper; - -HTMLHelper::_('behavior.formvalidator'); -HTMLHelper::_('behavior.keepalive'); -HTMLHelper::_('script', 'com_users/two-factor-switcher.js', ['version' => 'auto', 'relative' => true], ['defer' => true]); - -$input = Factory::getApplication()->input; - -// Get the form fieldsets. -$fieldsets = $this->form->getFieldsets(); - -// Fieldsets to not automatically render by /layouts/joomla/edit/params.php -$this->useCoreUI = true; -?> -
- 'user_details']); ?> - - twofactorform) && $this->item->id) : ?> - -
-
- -
-
- 'Joomla.twoFactorMethodChange();', 'class' => 'form-select'], 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false); ?> -
-
-
- twofactorform as $form) : ?> - otpConfig->method ? '' : ' class="hidden"'; ?> -
> - -
- -
- -
- - - -
- - -
- otpConfig->otep)) : ?> -
- - -
- - otpConfig->otep as $otep) : ?> - - --- - - - -
- - - - - - - - -
diff --git a/administrator/components/com_associations/tmpl/associations/modal.php b/administrator/components/com_associations/tmpl/associations/modal.php index a7ee822580d71..52e2ac30fb6d6 100644 --- a/administrator/components/com_associations/tmpl/associations/modal.php +++ b/administrator/components/com_associations/tmpl/associations/modal.php @@ -100,8 +100,10 @@ ?> typeSupports['state'])) : ?> - - + + + + diff --git a/administrator/components/com_categories/tmpl/categories/modal.php b/administrator/components/com_categories/tmpl/categories/modal.php index da19df9fc2820..2500c0b44a004 100644 --- a/administrator/components/com_categories/tmpl/categories/modal.php +++ b/administrator/components/com_categories/tmpl/categories/modal.php @@ -101,8 +101,10 @@ } ?> - - + + + + $item->level)); ?> diff --git a/administrator/components/com_config/tmpl/component/default.php b/administrator/components/com_config/tmpl/component/default.php index 20e0efe552dd0..3bae731d4530b 100644 --- a/administrator/components/com_config/tmpl/component/default.php +++ b/administrator/components/com_config/tmpl/component/default.php @@ -77,7 +77,7 @@
label); ?> -
+
@@ -98,7 +98,7 @@
label); ?> -
+
diff --git a/administrator/components/com_contact/config.xml b/administrator/components/com_contact/config.xml index a7a0745cce330..8aad1e749cb0f 100644 --- a/administrator/components/com_contact/config.xml +++ b/administrator/components/com_contact/config.xml @@ -488,6 +488,17 @@ view="category" /> + + + + + J5 + + + + + + - - - - + -
+ , + , + + - , - , - -
@@ -116,8 +116,10 @@ } ?>
- + + + + diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml index 73d98a9563f04..c57385f2202d1 100644 --- a/administrator/components/com_content/config.xml +++ b/administrator/components/com_content/config.xml @@ -280,25 +280,26 @@ /> - - + + - - + + +
+ - diff --git a/administrator/components/com_content/src/Model/ArticleModel.php b/administrator/components/com_content/src/Model/ArticleModel.php index 92639c9f40d4b..6f0b7acc24458 100644 --- a/administrator/components/com_content/src/Model/ArticleModel.php +++ b/administrator/components/com_content/src/Model/ArticleModel.php @@ -485,7 +485,6 @@ public function getItem($pk = null) public function getForm($data = array(), $loadData = true) { $app = Factory::getApplication(); - $user = $app->getIdentity(); // Get the form. $form = $this->loadForm('com_content.article', 'article', array('control' => 'jform', 'load_data' => $loadData)); @@ -495,12 +494,17 @@ public function getForm($data = array(), $loadData = true) return false; } + // Object uses for checking edit state permission of article + $record = new \stdClass; + // Get ID of the article from input, for frontend, we use a_id while backend uses id $articleIdFromInput = $app->input->getInt('a_id') ?: $app->input->getInt('id', 0); // On edit article, we get ID of article from article.id state, but on save, we use data from input $id = (int) $this->getState('article.id', $articleIdFromInput); + $record->id = $id; + // For new articles we load the potential state + associations if ($id == 0 && $formField = $form->getField('catid')) { @@ -531,12 +535,13 @@ public function getForm($data = array(), $loadData = true) $form->setFieldAttribute('catid', 'refresh-enabled', true); $form->setFieldAttribute('catid', 'refresh-cat-id', $assignedCatids); $form->setFieldAttribute('catid', 'refresh-section', 'article'); + + // Store ID of the category uses for edit state permission check + $record->catid = $assignedCatids; } - // Check for existing article. // Modify the form based on Edit State access controls. - if ($id != 0 && (!$user->authorise('core.edit.state', 'com_content.article.' . (int) $id)) - || ($id == 0 && !$user->authorise('core.edit.state', 'com_content'))) + if (!$this->canEditState($record)) { // Disable fields for display. $form->setFieldAttribute('featured', 'disabled', 'true'); diff --git a/administrator/components/com_content/tmpl/article/edit.php b/administrator/components/com_content/tmpl/article/edit.php index 7f8dc4f1ce86a..e43878555abc9 100644 --- a/administrator/components/com_content/tmpl/article/edit.php +++ b/administrator/components/com_content/tmpl/article/edit.php @@ -71,7 +71,7 @@
-
+
diff --git a/administrator/components/com_content/tmpl/articles/modal.php b/administrator/components/com_content/tmpl/articles/modal.php index d26b5f5da5517..9b7596fc67e27 100644 --- a/administrator/components/com_content/tmpl/articles/modal.php +++ b/administrator/components/com_content/tmpl/articles/modal.php @@ -118,8 +118,10 @@ } ?>
- + + + + escape($onclick) . '"' diff --git a/administrator/components/com_content/tmpl/featured/default.php b/administrator/components/com_content/tmpl/featured/default.php index acaa3ed0c700f..8d447835792ca 100644 --- a/administrator/components/com_content/tmpl/featured/default.php +++ b/administrator/components/com_content/tmpl/featured/default.php @@ -118,11 +118,11 @@ - - + + + @@ -229,7 +229,7 @@ - + 'articles.', diff --git a/administrator/components/com_fields/forms/filter_fields.xml b/administrator/components/com_fields/forms/filter_fields.xml index 71962f9641073..ae79d53b6f754 100644 --- a/administrator/components/com_fields/forms/filter_fields.xml +++ b/administrator/components/com_fields/forms/filter_fields.xml @@ -13,10 +13,9 @@ name="search" type="text" inputmode="search" - label="" + label="COM_FIELDS_FIELDS_FILTER_SEARCH_LABEL" description="COM_FIELDS_FIELDS_FILTER_SEARCH_DESC" hint="JSEARCH_FILTER" - class="js-stools-search-string" /> - +
- - - - @@ -66,8 +66,9 @@ - diff --git a/administrator/components/com_media/resources/scripts/app/Event.es6.js b/administrator/components/com_media/resources/scripts/app/Event.es6.js index edda0e87fbe84..233cbe0c197cf 100644 --- a/administrator/components/com_media/resources/scripts/app/Event.es6.js +++ b/administrator/components/com_media/resources/scripts/app/Event.es6.js @@ -1,5 +1,3 @@ -import Vue from 'vue/dist/vue.esm.browser.min.js'; - /** * Media Event bus - used for communication between joomla and vue */ @@ -8,7 +6,7 @@ export default class Event { * Media Event constructor */ constructor() { - this.vue = new Vue(); + this.events = {}; } /** @@ -17,7 +15,9 @@ export default class Event { * @param data */ fire(event, data = null) { - this.vue.$emit(event, data); + if (this.events[event]) { + this.events[event].forEach((fn) => fn(data)); + } } /** @@ -26,6 +26,7 @@ export default class Event { * @param callback */ listen(event, callback) { - this.vue.$on(event, callback); + this.events[event] = this.events[event] || []; + this.events[event].push(callback); } } diff --git a/administrator/components/com_media/resources/scripts/app/Notifications.es6.js b/administrator/components/com_media/resources/scripts/app/Notifications.es6.js index 0b99a1850a5a9..e23f256643d86 100644 --- a/administrator/components/com_media/resources/scripts/app/Notifications.es6.js +++ b/administrator/components/com_media/resources/scripts/app/Notifications.es6.js @@ -4,7 +4,7 @@ class Notifications { success(message, options) { // eslint-disable-next-line no-use-before-define notifications.notify(message, { - type: 'message', + type: 'message', // @todo rename it to success dismiss: true, ...options, }); @@ -15,7 +15,7 @@ class Notifications { error(message, options) { // eslint-disable-next-line no-use-before-define notifications.notify(message, { - type: 'error', + type: 'error', // @todo rename it to danger dismiss: true, ...options, }); @@ -30,10 +30,17 @@ class Notifications { /* Send a notification */ // eslint-disable-next-line class-methods-use-this notify(message, options) { + let timer; + if (options.type === 'message') { + timer = 3000; + } Joomla.renderMessages( { [options.type]: [Joomla.JText._(message)], }, + undefined, + true, + timer, ); } } diff --git a/administrator/components/com_media/resources/scripts/components/app.vue b/administrator/components/com_media/resources/scripts/components/app.vue index ae68a690eaa04..7c8e667ae1307 100644 --- a/administrator/components/com_media/resources/scripts/components/app.vue +++ b/administrator/components/com_media/resources/scripts/components/app.vue @@ -71,7 +71,6 @@ export default { setFullHeight() { this.fullHeight = `${window.innerHeight - this.$el.getBoundingClientRect().top}px`; }, - }, }; diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/item.es6.js b/administrator/components/com_media/resources/scripts/components/browser/items/item.es6.js index cac4efd0a66ec..80416d66040a2 100644 --- a/administrator/components/com_media/resources/scripts/components/browser/items/item.es6.js +++ b/administrator/components/com_media/resources/scripts/components/browser/items/item.es6.js @@ -1,3 +1,4 @@ +import { h } from 'vue'; import Directory from './directory.vue'; import File from './file.vue'; import Image from './image.vue'; @@ -154,8 +155,8 @@ export default { value ? this.mouseover() : this.mouseleave(); }, }, - render(createElement) { - return createElement( + render() { + return h( 'div', { class: { @@ -163,21 +164,17 @@ export default { selected: this.isSelected(), active: this.isHoverActive(), }, - on: { - click: this.handleClick, - mouseover: this.mouseover, - mouseleave: this.mouseleave, - focused: this.focused, - }, + onClick: this.handleClick, + onMouseover: this.mouseover, + onMouseleave: this.mouseleave, + onFocused: this.focused, }, [ - createElement( + h( this.itemType(), { - props: { - item: this.item, - focused: this.focused, - }, + item: this.item, + focused: this.focused, }, ), ], diff --git a/administrator/components/com_media/resources/scripts/mediamanager.es6.js b/administrator/components/com_media/resources/scripts/mediamanager.es6.js index fa06891807285..2a9d16ce348c9 100644 --- a/administrator/components/com_media/resources/scripts/mediamanager.es6.js +++ b/administrator/components/com_media/resources/scripts/mediamanager.es6.js @@ -1,5 +1,4 @@ -import Vue from 'vue/dist/vue.esm.browser.min.js'; -import Lock from 'vue-focus-lock/src/index.js'; +import { createApp } from 'vue'; import Event from './app/Event.es6'; import App from './components/app.vue'; import Disk from './components/tree/disk.vue'; @@ -19,41 +18,36 @@ import ShareModal from './components/modals/share-modal.vue'; import ConfirmDeleteModal from './components/modals/confirm-delete-modal.vue'; import Infobar from './components/infobar/infobar.vue'; import Upload from './components/upload/upload.vue'; -import Translate from './plugins/translate.es6'; +import translate from './plugins/translate.es6'; import store from './store/store.es6'; -// Add the plugins -Vue.use(Translate); - -// Register the vue components -Vue.component('MediaDrive', Drive); -Vue.component('MediaDisk', Disk); -Vue.component('MediaTree', Tree); -Vue.component('MediaTreeItem', TreeItem); -Vue.component('MediaToolbar', Toolbar); -Vue.component('MediaBreadcrumb', Breadcrumb); -Vue.component('MediaBrowser', Browser); -Vue.component('MediaBrowserItem', BrowserItem); -Vue.component('MediaBrowserItemRow', BrowserItemRow); -Vue.component('MediaModal', Modal); -Vue.component('MediaCreateFolderModal', CreateFolderModal); -Vue.component('MediaPreviewModal', PreviewModal); -Vue.component('MediaRenameModal', RenameModal); -Vue.component('MediaShareModal', ShareModal); -Vue.component('MediaConfirmDeleteModal', ConfirmDeleteModal); -Vue.component('MediaInfobar', Infobar); -Vue.component('MediaUpload', Upload); -Vue.component('TabLock', Lock); - // Register MediaManager namespace window.MediaManager = window.MediaManager || {}; // Register the media manager event bus window.MediaManager.Event = new Event(); -// Create the root Vue instance -document.addEventListener('DOMContentLoaded', - () => new Vue({ - el: '#com-media', - store, - render: (h) => h(App), - })); +// Create the Vue app instance +const app = createApp(App); +app.use(store); +app.use(translate); + +// Register the vue components +app.component('MediaDrive', Drive); +app.component('MediaDisk', Disk); +app.component('MediaTree', Tree); +app.component('MediaTreeItem', TreeItem); +app.component('MediaToolbar', Toolbar); +app.component('MediaBreadcrumb', Breadcrumb); +app.component('MediaBrowser', Browser); +app.component('MediaBrowserItem', BrowserItem); +app.component('MediaBrowserItemRow', BrowserItemRow); +app.component('MediaModal', Modal); +app.component('MediaCreateFolderModal', CreateFolderModal); +app.component('MediaPreviewModal', PreviewModal); +app.component('MediaRenameModal', RenameModal); +app.component('MediaShareModal', ShareModal); +app.component('MediaConfirmDeleteModal', ConfirmDeleteModal); +app.component('MediaInfobar', Infobar); +app.component('MediaUpload', Upload); + +app.mount('#com-media'); diff --git a/administrator/components/com_media/resources/scripts/store/store.es6.js b/administrator/components/com_media/resources/scripts/store/store.es6.js index ca77e42f91d2e..fda89f86d35a3 100644 --- a/administrator/components/com_media/resources/scripts/store/store.es6.js +++ b/administrator/components/com_media/resources/scripts/store/store.es6.js @@ -1,16 +1,13 @@ -import Vue from 'vue/dist/vue.esm.browser.min.js'; -import Vuex from 'vuex/dist/vuex.esm.browser.min.js'; -import createPersistedState from 'vuex-persistedstate/dist/vuex-persistedstate.es.js'; +import { createStore } from 'vuex'; +import createPersistedState from 'vuex-persistedstate'; import state from './state.es6'; import * as getters from './getters.es6'; import * as actions from './actions.es6'; import mutations from './mutations.es6'; import { persistedStateOptions } from './plugins/persisted-state.es6'; -Vue.use(Vuex); - // A Vuex instance is created by combining the state, mutations, actions, and getters. -export default new Vuex.Store({ +export default createStore({ state, getters, actions, diff --git a/administrator/components/com_menus/presets/system.xml b/administrator/components/com_menus/presets/system.xml index c01a1623f3700..709075760be30 100644 --- a/administrator/components/com_menus/presets/system.xml +++ b/administrator/components/com_menus/presets/system.xml @@ -127,25 +127,25 @@ $published, + 'published' => $this->state->get('filter.published'), 'checkacl' => (int) $this->state->get('menutypeid'), 'clientid' => (int) $clientId, ); diff --git a/administrator/components/com_menus/tmpl/menus/default.php b/administrator/components/com_menus/tmpl/menus/default.php index 09d4e4a71bbce..beb0b25a04071 100644 --- a/administrator/components/com_menus/tmpl/menus/default.php +++ b/administrator/components/com_menus/tmpl/menus/default.php @@ -151,7 +151,7 @@ - - - - - - - diff --git a/administrator/components/com_workflow/tmpl/transition/edit.php b/administrator/components/com_workflow/tmpl/transition/edit.php index 89499552a610a..e3a43356d5151 100644 --- a/administrator/components/com_workflow/tmpl/transition/edit.php +++ b/administrator/components/com_workflow/tmpl/transition/edit.php @@ -31,7 +31,7 @@ ?> - +
diff --git a/administrator/language/en-GB/com_admin.ini b/administrator/language/en-GB/com_admin.ini index 82f3853637d7d..8c630a1a48a5d 100644 --- a/administrator/language/en-GB/com_admin.ini +++ b/administrator/language/en-GB/com_admin.ini @@ -137,25 +137,6 @@ COM_ADMIN_PHPINFO_DISABLED="The built in phpinfo() function has been disabled by COM_ADMIN_POST_MAX_SIZE="Post Max Size" COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_DESCRIPTION="

Before 3.9.22 the default htaccess.txt file contained erroneous code meant for disabling directory listings. The security team recommends to manually apply the necessary changes to any existing .htaccess file, as this file can not be updated automatically.

The old code:

<IfModule autoindex>\n  IndexIgnore *\n</IfModule>

The new code:

<IfModule mod_autoindex.c>\n  IndexIgnore *\n</IfModule>
" COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_TITLE=".htaccess Update Concerning Directory Listings" -COM_ADMIN_PROFILE_FIELD_BACKEND_LANGUAGE_LABEL="Backend Language" -COM_ADMIN_PROFILE_FIELD_BACKEND_TEMPLATE_LABEL="Backend Template Style" -COM_ADMIN_PROFILE_FIELD_EDITOR_LABEL="Editor" -COM_ADMIN_PROFILE_FIELD_FRONTEND_LANGUAGE_LABEL="Frontend Language" -COM_ADMIN_PROFILE_FIELD_LASTVISIT_LABEL="Last Visit Date" -COM_ADMIN_PROFILE_FIELD_NOCHANGE_USERNAME_DESC="If you want to change your Username, please contact a site administrator." -COM_ADMIN_PROFILE_FIELD_PASSWORD1_MESSAGE="The passwords you entered do not match. Please enter your desired password in the password field and confirm your entry by entering it in the confirm password field." -COM_ADMIN_PROFILE_FIELD_PASSWORD2_LABEL="Confirm Password" -COM_ADMIN_PROFILE_FIELD_REGISTERDATE_LABEL="Registration Date" -COM_ADMIN_PROFILE_FIELD_TIMEZONE_LABEL="Time Zone" -COM_ADMIN_PROFILE_FIELD_TWOFACTOR_LABEL="Authentication Method" -COM_ADMIN_PROFILE_FIELD_USERNAME_LABEL="Login Name" -COM_ADMIN_PROFILE_FIELDSET_SETTINGS_LABEL="Basic Settings" -COM_ADMIN_PROFILE_FIELDSET_USER_DETAILS_LABEL="My Profile Details" -COM_ADMIN_PROFILE_HEADING_NAME="Name" -COM_ADMIN_PROFILE_OTEPS="One time emergency passwords" -COM_ADMIN_PROFILE_OTEPS_DESC="If you do not have access to your two factor authentication device you can use any of the following passwords instead of a regular security code. Each one of these emergency passwords is immediately destroyed upon use. We recommend printing these passwords out and keeping the printout in a safe and accessible location, eg your wallet or a safety deposit box." -COM_ADMIN_PROFILE_OTEPS_WAIT_DESC="There are no emergency one time passwords generated in your account. The passwords will be generated automatically and displayed here as soon as you activate two factor authentication." -COM_ADMIN_PROFILE_TWO_FACTOR_AUTH="Two Factor Authentication" COM_ADMIN_SAVE_SUCCESS="Profile saved." COM_ADMIN_SESSION_AUTO_START="Session Auto Start" COM_ADMIN_SESSION_SAVE_PATH="Session Save Path" @@ -169,7 +150,6 @@ COM_ADMIN_UNWRITABLE="Unwritable" COM_ADMIN_UPLOAD_MAX_FILESIZE="Upload Max Filesize" COM_ADMIN_USER_AGENT="User Agent" COM_ADMIN_VALUE="Value" -COM_ADMIN_VIEW_PROFILE_TITLE="My Profile" COM_ADMIN_WEB_SERVER="Web Server" COM_ADMIN_WEBSERVER_TO_PHP_INTERFACE="WebServer to PHP Interface" COM_ADMIN_WRITABLE="Writable" diff --git a/administrator/language/en-GB/com_banners.ini b/administrator/language/en-GB/com_banners.ini index ac39a9b0e7197..6bdf18f9464be 100644 --- a/administrator/language/en-GB/com_banners.ini +++ b/administrator/language/en-GB/com_banners.ini @@ -185,7 +185,7 @@ COM_BANNERS_TRACKS_FILTER_SEARCH_DESC="Search in track name and track client nam COM_BANNERS_TRACKS_FILTER_SEARCH_LABEL="Search Tracks" COM_BANNERS_TRACKS_N_ITEMS_DELETED="%d tracks deleted." COM_BANNERS_TRACKS_N_ITEMS_DELETED_1="Track deleted." -COM_BANNERS_TRACKS_NO_ITEMS_DELETED="No Tracks to Delete." +COM_BANNERS_TRACKS_NO_ITEMS_DELETED="No tracks to delete." COM_BANNERS_TRACKS_TABLE_CAPTION="Table of Tracks" COM_BANNERS_TYPE1="Impressions" COM_BANNERS_TYPE2="Clicks" diff --git a/administrator/language/en-GB/com_config.ini b/administrator/language/en-GB/com_config.ini index 81bf14c4af751..cf03c677dcaca 100644 --- a/administrator/language/en-GB/com_config.ini +++ b/administrator/language/en-GB/com_config.ini @@ -187,7 +187,7 @@ COM_CONFIG_FIELD_WEBSERVICES_CORS_ALLOW_METHODS_DESC="Specifies the Web service COM_CONFIG_FIELD_WEBSERVICES_CORS_ALLOW_ORIGIN_DESC="Specifies the origin allowed to access Web services on this site, sent back in response to a preflight request. Default: * (=all)." COM_CONFIG_FIELDSET_TAGS_LABEL="Tags" COM_CONFIG_FILTER_OPTION_SELECT_EXTENSION="- Select Extension -" -COM_CONFIG_FRONTEDITING_LABEL="Inline Editing" +COM_CONFIG_FRONTEDITING_LABEL="Frontend Editing" COM_CONFIG_FRONTEDITING_MENUSANDMODULES="Modules & Menus" COM_CONFIG_FRONTEDITING_MODULES="Modules" COM_CONFIG_FTP_DETAILS="FTP Login Details" diff --git a/administrator/language/en-GB/com_contact.sys.ini b/administrator/language/en-GB/com_contact.sys.ini index 16dcf4e4759f4..0b7c53be1659b 100644 --- a/administrator/language/en-GB/com_contact.sys.ini +++ b/administrator/language/en-GB/com_contact.sys.ini @@ -5,9 +5,9 @@ COM_CONTACT="Contacts" COM_CONTACT_CATEGORIES="Categories" -COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of contact categories within a category." +COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of categories within a contact category tree." COM_CONTACT_CATEGORIES_VIEW_DEFAULT_OPTION="Default" -COM_CONTACT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Contact Categories" +COM_CONTACT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories in a Contact Category Tree" COM_CONTACT_CATEGORY_VIEW_DEFAULT_DESC="This view lists the contacts in a category." COM_CONTACT_CATEGORY_VIEW_DEFAULT_OPTION="Default" COM_CONTACT_CATEGORY_VIEW_DEFAULT_TITLE="List Contacts in a Category" @@ -22,6 +22,7 @@ COM_CONTACT_FEATURED_VIEW_DEFAULT_OPTION="Default" COM_CONTACT_FEATURED_VIEW_DEFAULT_TITLE="Featured Contacts" COM_CONTACT_FORM_VIEW_DEFAULT_DESC="Create a new contact." COM_CONTACT_FORM_VIEW_DEFAULT_TITLE="Create Contact" +COM_CONTACT_NO_CONTACTS_LABEL="No Contacts Message" COM_CONTACT_TAGS_CATEGORY="Contact Category" COM_CONTACT_TAGS_CONTACT="Contact" COM_CONTACT_XML_DESCRIPTION="This component shows a listing of Contact Information." diff --git a/administrator/language/en-GB/com_content.sys.ini b/administrator/language/en-GB/com_content.sys.ini index c4b3ff825869b..171185ab24a91 100644 --- a/administrator/language/en-GB/com_content.sys.ini +++ b/administrator/language/en-GB/com_content.sys.ini @@ -17,9 +17,9 @@ COM_CONTENT_ARTICLES="Articles" COM_CONTENT_ARTICLES_VIEW_DEFAULT_DESC="Shows a list of all the articles." COM_CONTENT_ARTICLES_VIEW_DEFAULT_TITLE="List All Articles" COM_CONTENT_CATEGORIES="Categories" -COM_CONTENT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of all the article categories within a category." +COM_CONTENT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of all categories in the selected article category tree." COM_CONTENT_CATEGORIES_VIEW_DEFAULT_OPTION="Default" -COM_CONTENT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories" +COM_CONTENT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories in an Article Category Tree" COM_CONTENT_CATEGORY_VIEW_BLOG_DESC="Displays article introductions in a single or multi-column layout." COM_CONTENT_CATEGORY_VIEW_BLOG_OPTION="Blog" COM_CONTENT_CATEGORY_VIEW_BLOG_TITLE="Category Blog" diff --git a/administrator/language/en-GB/com_cpanel.ini b/administrator/language/en-GB/com_cpanel.ini index 7b32132e63c0d..3e74b8cfa25e4 100644 --- a/administrator/language/en-GB/com_cpanel.ini +++ b/administrator/language/en-GB/com_cpanel.ini @@ -18,11 +18,9 @@ COM_CPANEL_MESSAGES_TITLE="You have post-installation messages" ; Translators: Don't touch the code part in the following message, Starting with ## Mod_rewrite ... COM_CPANEL_MSG_ADDNOSNIFF_BODY="

Joomla is now shipped with additional security hardenings in the default htaccess.txt and web.config.txt files. These hardenings disable the so called MIME-type sniffing feature in web browsers. The sniffing leads to specific attack vectors, where scripts in normally harmless file formats (eg images) will be executed, leading to Cross-Site-Scripting vulnerabilities.

The security team recommends to manually apply the necessary changes to existing .htaccess or web.config files, as those files can not be updated automatically.

Changes for .htaccess
Add the following lines before \"## Mod_rewrite in use.\":

<IfModule mod_headers.c>\nHeader always set X-Content-Type-Options \"nosniff\"\n</IfModule>

Changes for web.config
Add the following lines right after \"</rewrite>\":

<httpProtocol>\n  <customHeaders>\n    <add name=\"X-Content-Type-Options\" value=\"nosniff\" />\n  </customHeaders>\n</httpProtocol>
" COM_CPANEL_MSG_ADDNOSNIFF_TITLE=".htaccess & web.config Security Update" -COM_CPANEL_MSG_HTACCESS_BODY="A change to the default .htaccess and web.config files was made in Joomla! 3.4 to disallow folder listings by default. Users are recommended to implement this change in their files. Please see this page for more information." -COM_CPANEL_MSG_HTACCESS_TITLE=".htaccess & web.config Update" -COM_CPANEL_MSG_LANGUAGEACCESS340_BODY="Since Joomla! 3.4.0 you may have issues with the System - Language Filter plugin on your website. To fix them please open the Language Manager and save each content language manually to make sure an Access level is saved." -COM_CPANEL_MSG_HTACCESSSVG_TITLE="Additional XSS protection for the usage of SVG files" COM_CPANEL_MSG_HTACCESSSVG_BODY="

Since 3.9.21 Joomla is shipped with an additional security rule in the default htaccess.txt. This rule will protect users of svg files from potential Cross-Site-Scripting (XSS) vulnerabilities.
The security team recommends to manually apply the necessary changes to any existing .htaccess file, as this file can not be updated automatically.

Changes for .htaccess

<FilesMatch \"\.svg$\">\n  <IfModule mod_headers.c>\n    Header always set Content-Security-Policy \"script-src 'none'\"\n  </IfModule>\n</FilesMatch>

Currently we are not aware of a method to conditionally configure this on IIS web servers, please contact your hosting provider for further assistance.

" +COM_CPANEL_MSG_HTACCESSSVG_TITLE="Additional XSS protection for the usage of SVG files" +COM_CPANEL_MSG_LANGUAGEACCESS340_BODY="Since Joomla! 3.4.0 you may have issues with the System - Language Filter plugin on your website. To fix them please open the Language Manager and save each content language manually to make sure an Access level is saved." COM_CPANEL_MSG_LANGUAGEACCESS340_TITLE="You have possible issues with your multilingual settings" COM_CPANEL_MSG_ROBOTS_BODY="A change to the default robots.txt files was made in Joomla! 3.3 to allow Google to access templates and media files by default to improve SEO. This change is not applied automatically on upgrades and users are recommended to review the changes in the robots.txt.dist file and implement these changes in their own robots.txt file." COM_CPANEL_MSG_ROBOTS_TITLE="robots.txt Update" @@ -30,8 +28,6 @@ COM_CPANEL_MSG_STATS_COLLECTION_BODY="

Since Joomla! 3.5 a statistics plugin w COM_CPANEL_MSG_STATS_COLLECTION_TITLE="Stats Collection in Joomla" COM_CPANEL_MSG_TEXTFILTER3919_BODY="

As part of our security team's review, we have made some changes to the default settings for the global text filters in a new Joomla installation. The default setting for the 'Public', 'Guest' and 'Registered' groups is now 'No HTML'. As these changes are only applied to new installations, we strongly recommend that you review these changes and update your site from: System -> Global Configuration -> Text Filters

" COM_CPANEL_MSG_TEXTFILTER3919_TITLE="Updated Text Filter Recommendations" -COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_BODY="

As part of our security team's review, we have made some changes to the default settings in a new Joomla installation. As these changes are only applied to new installations, we strongly recommend that you review these changes and update your site.

The changed settings are:

  • Global Configuration > Text Filters: The default \"Administrator\" user group has changed from \"No Filtering\" to \"Default Forbidden List\"
  • Users > Send Password: The option to send a user their password in plain text when an account is created is now disabled by default
  • Media Manager: Flash files (\"swf\" file extension and \"application/x-shockwave-flash\" MIME Type) are not allowed to be uploaded
  • Articles > Show Email: The option to show an email icon with articles is disabled by default

We have created a dedicated documentation page explaining these changes.

" -COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE="Updated site security recommendations" COM_CPANEL_TITLE_SYSTEM_PANEL="System Panel" COM_CPANEL_UNPUBLISH_MODULE_ERROR="Error unpublishing the module" COM_CPANEL_UNPUBLISH_MODULE_SUCCESS="Module unpublished" diff --git a/administrator/language/en-GB/com_fields.ini b/administrator/language/en-GB/com_fields.ini index 02154b4654b20..d48be8210722c 100644 --- a/administrator/language/en-GB/com_fields.ini +++ b/administrator/language/en-GB/com_fields.ini @@ -60,6 +60,7 @@ COM_FIELDS_FIELD_SUFFIX_LABEL="Suffix" COM_FIELDS_FIELD_TYPE_LABEL="Type" COM_FIELDS_FIELD_USE_GLOBAL="Use settings from Plugin" COM_FIELDS_FIELDS_FILTER_SEARCH_DESC="Search in field name, title or note. Prefix with ID: to search for a field ID. Prefix with AUTHOR: to search for a field author." +COM_FIELDS_FIELDS_FILTER_SEARCH_LABEL="Search Fields" COM_FIELDS_FIELDS_TABLE_CAPTION="Table of Fields" COM_FIELDS_GROUP_FORM_EDIT="Edit Field Group" COM_FIELDS_GROUP_FORM_NEW="New Field Group" @@ -77,6 +78,7 @@ COM_FIELDS_GROUP_N_ITEMS_UNPUBLISHED="%d field groups unpublished" COM_FIELDS_GROUP_N_ITEMS_UNPUBLISHED_1="Field group unpublished" COM_FIELDS_GROUP_SAVE_SUCCESS="Field Group saved" COM_FIELDS_GROUPS_FILTER_SEARCH_DESC="Search in field group title. Prefix with ID: to search for a field group ID." +COM_FIELDS_GROUPS_FILTER_SEARCH_LABEL="Search Field Groups" COM_FIELDS_GROUPS_TABLE_CAPTION="Table of Field Groups" COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD="Field must have a title." COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP="Field Group must have a title." diff --git a/administrator/language/en-GB/com_installer.ini b/administrator/language/en-GB/com_installer.ini index 6b0e15a64e260..c93d05a54f3c8 100644 --- a/administrator/language/en-GB/com_installer.ini +++ b/administrator/language/en-GB/com_installer.ini @@ -71,6 +71,7 @@ COM_INSTALLER_HEADING_PACKAGE_ID="Package ID" COM_INSTALLER_HEADING_PACKAGE_ID_ASC="Package ID ascending" COM_INSTALLER_HEADING_PACKAGE_ID_DESC="Package ID descending" COM_INSTALLER_HEADING_PROBLEMS="Problems" +COM_INSTALLER_HEADING_SUPPORTED="Download Key" COM_INSTALLER_HEADING_TYPE="Type" COM_INSTALLER_HEADING_TYPE_ASC="Type ascending" COM_INSTALLER_HEADING_TYPE_DESC="Type descending" diff --git a/administrator/language/en-GB/com_newsfeeds.sys.ini b/administrator/language/en-GB/com_newsfeeds.sys.ini index 13a0866466c55..a0d9b0c197b3e 100644 --- a/administrator/language/en-GB/com_newsfeeds.sys.ini +++ b/administrator/language/en-GB/com_newsfeeds.sys.ini @@ -5,9 +5,9 @@ COM_NEWSFEEDS="News Feeds" COM_NEWSFEEDS_CATEGORIES="Categories" -COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_DESC="Show all the news feed categories within a category." +COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of all categories in the selected news feed category tree." COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_OPTION="Default" -COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_TITLE="List All News Feed Categories" +COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories in a News Feed Category Tree" COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_DESC="Show all news feeds within a category." COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_OPTION="Default" COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_TITLE="List News Feeds in a Category" diff --git a/administrator/language/en-GB/com_users.ini b/administrator/language/en-GB/com_users.ini index 9a9299c20a957..8ab8a3e429368 100644 --- a/administrator/language/en-GB/com_users.ini +++ b/administrator/language/en-GB/com_users.ini @@ -12,6 +12,7 @@ COM_USERS_A11Y_SETTINGS_FIELD_MONOCHROME="Monochrome" COM_USERS_ACTIVATED="Activated" COM_USERS_ADD_NOTE="Add a Note" COM_USERS_ASSIGNED_GROUPS="Assigned User Groups" +COM_USERS_BATCH_ACTIONS="Select Action" COM_USERS_BATCH_ADD="Add To Group" COM_USERS_BATCH_DELETE="Delete From Group" COM_USERS_BATCH_GROUP="Select Group" @@ -90,12 +91,14 @@ COM_USERS_FIELD_IMAGE_ALT_EMPTY_DESC="Decorative Image - no description required COM_USERS_FIELD_IMAGE_ALT_EMPTY_LABEL="No Description" COM_USERS_FIELD_IMAGE_ALT_LABEL="Image Description (Alt Text)" COM_USERS_FIELD_LOGIN_MENUITEM="Menu Item" +COM_USERS_FIELD_LOGIN_REDIRECTMENU_DESC="If no menu item is selected, users will be redirected to the their profile after login." COM_USERS_FIELD_LOGIN_REDIRECTMENU_LABEL="Menu Item Login Redirect" COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_DESC="'Internal URL' lets you manually enter any internal URL in the Redirect field. 'Menu Item' lets you directly select an existing menu item.
For a multilingual site, it is recommended to use 'Menu Item'." COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_LABEL="Choose Login Redirect Type" COM_USERS_FIELD_LOGIN_REDIRECT_ERROR="Only one of the login redirect fields should have a value." COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER="index.php?Itemid=999&lang=en-GB" COM_USERS_FIELD_LOGIN_URL="Internal URL" +COM_USERS_FIELD_LOGOUT_REDIRECTMENU_DESC="If no menu item is selected, users will be redirected to the homepage after logout." COM_USERS_FIELD_LOGOUT_REDIRECTMENU_LABEL="Menu Item Logout Redirect" COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_DESC="'Internal URL' lets you manually enter any internal URL in the Redirect field. 'Menu Item' lets you directly select an existing menu item.
For a multilingual site, it is recommended to use 'Menu Item'." COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_LABEL="Choose Logout Redirect Type" @@ -336,6 +339,7 @@ COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL="Frontend Language" COM_USERS_USER_FIELD_LASTRESET_LABEL="Last Reset Date" COM_USERS_USER_FIELD_LASTVISIT_LABEL="Last Visit Date" COM_USERS_USER_FIELD_NAME_LABEL="Name" +COM_USERS_USER_FIELD_NOCHANGE_USERNAME_DESC="If you want to change your Username, please contact a site administrator." COM_USERS_USER_FIELD_PASSWORD1_MESSAGE="The passwords you entered do not match. Please enter your desired password in the password field and confirm your entry by entering it in the confirm password field." COM_USERS_USER_FIELD_PASSWORD2_LABEL="Confirm Password" COM_USERS_USER_FIELD_REGISTERDATE_LABEL="Registration Date" diff --git a/administrator/language/en-GB/com_wrapper.ini b/administrator/language/en-GB/com_wrapper.ini index d509695634135..a7b374ce082f8 100644 --- a/administrator/language/en-GB/com_wrapper.ini +++ b/administrator/language/en-GB/com_wrapper.ini @@ -6,11 +6,9 @@ COM_WRAPPER="Wrapper" COM_WRAPPER_FIELD_ADD_DESC="By default, http:// will be added unless it detects http:// or https:// in the URL you provide. This allows you to switch off this functionality." COM_WRAPPER_FIELD_ADD_LABEL="Auto Add" -COM_WRAPPER_FIELD_FRAME_LABEL="Frame Border" COM_WRAPPER_FIELD_HEIGHT_LABEL="Height" COM_WRAPPER_FIELD_HEIGHTAUTO_LABEL="Auto Height" COM_WRAPPER_FIELD_LABEL_SCROLLBARSPARAMS="Scroll Bar Parameters" -COM_WRAPPER_FIELD_SCROLLBARS_LABEL="Scroll Bars" +COM_WRAPPER_FIELD_LAZYLOADING_LABEL="Lazy Loading" COM_WRAPPER_FIELD_URL_LABEL="URL" -COM_WRAPPER_FIELD_VALUE_AUTO="Auto" COM_WRAPPER_XML_DESCRIPTION="Displays an iframe to wrap an external page or site into Joomla!" diff --git a/administrator/language/en-GB/joomla.ini b/administrator/language/en-GB/joomla.ini index f7cddb5954177..6af1dab6e81e2 100644 --- a/administrator/language/en-GB/joomla.ini +++ b/administrator/language/en-GB/joomla.ini @@ -278,8 +278,6 @@ JFIELD_PASSWORD_NOT_ENOUGH_SYMBOLS_N="Password does not have enough symbols (suc JFIELD_PASSWORD_NOT_ENOUGH_SYMBOLS_N_1="Password does not have enough symbols (such as !@#$). At least 1 symbol is required." JFIELD_PASSWORD_NOT_ENOUGH_UPPERCASE_LETTERS_N="Password does not have enough upper case characters. At least %s upper case characters are required." JFIELD_PASSWORD_NOT_ENOUGH_UPPERCASE_LETTERS_N_1="Password does not have enough upper case characters. At least 1 upper case character is required." -JFIELD_PASSWORD_NOTE_DESC="%1 symbol(s), %2 uppercase letter(s), %3 lowercase letter(s), %4 number(s)" -JFIELD_PASSWORD_NOTE_LBL="Password must contain:" JFIELD_PASSWORD_RULES_CHARACTERS="Characters: %d" JFIELD_PASSWORD_RULES_DIGITS="Numbers: %d" JFIELD_PASSWORD_RULES_LOWERCASE="Lower Case: %d" @@ -401,8 +399,7 @@ JGLOBAL_FEED_SUMMARY_DESC="If set to Intro Text, only the Intro Text of each art JGLOBAL_FEED_SUMMARY_LABEL="Include in Feed" JGLOBAL_FEED_TITLE="News Feeds" JGLOBAL_FIELD_ADD="Add" -JGLOBAL_FIELD_CATEGORIES_CHOOSE_CATEGORY_DESC="Categories that are within this category will be displayed." -JGLOBAL_FIELD_CATEGORIES_CHOOSE_CATEGORY_LABEL="Select a Top Level Category" +JGLOBAL_FIELD_CATEGORIES_CHOOSE_CATEGORY_LABEL="Select the Top Level Category" JGLOBAL_FIELD_CATEGORIES_DESC_DESC="If you enter some text in this field, it will replace the Top Level Category Description, if it has one." JGLOBAL_FIELD_CATEGORIES_DESC_LABEL="Alternative Description" JGLOBAL_FIELD_CREATED_BY_ALIAS_DESC="Uses another name than the author's for display." @@ -430,7 +427,7 @@ JGLOBAL_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" JGLOBAL_FIELD_PUBLISH_UP_DESC="An optional date to start publishing." JGLOBAL_FIELD_PUBLISH_UP_LABEL="Start Publishing" JGLOBAL_FIELD_REMOVE="Remove" -JGLOBAL_FIELD_SHOW_BASE_DESCRIPTION_DESC="Show description of the top level category or alternatively replace with the text from the description field found in the menu item. If using Root as a top level category, the description field has to be filled." +JGLOBAL_FIELD_SHOW_BASE_DESCRIPTION_DESC="Show description of the top level category or alternatively replace with the text from the description field found in the menu item. If using Root as the Top Level category, the description field has to be filled." JGLOBAL_FIELD_SHOW_BASE_DESCRIPTION_LABEL="Top Level Category Description" JGLOBAL_FIELD_VERSION_NOTE_DESC="Enter an optional note for this version of the item." JGLOBAL_FIELD_VERSION_NOTE_LABEL="Version Note" diff --git a/administrator/language/en-GB/plg_actionlog_joomla.ini b/administrator/language/en-GB/plg_actionlog_joomla.ini index cd0085a828b16..18a905d74f71e 100644 --- a/administrator/language/en-GB/plg_actionlog_joomla.ini +++ b/administrator/language/en-GB/plg_actionlog_joomla.ini @@ -44,7 +44,7 @@ PLG_ACTIONLOG_JOOMLA_USER_LOG="User {username} purge PLG_ACTIONLOG_JOOMLA_USER_LOGEXPORT="User {username} exported one or more rows from the action log" PLG_ACTIONLOG_JOOMLA_USER_LOGGED_IN="User {username} logged in to {app}" PLG_ACTIONLOG_JOOMLA_USER_LOGGED_OUT="User {username} logged out from {app}" -PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED="User {username} tried to login to {app}" +PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED="A failed attempt was made to login as {username} to {app}" PLG_ACTIONLOG_JOOMLA_USER_REGISTRATION_ACTIVATE="User {username} activated the account" PLG_ACTIONLOG_JOOMLA_USER_REGISTERED="User {username} registered for an account" PLG_ACTIONLOG_JOOMLA_USER_REMIND="User {username} requested a username reminder for their account" diff --git a/administrator/language/en-GB/plg_sampledata_blog.ini b/administrator/language/en-GB/plg_sampledata_blog.ini index 414fd4e737a4e..c2a50a798124e 100644 --- a/administrator/language/en-GB/plg_sampledata_blog.ini +++ b/administrator/language/en-GB/plg_sampledata_blog.ini @@ -57,7 +57,7 @@ PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE2_DESCRIPTION="Copywriter i PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE2_TITLE="Copywriting" PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE3_DESCRIPTION="Graphic Designer is at work." PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE3_TITLE="Graphic Design" -PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE4_DESCRIPTION="Graphic Designer is at work." +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE4_DESCRIPTION="Fact Checker is at work." PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE4_TITLE="Fact Check" PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE5_DESCRIPTION="The article is reviewed, checked for text, illustration, HTML." PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_WORKFLOW_STAGE5_TITLE="Content Review" diff --git a/administrator/language/en-GB/plg_system_privacyconsent.ini b/administrator/language/en-GB/plg_system_privacyconsent.ini index 882ff0e87ea68..a13c371f60bb1 100644 --- a/administrator/language/en-GB/plg_system_privacyconsent.ini +++ b/administrator/language/en-GB/plg_system_privacyconsent.ini @@ -5,7 +5,7 @@ PLG_SYSTEM_PRIVACYCONSENT="System - Privacy Consent" PLG_SYSTEM_PRIVACYCONSENT_BODY="

The user consented to storing their user information using the IP address %s

The user agent string of the user's browser was:
%s

This information was automatically recorded when the user submitted their details on the website and checked the confirm box

" -PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_DESC="How often the check is performed" +PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_DESC="How often the check is performed." PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_LABEL="Periodic check (days)" PLG_SYSTEM_PRIVACYCONSENT_CONSENT="User {username} consented to the privacy policy." PLG_SYSTEM_PRIVACYCONSENT_CONSENTEXPIRATION_DESC="Number of days after which the privacy consent shall expire." @@ -15,8 +15,8 @@ PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_SUBJECT="Privacy Consent at {SITENAME}" PLG_SYSTEM_PRIVACYCONSENT_EXPIRATION_FIELDSET_LABEL="Expiration" PLG_SYSTEM_PRIVACYCONSENT_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." PLG_SYSTEM_PRIVACYCONSENT_FIELD_ARTICLE_LABEL="Privacy Article" -PLG_SYSTEM_PRIVACYCONSENT_FIELD_DESC="Read the full privacy policy" -PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_DESC="When enabled it performs checks for consent expiration" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_DESC="Read the full privacy policy." +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_DESC="When enabled it performs checks for consent expiration." PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_LABEL="Enable" PLG_SYSTEM_PRIVACYCONSENT_FIELD_ERROR="Agreement to the site's Privacy Policy is required." PLG_SYSTEM_PRIVACYCONSENT_FIELD_LABEL="Privacy Policy" diff --git a/administrator/language/en-GB/plg_system_skipto.ini b/administrator/language/en-GB/plg_system_skipto.ini index fed6455a1fecb..a94b17f78cf5e 100644 --- a/administrator/language/en-GB/plg_system_skipto.ini +++ b/administrator/language/en-GB/plg_system_skipto.ini @@ -4,7 +4,8 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SYSTEM_SKIPTO="System - Skip-To Navigation" -PLG_SYSTEM_SKIPTO_ACCESS_KEY_NOT_SUPPORTED="The use of Access keys is not supported on this browser." +; do not translate $key +PLG_SYSTEM_SKIPTO_ACCESS_KEY="Access key is $key" PLG_SYSTEM_SKIPTO_HEADING="Page Outline" PLG_SYSTEM_SKIPTO_HEADING_LEVEL="Heading level" ; next line begins with a space. $m is count, %n is total @@ -25,8 +26,5 @@ PLG_SYSTEM_SKIPTO_SECTION="Site Section" PLG_SYSTEM_SKIPTO_SECTION_ADMIN="Administrator (Backend)" PLG_SYSTEM_SKIPTO_SECTION_BOTH="Both" PLG_SYSTEM_SKIPTO_SECTION_SITE="Site (Frontend)" -PLG_SYSTEM_SKIPTO_SKIP_TO="Skip To" PLG_SYSTEM_SKIPTO_TITLE="Keyboard Navigation" -; do not translate $key -PLG_SYSTEM_SKIPTO_TITLE_WITH_ACCCESS_KEY="Keyboard Navigation - Access key is $key" PLG_SYSTEM_SKIPTO_XML_DESCRIPTION="The plugin creates a dropdown menu consisting of the links to the important places on a given web page. This makes it easier for keyboard and screen reader users to quickly jump to the desired location by choosing it from the list of options." diff --git a/administrator/modules/mod_latestactions/tmpl/default.php b/administrator/modules/mod_latestactions/tmpl/default.php index 5c858f943e9aa..532eb228b2d29 100644 --- a/administrator/modules/mod_latestactions/tmpl/default.php +++ b/administrator/modules/mod_latestactions/tmpl/default.php @@ -29,7 +29,7 @@ message; ?>
diff --git a/administrator/modules/mod_menu/tmpl/default_submenu.php b/administrator/modules/mod_menu/tmpl/default_submenu.php index 6da1885f3a7f4..d2cfd98caf4a1 100644 --- a/administrator/modules/mod_menu/tmpl/default_submenu.php +++ b/administrator/modules/mod_menu/tmpl/default_submenu.php @@ -73,7 +73,7 @@ if ($current->level > 2) { - $dataToggle = ' data-bs-toggle="dropdown"'; + $dataToggle = ' data-bs-toggle="dropdown"'; } } else diff --git a/administrator/modules/mod_quickicon/services/provider.php b/administrator/modules/mod_quickicon/services/provider.php index 19af2e87b4ad9..86c396968362b 100644 --- a/administrator/modules/mod_quickicon/services/provider.php +++ b/administrator/modules/mod_quickicon/services/provider.php @@ -9,6 +9,7 @@ defined('_JEXEC') or die; +use Joomla\CMS\Extension\Service\Provider\HelperFactory; use Joomla\CMS\Extension\Service\Provider\Module; use Joomla\CMS\Extension\Service\Provider\ModuleDispatcherFactory; use Joomla\DI\Container; @@ -33,6 +34,7 @@ public function register(Container $container) { $container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Quickicon')); + $container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Quickicon\\Administrator\\Helper')); $container->registerServiceProvider(new Module); } diff --git a/administrator/modules/mod_quickicon/src/Dispatcher/Dispatcher.php b/administrator/modules/mod_quickicon/src/Dispatcher/Dispatcher.php index 60fd120ac8ae6..600e8f692c574 100644 --- a/administrator/modules/mod_quickicon/src/Dispatcher/Dispatcher.php +++ b/administrator/modules/mod_quickicon/src/Dispatcher/Dispatcher.php @@ -32,7 +32,8 @@ protected function getLayoutData() { $data = parent::getLayoutData(); - $data['buttons'] = QuickIconHelper::getButtons($data['params'], $this->getApplication()); + $helper = $this->app->bootModule('mod_quickicon', 'administrator')->getHelper('QuickIconHelper'); + $data['buttons'] = $helper->getButtons($data['params'], $this->getApplication()); return $data; } diff --git a/administrator/modules/mod_quickicon/src/Helper/QuickIconHelper.php b/administrator/modules/mod_quickicon/src/Helper/QuickIconHelper.php index 652ef12500176..1e2500c759323 100644 --- a/administrator/modules/mod_quickicon/src/Helper/QuickIconHelper.php +++ b/administrator/modules/mod_quickicon/src/Helper/QuickIconHelper.php @@ -23,7 +23,7 @@ * * @since 1.6 */ -abstract class QuickIconHelper +class QuickIconHelper { /** * Stack to hold buttons @@ -31,7 +31,7 @@ abstract class QuickIconHelper * @var array[] * @since 1.6 */ - protected static $buttons = array(); + protected $buttons = array(); /** * Helper method to return button list. @@ -46,7 +46,7 @@ abstract class QuickIconHelper * * @since 1.6 */ - public static function &getButtons(Registry $params, CMSApplication $application = null) + public function getButtons(Registry $params, CMSApplication $application = null) { if ($application == null) { @@ -56,12 +56,12 @@ public static function &getButtons(Registry $params, CMSApplication $application $key = (string) $params; $context = (string) $params->get('context', 'mod_quickicon'); - if (!isset(self::$buttons[$key])) + if (!isset($this->buttons[$key])) { // Load mod_quickicon language file in case this method is called before rendering the module $application->getLanguage()->load('mod_quickicon'); - self::$buttons[$key] = []; + $this->buttons[$key] = []; if ($params->get('show_users')) { @@ -79,7 +79,7 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_users&task=users.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_menuitems')) @@ -98,7 +98,7 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_menus&task=items.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_articles')) @@ -117,7 +117,7 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_content&task=articles.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_categories')) @@ -136,12 +136,12 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_categories&task=categories.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_media')) { - self::$buttons[$key][] = [ + $this->buttons[$key][] = [ 'image' => 'icon-images', 'link' => Route::_('index.php?option=com_media'), 'name' => 'MOD_QUICKICON_MEDIA_MANAGER', @@ -166,7 +166,7 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_modules&task=modules.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_plugins')) @@ -184,12 +184,12 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_plugins&task=plugins.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_template_styles')) { - self::$buttons[$key][] = [ + $this->buttons[$key][] = [ 'image' => 'icon-paint-brush', 'link' => Route::_('index.php?option=com_templates&view=styles&client_id=0'), 'name' => 'MOD_QUICKICON_TEMPLATE_STYLES', @@ -200,7 +200,7 @@ public static function &getButtons(Registry $params, CMSApplication $application if ($params->get('show_template_code')) { - self::$buttons[$key][] = [ + $this->buttons[$key][] = [ 'image' => 'icon-code', 'link' => Route::_('index.php?option=com_templates&view=templates&client_id=0'), 'name' => 'MOD_QUICKICON_TEMPLATE_CODE', @@ -224,7 +224,7 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_checkin&task=getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_cache')) @@ -242,12 +242,12 @@ public static function &getButtons(Registry $params, CMSApplication $application $tmp['ajaxurl'] = 'index.php?option=com_cache&task=display.getQuickiconContent&format=json'; } - self::$buttons[$key][] = $tmp; + $this->buttons[$key][] = $tmp; } if ($params->get('show_global')) { - self::$buttons[$key][] = [ + $this->buttons[$key][] = [ 'image' => 'icon-cog', 'link' => Route::_('index.php?option=com_config'), 'name' => 'MOD_QUICKICON_GLOBAL_CONFIGURATION', @@ -287,12 +287,12 @@ public static function &getButtons(Registry $params, CMSApplication $application if (!\is_null($icon['link']) && !\is_null($icon['text'])) { - self::$buttons[$key][] = $icon; + $this->buttons[$key][] = $icon; } } } } - return self::$buttons[$key]; + return $this->buttons[$key]; } } diff --git a/administrator/modules/mod_submenu/src/Menu/Menu.php b/administrator/modules/mod_submenu/src/Menu/Menu.php index c9fdecc3363d4..f8c002a4c9efa 100644 --- a/administrator/modules/mod_submenu/src/Menu/Menu.php +++ b/administrator/modules/mod_submenu/src/Menu/Menu.php @@ -51,6 +51,12 @@ public static function preprocess($parent) foreach ($children as $item) { + if ($item->element && !ComponentHelper::isEnabled($item->element)) + { + $parent->removeChild($item); + continue; + } + $itemParams = $item->getParams(); // Exclude item with menu item option set to exclude from menu modules diff --git a/administrator/modules/mod_user/tmpl/default.php b/administrator/modules/mod_user/tmpl/default.php index 55c65ea1447d7..b850bbeb6ad17 100644 --- a/administrator/modules/mod_user/tmpl/default.php +++ b/administrator/modules/mod_user/tmpl/default.php @@ -21,7 +21,7 @@ $hideLinks = $app->input->getBool('hidemainmenu'); ?> diff --git a/administrator/templates/atum/html/layouts/chromes/body.php b/administrator/templates/atum/html/layouts/chromes/body.php index 4506d48b34b47..58767ae365df6 100644 --- a/administrator/templates/atum/html/layouts/chromes/body.php +++ b/administrator/templates/atum/html/layouts/chromes/body.php @@ -45,7 +45,7 @@ isRTL() ? 'start' : 'end'; ?> -
, , @@ -81,8 +81,10 @@ foreach ($this->items as $i => $item) : ?>
- + + + + escape($item->title); ?> diff --git a/administrator/components/com_finder/src/Model/IndexModel.php b/administrator/components/com_finder/src/Model/IndexModel.php index 6244106c60be8..7628988331b1f 100644 --- a/administrator/components/com_finder/src/Model/IndexModel.php +++ b/administrator/components/com_finder/src/Model/IndexModel.php @@ -327,8 +327,6 @@ public function getTotalIndexed() ->from($db->quoteName('#__finder_links')); $db->setQuery($query); - $db->execute(); - return (int) $db->loadResult(); } diff --git a/administrator/components/com_installer/forms/filter_updatesites.xml b/administrator/components/com_installer/forms/filter_updatesites.xml index f3f10f16b51e3..b468579c6b833 100644 --- a/administrator/components/com_installer/forms/filter_updatesites.xml +++ b/administrator/components/com_installer/forms/filter_updatesites.xml @@ -47,9 +47,10 @@ + > diff --git a/administrator/components/com_installer/src/Model/UpdateModel.php b/administrator/components/com_installer/src/Model/UpdateModel.php index 4b7ad7ef4cdda..1b55b89637aa3 100644 --- a/administrator/components/com_installer/src/Model/UpdateModel.php +++ b/administrator/components/com_installer/src/Model/UpdateModel.php @@ -352,7 +352,13 @@ public function update($uids, $minimumStability = Updater::STABILITY_STABLE) { $update = new Update; $instance = new \Joomla\CMS\Table\Update($this->getDbo()); - $instance->load($uid); + + if (!$instance->load($uid)) + { + // Update no longer available, maybe already updated by a package. + continue; + } + $update->loadFromXml($instance->detailsurl, $minimumStability); $update->set('extra_query', $instance->extra_query); diff --git a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php index 0d0a452c62aaa..069fa12285f15 100644 --- a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php +++ b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php @@ -19,6 +19,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\File; use Joomla\CMS\Filesystem\Path; +use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Http\Http; use Joomla\CMS\Http\HttpFactory; use Joomla\CMS\Installer\Installer; @@ -338,7 +339,13 @@ public function download() } // Find the path to the temp directory and the local package. - $tempdir = Factory::getApplication()->get('tmp_path'); + $tempdir = (string) InputFilter::getInstance( + [], + [], + InputFilter::ONLY_BLOCK_DEFINED_TAGS, + InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES + ) + ->clean(Factory::getApplication()->get('tmp_path'), 'path'); $target = $tempdir . '/' . $basename; $response = []; diff --git a/administrator/components/com_languages/forms/filter_overrides.xml b/administrator/components/com_languages/forms/filter_overrides.xml index eeb5c68cefc31..f452039b4cc82 100644 --- a/administrator/components/com_languages/forms/filter_overrides.xml +++ b/administrator/components/com_languages/forms/filter_overrides.xml @@ -7,7 +7,7 @@ onchange="this.form.submit();" filtermode="selector" addfieldprefix="Joomla\Component\Languages\Administrator\Field" - > + > diff --git a/administrator/components/com_login/src/Controller/DisplayController.php b/administrator/components/com_login/src/Controller/DisplayController.php index 6bfb271180718..db93e6ebdb584 100644 --- a/administrator/components/com_login/src/Controller/DisplayController.php +++ b/administrator/components/com_login/src/Controller/DisplayController.php @@ -77,26 +77,16 @@ public function login() $credentials = $model->getState('credentials'); $return = $model->getState('return'); - $result = $app->login($credentials, array('action' => 'core.login.admin')); + $app->login($credentials, array('action' => 'core.login.admin')); - if ($result && !($result instanceof \Exception)) + if (Uri::isInternal($return) && strpos($return, 'tmpl=component') === false) { - // Only redirect to an internal URL. - if (Uri::isInternal($return)) - { - // If &tmpl=component - redirect to index.php - if (strpos($return, 'tmpl=component') === false) - { - $app->redirect($return); - } - else - { - $app->redirect('index.php'); - } - } + $app->redirect($return); + } + else + { + $app->redirect('index.php'); } - - $this->display(); } /** diff --git a/administrator/components/com_mails/forms/filter_templates.xml b/administrator/components/com_mails/forms/filter_templates.xml index 429ee29cc8ed2..62fdd17cb117c 100644 --- a/administrator/components/com_mails/forms/filter_templates.xml +++ b/administrator/components/com_mails/forms/filter_templates.xml @@ -17,7 +17,6 @@ onchange="this.form.submit();" > - - - - - - + diff --git a/administrator/components/com_mails/src/Controller/DisplayController.php b/administrator/components/com_mails/src/Controller/DisplayController.php index 7e6ef1ee2b1f5..db491c778838b 100644 --- a/administrator/components/com_mails/src/Controller/DisplayController.php +++ b/administrator/components/com_mails/src/Controller/DisplayController.php @@ -26,7 +26,7 @@ class DisplayController extends BaseController * The default view. * * @var string - * @since 1.6 + * @since __DEPLOY_VERSION__ */ protected $default_view = 'templates'; @@ -38,7 +38,7 @@ class DisplayController extends BaseController * * @return BaseController|boolean This object to support chaining. * - * @since 1.5 + * @since __DEPLOY_VERSION__ */ public function display($cachable = false, $urlparams = array()) { diff --git a/administrator/components/com_mails/src/Helper/MailsHelper.php b/administrator/components/com_mails/src/Helper/MailsHelper.php index 9903a98041810..d3c3c0221f480 100644 --- a/administrator/components/com_mails/src/Helper/MailsHelper.php +++ b/administrator/components/com_mails/src/Helper/MailsHelper.php @@ -32,7 +32,6 @@ abstract class MailsHelper */ public static function mailtags($mail, $fieldname) { - $app = Factory::getApplication(); Factory::getApplication()->triggerEvent('onMailBeforeTagsRendering', array($mail->template_id, &$mail)); if (!isset($mail->params['tags']) || !count($mail->params['tags'])) @@ -45,7 +44,7 @@ public static function mailtags($mail, $fieldname) foreach ($mail->params['tags'] as $tag) { $html .= '
  • ' - . '' . $tag . '' . '
  • '; } @@ -54,4 +53,60 @@ public static function mailtags($mail, $fieldname) return $html; } + + /** + * Load the translation files for an extension + * + * @param string $extension Extension name + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public static function loadTranslationFiles($extension) + { + static $cache = array(); + + $extension = strtolower($extension); + + if (isset($cache[$extension])) + { + return; + } + + $lang = Factory::getLanguage(); + $source = ''; + + switch (substr($extension, 0, 3)) + { + case 'com': + default: + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + break; + + case 'mod': + $source = JPATH_SITE . '/modules/' . $extension; + break; + + case 'plg': + $parts = explode('_', $extension, 3); + + if (count($parts) > 2) + { + $source = JPATH_PLUGINS . '/' . $parts[1] . '/' . $parts[2]; + } + break; + } + + $lang->load($extension, JPATH_ADMINISTRATOR) + || $lang->load($extension, $source); + + if (!$lang->hasKey(strtoupper($extension))) + { + $lang->load($extension . '.sys', JPATH_ADMINISTRATOR) + || $lang->load($extension . '.sys', $source); + } + + $cache[$extension] = true; + } } diff --git a/administrator/components/com_mails/src/Model/TemplatesModel.php b/administrator/components/com_mails/src/Model/TemplatesModel.php index 33dd4269ba467..4a3d753f1a36a 100644 --- a/administrator/components/com_mails/src/Model/TemplatesModel.php +++ b/administrator/components/com_mails/src/Model/TemplatesModel.php @@ -170,9 +170,36 @@ protected function getListQuery() ->bind(':language', $language); } + // Add the list ordering clause + $listOrdering = $this->state->get('list.ordering', 'a.template_id'); + $orderDirn = $this->state->get('list.direction', 'ASC'); + + $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); + return $query; } + /** + * Get list of extensions which are using mail templates + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function getExtensions() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select( + 'DISTINCT SUBSTRING(' . $db->quoteName('template_id') + . ', 1, POSITION(' . $db->quote('.') . ' IN ' . $db->quoteName('template_id') . ') - 1) AS ' . $db->quoteName('extension') + ) + ->from($db->quoteName('#__mail_templates')); + $db->setQuery($query); + + return $db->loadColumn(); + } + /** * Get a list of the current content languages * diff --git a/administrator/components/com_mails/src/Table/TemplateTable.php b/administrator/components/com_mails/src/Table/TemplateTable.php index 0d5c938d38ea4..2b2d6ef47fa34 100644 --- a/administrator/components/com_mails/src/Table/TemplateTable.php +++ b/administrator/components/com_mails/src/Table/TemplateTable.php @@ -25,7 +25,7 @@ class TemplateTable extends Table * An array of key names to be json encoded in the bind function * * @var array - * @since 3.3 + * @since __DEPLOY_VERSION__ */ protected $_jsonEncode = ['attachments', 'params']; diff --git a/administrator/components/com_mails/src/View/Templates/HtmlView.php b/administrator/components/com_mails/src/View/Templates/HtmlView.php index 01b5275659437..1175bf8637809 100644 --- a/administrator/components/com_mails/src/View/Templates/HtmlView.php +++ b/administrator/components/com_mails/src/View/Templates/HtmlView.php @@ -20,6 +20,7 @@ use Joomla\CMS\Pagination\Pagination; use Joomla\CMS\Toolbar\Toolbar; use Joomla\CMS\Toolbar\ToolbarHelper; +use Joomla\Component\Mails\Administrator\Helper\MailsHelper; /** * View for the mail templates configuration @@ -87,6 +88,7 @@ public function display($tpl = null) $this->state = $this->get('State'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); + $extensions = $this->get('Extensions'); // Check for errors. if (count($errors = $this->get('Errors'))) @@ -94,20 +96,9 @@ public function display($tpl = null) throw new GenericDataException(implode("\n", $errors), 500); } - $cache = array(); - $language = Factory::getLanguage(); - - foreach ($this->items as $item) + foreach ($extensions as $extension) { - list($component, $template_id) = explode('.', $item->template_id, 2); - - if (isset($cache[$component])) - { - continue; - } - - $language->load($component, JPATH_ADMINISTRATOR); - $cache[$component] = true; + MailsHelper::loadTranslationFiles($extension); } $this->addToolbar(); diff --git a/administrator/components/com_mails/tmpl/templates/default.php b/administrator/components/com_mails/tmpl/templates/default.php index 132b945644922..1358266efec77 100644 --- a/administrator/components/com_mails/tmpl/templates/default.php +++ b/administrator/components/com_mails/tmpl/templates/default.php @@ -38,11 +38,11 @@
    - + + - + @@ -50,11 +50,11 @@ + - + +
    + template_id; ?>
    modules[$item->menutype])) : ?>
    - + + + + diff --git a/administrator/components/com_modules/tmpl/select/default.php b/administrator/components/com_modules/tmpl/select/default.php index f823168636d4d..51e6a6e28ceb5 100644 --- a/administrator/components/com_modules/tmpl/select/default.php +++ b/administrator/components/com_modules/tmpl/select/default.php @@ -50,6 +50,10 @@ class="form-control" id="comModulesSelectSearch"
    +
    + + +
    items as &$item) : ?>
    diff --git a/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php b/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php index fad83d7f318d9..a28041ac192d7 100644 --- a/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php +++ b/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php @@ -285,7 +285,12 @@ public function getItem($pk = null) { $item->tags = new TagsHelper; $item->tags->getTagIds($item->id, 'com_newsfeeds.newsfeed'); - $item->metadata['tags'] = $item->tags; + + // TODO: We probably don't need this in any client - but needs careful validation + if (!Factory::getApplication()->isClient('api')) + { + $item->metadata['tags'] = $item->tags; + } } return $item; diff --git a/administrator/components/com_newsfeeds/tmpl/newsfeeds/modal.php b/administrator/components/com_newsfeeds/tmpl/newsfeeds/modal.php index 46bf494c58fff..6ab5819394f2a 100644 --- a/administrator/components/com_newsfeeds/tmpl/newsfeeds/modal.php +++ b/administrator/components/com_newsfeeds/tmpl/newsfeeds/modal.php @@ -96,8 +96,10 @@ } ?>
    - + + + + diff --git a/administrator/components/com_privacy/forms/filter_consents.xml b/administrator/components/com_privacy/forms/filter_consents.xml index bc418f048f692..c041160119a65 100644 --- a/administrator/components/com_privacy/forms/filter_consents.xml +++ b/administrator/components/com_privacy/forms/filter_consents.xml @@ -57,7 +57,7 @@ - + diff --git a/administrator/components/com_tags/tmpl/tags/default.php b/administrator/components/com_tags/tmpl/tags/default.php index 6924673d115ab..50f837de95c02 100644 --- a/administrator/components/com_tags/tmpl/tags/default.php +++ b/administrator/components/com_tags/tmpl/tags/default.php @@ -79,7 +79,7 @@ + diff --git a/administrator/components/com_users/config.xml b/administrator/components/com_users/config.xml index 4238d255eebad..8c19210717d33 100644 --- a/administrator/components/com_users/config.xml +++ b/administrator/components/com_users/config.xml @@ -128,13 +128,13 @@
    app->getIdentity()->id === (int) $data[$key]) + { + return true; + } + return parent::allowEdit($data, $key); } @@ -85,6 +91,38 @@ public function cancel($key = null) return $result; } + /** + * Override parent save to redirect when using status edit account. + * + * @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 True if successful, false otherwise. + * + * @since __DEPLOY_VERSION__ + */ + public function save($key = null, $urlVar = null) + { + $result = parent::save($key, $urlVar); + + $task = $this->getTask(); + + if ($task === 'save' && $return = $this->input->get('return', '', 'BASE64')) + { + $return = base64_decode($return); + + // Don't redirect to an external URL. + if (!Uri::isInternal($return)) + { + $return = Uri::base(); + } + + $this->setRedirect($return); + } + + return $result; + } + /** * Method to run batch operations. * diff --git a/administrator/components/com_users/src/Dispatcher/Dispatcher.php b/administrator/components/com_users/src/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..55d0cb0308ef0 --- /dev/null +++ b/administrator/components/com_users/src/Dispatcher/Dispatcher.php @@ -0,0 +1,51 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Component\Users\Administrator\Dispatcher; + +\defined('_JEXEC') or die; + +use Joomla\CMS\Dispatcher\ComponentDispatcher; + +/** + * ComponentDispatcher class for com_users + * + * @since __DEPLOY_VERSION__ + */ +class Dispatcher extends ComponentDispatcher +{ + /** + * Override checkAccess to allow users edit profile without having to have core.manager permission + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function checkAccess() + { + $task = $this->input->getCmd('task'); + $view = $this->input->getCmd('view'); + $layout = $this->input->getCmd('layout'); + $allowedTasks = ['user.edit', 'user.apply', 'user.save', 'user.cancel']; + + // Allow users to edit their own account + if (in_array($task, $allowedTasks, true) || ($view === 'user' && $layout === 'edit')) + { + $user = $this->app->getIdentity(); + $id = $this->input->getInt('id'); + + if ((int) $user->id === $id) + { + return; + } + } + + parent::checkAccess(); + } +} diff --git a/administrator/components/com_users/src/Model/UserModel.php b/administrator/components/com_users/src/Model/UserModel.php index 24e0e21d704b6..f43d37f687436 100644 --- a/administrator/components/com_users/src/Model/UserModel.php +++ b/administrator/components/com_users/src/Model/UserModel.php @@ -130,8 +130,10 @@ public function getForm($data = array(), $loadData = true) return false; } + $user = Factory::getUser(); + // If the user needs to change their password, mark the password fields as required - if (Factory::getUser()->requireReset) + if ($user->requireReset) { $form->setFieldAttribute('password', 'required', 'true'); $form->setFieldAttribute('password2', 'required', 'true'); @@ -143,14 +145,33 @@ public function getForm($data = array(), $loadData = true) $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); } - $userId = $form->getValue('id'); + $userId = (int) $form->getValue('id'); // The user should not be able to set the requireReset value on their own account - if ((int) $userId === (int) Factory::getUser()->id) + if ($userId === (int) $user->id) { $form->removeField('requireReset'); } + /** + * If users without core.manage permission editing their own account, remove some fields which they should + * not be allowed to change and prevent them to change user name if configured + */ + if (!$user->authorise('core.manage', 'com_users') && (int) $user->id === $userId) + { + if (!ComponentHelper::getParams('com_users')->get('change_login_name')) + { + $form->setFieldAttribute('username', 'required', 'false'); + $form->setFieldAttribute('username', 'readonly', 'true'); + $form->setFieldAttribute('username', 'description', 'COM_USERS_USER_FIELD_NOCHANGE_USERNAME_DESC'); + } + + $form->removeField('lastResetTime'); + $form->removeField('resetCount'); + $form->removeField('sendEmail'); + $form->removeField('block'); + } + return $form; } @@ -257,7 +278,7 @@ public function save($data) } // Handle the two factor authentication setup - if (array_key_exists('twofactor', $data)) + if (isset($data['twofactor']['method'])) { $twoFactorMethod = $data['twofactor']['method']; diff --git a/administrator/components/com_users/src/Service/HTML/Users.php b/administrator/components/com_users/src/Service/HTML/Users.php index 82055a8fbf250..1f8e9edfe6194 100644 --- a/administrator/components/com_users/src/Service/HTML/Users.php +++ b/administrator/components/com_users/src/Service/HTML/Users.php @@ -66,8 +66,8 @@ public function addNote($userId) $title = Text::_('COM_USERS_ADD_NOTE'); return ' ' . $title . ''; + . '" class="btn btn-secondary btn-sm">' . $title . ''; } /** @@ -90,7 +90,7 @@ public function filterNotes($count, $userId) $title = Text::_('COM_USERS_FILTER_NOTES'); return ' ' . $title . ''; + . '" class="dropdown-item">' . $title . ''; } /** @@ -113,7 +113,7 @@ public function notes($count, $userId) $title = Text::plural('COM_USERS_N_USER_NOTES', $count); return ''; + . '" data-bs-toggle="modal" class="dropdown-item">' . $title . ''; } /** diff --git a/administrator/components/com_users/src/View/User/HtmlView.php b/administrator/components/com_users/src/View/User/HtmlView.php index 79b345883e2f7..8c67309df88fe 100644 --- a/administrator/components/com_users/src/View/User/HtmlView.php +++ b/administrator/components/com_users/src/View/User/HtmlView.php @@ -144,7 +144,7 @@ protected function addToolbar() $toolbarButtons = []; - if ($canDo->get('core.edit') || $canDo->get('core.create')) + if ($canDo->get('core.edit') || $canDo->get('core.create') || $isProfile) { ToolbarHelper::apply('user.apply'); $toolbarButtons[] = ['save', 'user.save']; diff --git a/administrator/components/com_users/tmpl/users/default.php b/administrator/components/com_users/tmpl/users/default.php index 4d65a2aea2f30..e2e7fc13fad95 100644 --- a/administrator/components/com_users/tmpl/users/default.php +++ b/administrator/components/com_users/tmpl/users/default.php @@ -118,7 +118,7 @@
    id); ?> note_count > 0) : ?> -
    +
    +
    + + + + +
    +
    diff --git a/administrator/components/com_users/tmpl/users/modal.php b/administrator/components/com_users/tmpl/users/modal.php index 73d4b9f342644..4372f85f54e53 100644 --- a/administrator/components/com_users/tmpl/users/modal.php +++ b/administrator/components/com_users/tmpl/users/modal.php @@ -83,11 +83,15 @@
    escape($item->username); ?> - + + + + - + + + + group_names); ?> diff --git a/administrator/components/com_workflow/tmpl/stages/default.php b/administrator/components/com_workflow/tmpl/stages/default.php index 9f9d529673310..5293217c74b9c 100644 --- a/administrator/components/com_workflow/tmpl/stages/default.php +++ b/administrator/components/com_workflow/tmpl/stages/default.php @@ -72,10 +72,10 @@ + +
    - log_date, Text::_('DATE_FORMAT_LC5')); ?> + log_date); ?>