diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 9aceb79e81cad..50b6393e5c76d 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -14,12 +14,12 @@ If it is a PR, include what the issue is, what the PR is addressing, testing ins
Please be patient as not all items will be tested immediately (remember, all bug testing for the Joomla! CMS is done by volunteers) and be receptive to feedback about your code.
#### Branches
-PRs should usually be made to the `4.2-dev` branch as this contains the most recent version of the code.
+PRs should usually be made to the `4.3-dev` branch as this contains the most recent version of the code.
There are other branches available which serve specific purposes.
| Branch | Purpose |
| ------ | ------- |
| 3.10-dev | Branch for the Joomla 3.x series. The 3.10 series release will now only include security patches. |
-| 4.2-dev | Branch for the current minor Joomla version.|
-| 4.3-dev | Branch for the next minor Joomla version. New features go into this branch. Commits to 4.2-dev will be applied to this branch as well. |
-| 5.0-dev | Branch for the next major Joomla version. |
+| 4.3-dev | Branch for the current minor Joomla version.|
+| 4.4-dev | Branch for the next minor Joomla version. Commits to 4.3-dev will be applied to this branch as well. |
+| 5.0-dev | Branch for the next major Joomla version. New features go into this branch. |
diff --git a/README.md b/README.md
index 709e9e65905fd..7b42c4793857f 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ Overview
* This is the source of Joomla! 4.x.
* Joomla's [Official website](https://www.joomla.org).
* Joomla! 4.3 [version history](https://docs.joomla.org/Special:MyLanguage/Joomla_4.3_version_history).
-* Detailed changes are in the [changelog](https://github.com/joomla/joomla-cms/commits/4.2-dev).
+* Detailed changes are in the [changelog](https://github.com/joomla/joomla-cms/commits/4.3-dev).
What is Joomla?
---------------------
diff --git a/README.txt b/README.txt
index 0eaac7a3084e5..1caf5eef7ef98 100644
--- a/README.txt
+++ b/README.txt
@@ -4,7 +4,7 @@ Joomla! CMS™
* This is a Joomla! 4.x installation/upgrade package.
* Joomla! Official site: https://www.joomla.org
* Joomla! 4.3 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_4.3_version_history
- * Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/4.2-dev
+ * Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/4.3-dev
2- What is Joomla?
* Joomla! is a Content Management System (CMS) which enables you to build websites and powerful online applications.
diff --git a/administrator/components/com_actionlogs/src/Controller/DisplayController.php b/administrator/components/com_actionlogs/src/Controller/DisplayController.php
index 3ff880b1ebeed..7493052e2de1c 100644
--- a/administrator/components/com_actionlogs/src/Controller/DisplayController.php
+++ b/administrator/components/com_actionlogs/src/Controller/DisplayController.php
@@ -17,7 +17,7 @@
// phpcs:enable PSR1.Files.SideEffects
/**
- * Plugins master display controller.
+ * Plugins display controller.
*
* @since 4.0.0
*/
diff --git a/administrator/components/com_actionlogs/src/Dispatcher/Dispatcher.php b/administrator/components/com_actionlogs/src/Dispatcher/Dispatcher.php
index 778d74d4b96fa..adfe2f4e5f0ff 100644
--- a/administrator/components/com_actionlogs/src/Dispatcher/Dispatcher.php
+++ b/administrator/components/com_actionlogs/src/Dispatcher/Dispatcher.php
@@ -18,14 +18,14 @@
// phpcs:enable PSR1.Files.SideEffects
/**
- * ComponentDispatcher class for com_admin
+ * ComponentDispatcher class for com_actionlogs
*
* @since 4.2.7
*/
class Dispatcher extends ComponentDispatcher
{
/**
- * com_admin does not require check permission, so we override checkAccess method and have it empty
+ * Method to check component access permission
*
* @return void
*
diff --git a/administrator/components/com_actionlogs/src/Field/LogtypeField.php b/administrator/components/com_actionlogs/src/Field/LogtypeField.php
index d55071386192f..6aae799f0c2b2 100644
--- a/administrator/components/com_actionlogs/src/Field/LogtypeField.php
+++ b/administrator/components/com_actionlogs/src/Field/LogtypeField.php
@@ -21,7 +21,7 @@
// phpcs:enable PSR1.Files.SideEffects
/**
- * Field to load a list of all users that have logged actions
+ * Field to load a list of all extensions that have logged actions
*
* @since 3.9.0
*/
diff --git a/administrator/components/com_admin/src/View/Sysinfo/TextView.php b/administrator/components/com_admin/src/View/Sysinfo/TextView.php
index 603c565aeaebe..3a778e664e2b8 100644
--- a/administrator/components/com_admin/src/View/Sysinfo/TextView.php
+++ b/administrator/components/com_admin/src/View/Sysinfo/TextView.php
@@ -146,6 +146,7 @@ protected function renderSection(string $sectionName, array $sectionData, int $l
}
if (\is_int($name) && ($name == 0 || $name == 1)) {
+ // The term "Master" is used because it is the term used in phpinfo() and this is a text representation of that.
$name = ($name == 0 ? 'Local Value' : 'Master Value');
}
diff --git a/administrator/components/com_banners/src/Controller/DisplayController.php b/administrator/components/com_banners/src/Controller/DisplayController.php
index 72a595c51c13a..3e1d8b0da07bb 100644
--- a/administrator/components/com_banners/src/Controller/DisplayController.php
+++ b/administrator/components/com_banners/src/Controller/DisplayController.php
@@ -20,7 +20,7 @@
// phpcs:enable PSR1.Files.SideEffects
/**
- * Banners master display controller.
+ * Banners display controller.
*
* @since 1.6
*/
diff --git a/administrator/components/com_config/src/Controller/RequestController.php b/administrator/components/com_config/src/Controller/RequestController.php
index 4ecd25cdeb5ef..889f3282f1b59 100644
--- a/administrator/components/com_config/src/Controller/RequestController.php
+++ b/administrator/components/com_config/src/Controller/RequestController.php
@@ -65,15 +65,12 @@ public function getJson()
try {
$data = $model->getData();
- $user = $this->app->getIdentity();
} catch (\Exception $e) {
$this->app->enqueueMessage($e->getMessage(), 'error');
return false;
}
- $this->userIsSuperAdmin = $user->authorise('core.admin');
-
// Required data
$requiredData = [
'sitename' => null,
diff --git a/administrator/components/com_config/src/Dispatcher/Dispatcher.php b/administrator/components/com_config/src/Dispatcher/Dispatcher.php
index 6874ee33ea6f9..97bfa3b44ca9f 100644
--- a/administrator/components/com_config/src/Dispatcher/Dispatcher.php
+++ b/administrator/components/com_config/src/Dispatcher/Dispatcher.php
@@ -36,8 +36,8 @@ class Dispatcher extends ComponentDispatcher
*/
protected function checkAccess(): void
{
- // sendtestmail expects json response, so we leave the method to handle the permission and send response itself
- if ($this->input->getCmd('task') === 'application.sendtestmail') {
+ // 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;
}
diff --git a/administrator/components/com_contact/forms/filter_contacts.xml b/administrator/components/com_contact/forms/filter_contacts.xml
index 614589dde237c..b47a392d13dfb 100644
--- a/administrator/components/com_contact/forms/filter_contacts.xml
+++ b/administrator/components/com_contact/forms/filter_contacts.xml
@@ -107,8 +107,8 @@
-
-
+
+
diff --git a/administrator/components/com_contact/tmpl/contacts/default.php b/administrator/components/com_contact/tmpl/contacts/default.php
index 849ddc6e34551..0a44ad724f9bf 100644
--- a/administrator/components/com_contact/tmpl/contacts/default.php
+++ b/administrator/components/com_contact/tmpl/contacts/default.php
@@ -68,7 +68,7 @@
-
+
diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml
index eee659d520a17..c037c6e9de367 100644
--- a/administrator/components/com_content/config.xml
+++ b/administrator/components/com_content/config.xml
@@ -509,6 +509,7 @@
name="float_intro"
type="text"
label="COM_CONTENT_IMAGE_INTRO_CLASS_LABEL"
+ validate="CssIdentifier"
showon="show_urls_images_backend:1[OR]show_urls_images_frontend:1"
/>
@@ -516,6 +517,7 @@
name="float_fulltext"
type="text"
label="COM_CONTENT_IMAGE_FULLTEXT_CLASS_LABEL"
+ validate="CssIdentifier"
showon="show_urls_images_backend:1[OR]show_urls_images_frontend:1"
/>
diff --git a/administrator/components/com_content/forms/article.xml b/administrator/components/com_content/forms/article.xml
index b7755b67aa1b7..b53a81ee43667 100644
--- a/administrator/components/com_content/forms/article.xml
+++ b/administrator/components/com_content/forms/article.xml
@@ -744,6 +744,7 @@
label="COM_CONTENT_FIELD_IMAGE_CLASS_LABEL"
description="COM_CONTENT_FIELD_IMAGE_CLASS_DESC"
useglobal="true"
+ validate="CssIdentifier"
/>
diff --git a/administrator/components/com_fields/forms/field.xml b/administrator/components/com_fields/forms/field.xml
index 98e9d563f01fe..a25de44730f62 100644
--- a/administrator/components/com_fields/forms/field.xml
+++ b/administrator/components/com_fields/forms/field.xml
@@ -270,6 +270,7 @@
label="COM_FIELDS_FIELD_VALUE_RENDER_CLASS_LABEL"
description="COM_FIELDS_FIELD_VALUE_RENDER_CLASS_DESC"
size="40"
+ validate="CssIdentifier"
/>
state->get('filter.context'));
+ // If we don't have a valid context then return early
+ if (!$parts) {
+ return;
+ }
+
// Extract the component name
$component = $parts[0];
- // Extract the optional section name
- $section = (count($parts) > 1) ? $parts[1] : null;
+ // Extract the section name
+ $section = $parts[1];
- if ($parts) {
- // Set the access control rules field component value.
- $form->setFieldAttribute('rules', 'component', $component);
- }
+ // Set the access control rules field component value.
+ $form->setFieldAttribute('rules', 'component', $component);
- if ($section !== null) {
- // Looking first in the component models/forms folder
- $path = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fieldgroup/' . $section . '.xml');
+ // Looking first in the component models/forms folder
+ $path = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fieldgroup/' . $section . '.xml');
- if (file_exists($path)) {
- $lang = Factory::getLanguage();
- $lang->load($component, JPATH_BASE);
- $lang->load($component, JPATH_BASE . '/components/' . $component);
+ if (file_exists($path)) {
+ $lang = Factory::getLanguage();
+ $lang->load($component, JPATH_BASE);
+ $lang->load($component, JPATH_BASE . '/components/' . $component);
- if (!$form->loadFile($path, false)) {
- throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
- }
+ if (!$form->loadFile($path, false)) {
+ throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
}
}
}
diff --git a/administrator/components/com_fields/tmpl/fields/default.php b/administrator/components/com_fields/tmpl/fields/default.php
index e0f5c4c72062c..3778dceca1968 100644
--- a/administrator/components/com_fields/tmpl/fields/default.php
+++ b/administrator/components/com_fields/tmpl/fields/default.php
@@ -198,7 +198,7 @@
pagination->getListFooter(); ?>
-
+
authorise('core.create', $component)
diff --git a/administrator/components/com_fields/tmpl/groups/default.php b/administrator/components/com_fields/tmpl/groups/default.php
index 1bde8e30eb335..f9b5bcd3360ba 100644
--- a/administrator/components/com_fields/tmpl/groups/default.php
+++ b/administrator/components/com_fields/tmpl/groups/default.php
@@ -166,7 +166,7 @@
pagination->getListFooter(); ?>
-
+
authorise('core.create', $component)
diff --git a/administrator/components/com_finder/src/Indexer/Language/Zh.php b/administrator/components/com_finder/src/Indexer/Language/Zh.php
index bfe598b52721a..5e8217e1d3301 100644
--- a/administrator/components/com_finder/src/Indexer/Language/Zh.php
+++ b/administrator/components/com_finder/src/Indexer/Language/Zh.php
@@ -11,7 +11,6 @@
namespace Joomla\Component\Finder\Administrator\Indexer\Language;
use Joomla\Component\Finder\Administrator\Indexer\Language;
-use Joomla\String\StringHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -61,26 +60,11 @@ public function __construct($locale = null)
*/
public function tokenise($input)
{
- $terms = parent::tokenise($input);
-
- // Iterate through the terms and test if they contain Chinese.
- for ($i = 0, $n = count($terms); $i < $n; $i++) {
- $charMatches = [];
- $charCount = preg_match_all('#[\p{Han}]#mui', $terms[$i], $charMatches);
-
- // Split apart any groups of Chinese characters.
- for ($j = 0; $j < $charCount; $j++) {
- $tSplit = StringHelper::str_ireplace($charMatches[0][$j], '', $terms[$i], false);
+ // We first add whitespace around each Chinese character, so that our later code can easily split on this.
+ $input = preg_replace('#\p{Han}#mui', ' $0 ', $input);
- if (!empty($tSplit)) {
- $terms[$i] = $tSplit;
- } else {
- unset($terms[$i]);
- }
-
- $terms[] = $charMatches[0][$j];
- }
- }
+ // Now we split up the input into individual terms
+ $terms = parent::tokenise($input);
return $terms;
}
diff --git a/administrator/components/com_guidedtours/src/Controller/DisplayController.php b/administrator/components/com_guidedtours/src/Controller/DisplayController.php
index 3f83224df59c0..c5ef8a5738126 100644
--- a/administrator/components/com_guidedtours/src/Controller/DisplayController.php
+++ b/administrator/components/com_guidedtours/src/Controller/DisplayController.php
@@ -12,6 +12,7 @@
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
+use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
// phpcs:disable PSR1.Files.SideEffects
@@ -49,6 +50,11 @@ public function display($cachable = false, $urlparams = [])
$layout = $this->input->get('layout', 'default');
$id = $this->input->getInt('id');
+ // Show messages about the disabled plugin
+ if ($view === 'tours' && !PluginHelper::isEnabled('system', 'guidedtours')) {
+ $this->app->enqueueMessage(Text::_('COM_GUIDEDTOURS_PLUGIN_DISABLED'), 'error');
+ }
+
if ($view === 'tour' && $layout === 'edit' && !$this->checkEditId('com_guidedtours.edit.tour', $id)) {
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
$this->setRedirect(Route::_('index.php?option=com_guidedtours&view=tours', false));
diff --git a/administrator/components/com_guidedtours/src/Model/StepsModel.php b/administrator/components/com_guidedtours/src/Model/StepsModel.php
index 14c6c3584070a..134721e5756d9 100644
--- a/administrator/components/com_guidedtours/src/Model/StepsModel.php
+++ b/administrator/components/com_guidedtours/src/Model/StepsModel.php
@@ -50,6 +50,7 @@ public function __construct($config = [])
'created_by', 'a.created_by',
'modified', 'a.modified',
'modified_by', 'a.modified_by',
+ 'note', 'a.note',
];
}
@@ -200,9 +201,10 @@ protected function getListQuery()
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
$query->where(
'(' . $db->quoteName('a.title') . ' LIKE :search1'
- . ' OR ' . $db->quoteName('a.description') . ' LIKE :search2)'
+ . ' OR ' . $db->quoteName('a.description') . ' LIKE :search2'
+ . ' OR ' . $db->quoteName('a.note') . ' LIKE :search3)'
)
- ->bind([':search1', ':search2'], $search);
+ ->bind([':search1', ':search2', ':search3'], $search);
}
}
diff --git a/administrator/components/com_guidedtours/src/Model/TourModel.php b/administrator/components/com_guidedtours/src/Model/TourModel.php
index bc23ae4f008cf..71acf8884af22 100644
--- a/administrator/components/com_guidedtours/src/Model/TourModel.php
+++ b/administrator/components/com_guidedtours/src/Model/TourModel.php
@@ -77,24 +77,7 @@ public function save($data)
$this->setStepsLanguage($id, $lang);
- $result = parent::save($data);
-
- // Create default step for new tour
- if ($result && $input->getCmd('task') !== 'save2copy' && $this->getState($this->getName() . '.new')) {
- $tourId = (int) $this->getState($this->getName() . '.id');
-
- $table = $this->getTable('Step');
-
- $table->id = 0;
- $table->title = 'COM_GUIDEDTOURS_BASIC_STEP';
- $table->description = '';
- $table->tour_id = $tourId;
- $table->published = 1;
-
- $table->store();
- }
-
- return $result;
+ return parent::save($data);
}
/**
diff --git a/administrator/components/com_guidedtours/src/Model/ToursModel.php b/administrator/components/com_guidedtours/src/Model/ToursModel.php
index 2ee0df9df3953..3850090ca947a 100644
--- a/administrator/components/com_guidedtours/src/Model/ToursModel.php
+++ b/administrator/components/com_guidedtours/src/Model/ToursModel.php
@@ -51,6 +51,7 @@ public function __construct($config = [])
'created_by', 'a.created_by',
'modified', 'a.modified',
'modified_by', 'a.modified_by',
+ 'note', 'a.note',
];
}
@@ -220,9 +221,10 @@ public function getListQuery()
$search = '%' . str_replace(' ', '%', trim($search)) . '%';
$query->where(
'(' . $db->quoteName('a.title') . ' LIKE :search1'
- . ' OR ' . $db->quoteName('a.description') . ' LIKE :search2)'
+ . ' OR ' . $db->quoteName('a.description') . ' LIKE :search2'
+ . ' OR ' . $db->quoteName('a.note') . ' LIKE :search3)'
)
- ->bind([':search1', ':search2'], $search);
+ ->bind([':search1', ':search2', ':search3'], $search);
}
}
diff --git a/administrator/components/com_installer/src/Model/ManageModel.php b/administrator/components/com_installer/src/Model/ManageModel.php
index 4520c9f4ea20a..d6a5932d8ec6c 100644
--- a/administrator/components/com_installer/src/Model/ManageModel.php
+++ b/administrator/components/com_installer/src/Model/ManageModel.php
@@ -56,6 +56,7 @@ public function __construct($config = [], MVCFactoryInterface $factory = null)
'package_id',
'extension_id',
'creationDate',
+ 'core',
];
}
diff --git a/administrator/components/com_joomlaupdate/src/Controller/UpdateController.php b/administrator/components/com_joomlaupdate/src/Controller/UpdateController.php
index 054da8a3c4862..0d8a0a09cccba 100644
--- a/administrator/components/com_joomlaupdate/src/Controller/UpdateController.php
+++ b/administrator/components/com_joomlaupdate/src/Controller/UpdateController.php
@@ -60,7 +60,7 @@ public function download()
$message = null;
$messageType = null;
- // The validation was not successful so abort.
+ // The validation was not successful so stop.
if ($result['check'] === false) {
$message = Text::_('COM_JOOMLAUPDATE_VIEW_UPDATE_CHECKSUM_WRONG');
$messageType = 'error';
diff --git a/administrator/components/com_joomlaupdate/src/Dispatcher/Dispatcher.php b/administrator/components/com_joomlaupdate/src/Dispatcher/Dispatcher.php
index e96f052286353..768f4369dce3f 100644
--- a/administrator/components/com_joomlaupdate/src/Dispatcher/Dispatcher.php
+++ b/administrator/components/com_joomlaupdate/src/Dispatcher/Dispatcher.php
@@ -18,7 +18,7 @@
// phpcs:enable PSR1.Files.SideEffects
/**
- * ComponentDispatcher class for com_admin
+ * ComponentDispatcher class for com_joomlaupdate
*
* @since 4.0.0
*/
diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/image.vue b/administrator/components/com_media/resources/scripts/components/browser/items/image.vue
index 5c91946511152..f8d1606b22c3a 100644
--- a/administrator/components/com_media/resources/scripts/components/browser/items/image.vue
+++ b/administrator/components/com_media/resources/scripts/components/browser/items/image.vue
@@ -77,7 +77,7 @@ export default {
}
return this.item.thumb_path.split(Joomla.getOptions('system.paths').rootFull).length > 1
- ? `${this.item.thumb_path}?${api.mediaVersion}`
+ ? `${this.item.thumb_path}?${this.item.modified_date ? new Date(this.item.modified_date).valueOf() : api.mediaVersion}`
: `${this.item.thumb_path}`;
},
width() {
diff --git a/administrator/components/com_media/resources/scripts/store/state.es6.js b/administrator/components/com_media/resources/scripts/store/state.es6.js
index 593aa949776c8..8cb71276175c6 100644
--- a/administrator/components/com_media/resources/scripts/store/state.es6.js
+++ b/administrator/components/com_media/resources/scripts/store/state.es6.js
@@ -39,48 +39,39 @@ function setSession(path) {
// Gracefully use the given path, the session storage state or fall back to sensible default
function getCurrentPath() {
- // Nothing stored in the session, use the root of the first drive
- if (!storedState || !storedState.selectedDirectory) {
- setSession(defaultDisk.drives[0].root);
- return defaultDisk.drives[0].root;
+ let path = options.currentPath;
+
+ // Set the path from the session when available
+ if (!path && storedState && storedState.selectedDirectory) {
+ path = storedState.selectedDirectory;
}
- // Check that we have a fragment
- if (!options.currentPath) {
- if (!(storedState || storedState.selectedDirectory)) {
- setSession(defaultDisk.drives[0].root);
- return defaultDisk.drives[0].root;
- }
- options.currentPath = '';
+ // No path available, use the root of the first drive
+ if (!path) {
+ setSession(defaultDisk.drives[0].root);
+ return defaultDisk.drives[0].root;
}
// Get the fragments
- const fragment = options.currentPath.split(':/');
+ const fragment = path.split(':/');
- // Check that we have a fragment
+ // Check that we have a drive
if (!fragment.length) {
setSession(defaultDisk.drives[0].root);
return defaultDisk.drives[0].root;
}
const drivesTmp = Object.values(loadedDisks).map((drive) => drive.drives);
- const useDrive = drivesTmp.flat().find((drive) => drive.root.startsWith(fragment[0]));
// Drive doesn't exist
- if (!useDrive) {
+ if (!drivesTmp.flat().find((drive) => drive.root.startsWith(fragment[0]))) {
setSession(defaultDisk.drives[0].root);
return defaultDisk.drives[0].root;
}
- // Session match
- if ((storedState && storedState.selectedDirectory && storedState.selectedDirectory.startsWith(useDrive.root))) {
- setSession(storedState.selectedDirectory);
- return storedState.selectedDirectory;
- }
-
// Session missmatch
- setSession(options.currentPath);
- return options.currentPath;
+ setSession(path);
+ return path;
}
// The initial state
diff --git a/administrator/components/com_menus/forms/itemadmin_alias.xml b/administrator/components/com_menus/forms/itemadmin_alias.xml
index e32fdd55529a3..2e4077f90205f 100644
--- a/administrator/components/com_menus/forms/itemadmin_alias.xml
+++ b/administrator/components/com_menus/forms/itemadmin_alias.xml
@@ -27,17 +27,12 @@
label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL"
/>
-
-
+
+