diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000..0be9be57ae051 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://community.joomla.org/sponsorship-campaigns.html diff --git a/administrator/components/com_associations/View/Association/HtmlView.php b/administrator/components/com_associations/View/Association/HtmlView.php index f1a412e22553d..a2eb8f6c5878a 100644 --- a/administrator/components/com_associations/View/Association/HtmlView.php +++ b/administrator/components/com_associations/View/Association/HtmlView.php @@ -118,8 +118,9 @@ public function display($tpl = null) $referenceId = $input->get('id', 0, 'int'); $reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId)); - $this->referenceLanguage = $reference[$languageField]; - $this->referenceTitle = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'title'); + $this->referenceLanguage = $reference[$languageField]; + $this->referenceTitle = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'title'); + $this->referenceTitleValue = $reference[$this->referenceTitle]; // Check for special case category $typeNameExploded = explode('.', $typeName); diff --git a/administrator/components/com_associations/tmpl/association/edit.php b/administrator/components/com_associations/tmpl/association/edit.php index 34d948ca05bc4..aca22cdafc274 100644 --- a/administrator/components/com_associations/tmpl/association/edit.php +++ b/administrator/components/com_associations/tmpl/association/edit.php @@ -44,6 +44,7 @@ data-item="typeName; ?>" data-id="referenceId; ?>" data-title="referenceTitle; ?>" + data-title-value="referenceTitleValue; ?>" data-language="referenceLanguage; ?>" data-editurl="editUri); ?>"> diff --git a/administrator/components/com_banners/Model/BannerModel.php b/administrator/components/com_banners/Model/BannerModel.php index e056a05cd7aae..20293e4d7e58b 100644 --- a/administrator/components/com_banners/Model/BannerModel.php +++ b/administrator/components/com_banners/Model/BannerModel.php @@ -373,6 +373,9 @@ protected function preprocessForm(Form $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } parent::preprocessForm($form, $data, $group); @@ -391,20 +394,22 @@ public function save($data) { $input = Factory::getApplication()->input; - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_banners'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_banners'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_banners'; $table['language'] = $data['language']; diff --git a/administrator/components/com_categories/Field/CategoryeditField.php b/administrator/components/com_categories/Field/CategoryeditField.php index 5042baab34949..e75a578231912 100644 --- a/administrator/components/com_categories/Field/CategoryeditField.php +++ b/administrator/components/com_categories/Field/CategoryeditField.php @@ -32,6 +32,14 @@ class CategoryeditField extends ListField */ protected $allowAdd; + /** + * Optional prefix for new categories. + * + * @var string + * @since 3.9.11 + */ + protected $customPrefix; + /** * A flexible category list that respects access controls * @@ -69,6 +77,7 @@ public function setup(\SimpleXMLElement $element, $value, $group = null) if ($return) { $this->allowAdd = isset($this->element['allowAdd']) ? (boolean) $this->element['allowAdd'] : false; + $this->customPrefix = (string) $this->element['customPrefix']; } return $return; @@ -89,6 +98,8 @@ public function __get($name) { case 'allowAdd': return (bool) $this->$name; + case 'customPrefix': + return $this->$name; } return parent::__get($name); @@ -114,6 +125,9 @@ public function __set($name, $value) $value = (string) $value; $this->$name = ($value === 'true' || $value === $name || $value === '1'); break; + case 'customPrefix': + $this->$name = (string) $value; + break; default: parent::__set($name, $value); } diff --git a/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php b/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php index 7e2f99159d38d..2645a45de6136 100644 --- a/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php +++ b/administrator/components/com_categories/layouts/joomla/form/field/categoryedit.php @@ -71,6 +71,11 @@ if ($allowCustom) { $attr2 .= ' allow-custom'; + + if ($this->customPrefix !== '') + { + $attr2 .= ' data-custom_value_prefix="' . $this->customPrefix . '" '; + } } if ($required) diff --git a/administrator/components/com_contact/Model/ContactModel.php b/administrator/components/com_contact/Model/ContactModel.php index 59c04ea0f507e..d4ebf420ac711 100644 --- a/administrator/components/com_contact/Model/ContactModel.php +++ b/administrator/components/com_contact/Model/ContactModel.php @@ -278,20 +278,22 @@ public function save($data) { $input = Factory::getApplication()->input; - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_contact'; $table['language'] = $data['language']; @@ -427,6 +429,9 @@ protected function preprocessForm(Form $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } // Association contact items diff --git a/administrator/components/com_contact/tmpl/contacts/modal.php b/administrator/components/com_contact/tmpl/contacts/modal.php index 86b7424b5ef82..e1fa25cc5135f 100644 --- a/administrator/components/com_contact/tmpl/contacts/modal.php +++ b/administrator/components/com_contact/tmpl/contacts/modal.php @@ -44,7 +44,7 @@ ?>
-
+ $this)); ?> diff --git a/administrator/components/com_content/Model/ArticleModel.php b/administrator/components/com_content/Model/ArticleModel.php index 2f2d9c080c4ba..b23a2544208e8 100644 --- a/administrator/components/com_content/Model/ArticleModel.php +++ b/administrator/components/com_content/Model/ArticleModel.php @@ -780,20 +780,24 @@ public function save($data) $data['images'] = (string) $registry; } - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + \JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - // Check if New Category exists - if ($catid > 0) + // Create new category, if needed. + $createCategory = true; + + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_content'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_content'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_content'; $table['language'] = $data['language']; @@ -1115,6 +1119,9 @@ protected function preprocessForm(Form $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } // Association content items diff --git a/administrator/components/com_fields/Model/FieldsModel.php b/administrator/components/com_fields/Model/FieldsModel.php index 3f4566f0daa05..91eaffac23a33 100644 --- a/administrator/components/com_fields/Model/FieldsModel.php +++ b/administrator/components/com_fields/Model/FieldsModel.php @@ -53,7 +53,7 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu 'checked_out_time', 'a.checked_out_time', 'created_time', 'a.created_time', 'created_user_id', 'a.created_user_id', - 'category_title', + 'group_title', 'g.title', 'category_id', 'a.category_id', 'group_id', 'a.group_id', 'assigned_cat_ids' diff --git a/administrator/components/com_fields/View/Fields/HtmlView.php b/administrator/components/com_fields/View/Fields/HtmlView.php index e98f7acfa4f94..092ed567be606 100644 --- a/administrator/components/com_fields/View/Fields/HtmlView.php +++ b/administrator/components/com_fields/View/Fields/HtmlView.php @@ -219,7 +219,7 @@ protected function getSortFields() 'a.title' => Text::_('JGLOBAL_TITLE'), 'a.type' => Text::_('COM_FIELDS_FIELD_TYPE_LABEL'), 'a.access' => Text::_('JGRID_HEADING_ACCESS'), - 'language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.language' => Text::_('JGRID_HEADING_LANGUAGE'), 'a.id' => Text::_('JGRID_HEADING_ID'), ); } diff --git a/administrator/components/com_fields/tmpl/fields/modal.php b/administrator/components/com_fields/tmpl/fields/modal.php index 9e4e351119941..c7a1b06364ac9 100644 --- a/administrator/components/com_fields/tmpl/fields/modal.php +++ b/administrator/components/com_fields/tmpl/fields/modal.php @@ -29,7 +29,7 @@ ?>
- + $this)); ?> items)) : ?> @@ -51,7 +51,7 @@ - + @@ -60,7 +60,7 @@ - + diff --git a/administrator/components/com_finder/Indexer/Parser/Html.php b/administrator/components/com_finder/Indexer/Parser/Html.php index c968fe09beb0a..6df538bde3379 100644 --- a/administrator/components/com_finder/Indexer/Parser/Html.php +++ b/administrator/components/com_finder/Indexer/Parser/Html.php @@ -65,9 +65,14 @@ public function parse($input) // Convert entities equivalent to spaces to actual spaces. $input = str_replace(array(' ', ' '), ' ', $input); - // This fixes issues such as '

Title

Paragraph

' - // being transformed into 'TitleParagraph' with no space. - $input = str_replace('>', '> ', $input); + // Add a space before both the OPEN and CLOSE tags of BLOCK and LINE BREAKING elements, + // e.g. 'all

mobile List

' will become 'all mobile List' + $input = preg_replace('/(<|<\/)(' . + 'address|article|aside|blockquote|br|canvas|dd|div|dl|dt|' . + 'fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|li|' . + 'main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video' . + ')\b/i', ' $1$2', $input + ); // Strip HTML tags. $input = strip_tags($input); diff --git a/administrator/components/com_languages/tmpl/multilangstatus/default.php b/administrator/components/com_languages/tmpl/multilangstatus/default.php index ffb30a4bfb509..b3ac082d94056 100644 --- a/administrator/components/com_languages/tmpl/multilangstatus/default.php +++ b/administrator/components/com_languages/tmpl/multilangstatus/default.php @@ -44,7 +44,7 @@
- +
@@ -83,9 +83,9 @@ listUsersError) : ?> -
- - +
+ +
    listUsersError as $user) : ?> diff --git a/administrator/components/com_newsfeeds/Model/NewsfeedModel.php b/administrator/components/com_newsfeeds/Model/NewsfeedModel.php index 80fb266d9ac34..f907d635761f7 100644 --- a/administrator/components/com_newsfeeds/Model/NewsfeedModel.php +++ b/administrator/components/com_newsfeeds/Model/NewsfeedModel.php @@ -188,20 +188,22 @@ public function save($data) { $input = Factory::getApplication()->input; - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_newsfeeds'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_newsfeeds'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_newsfeeds'; $table['language'] = $data['language']; @@ -388,6 +390,9 @@ protected function preprocessForm(Form $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } // Association newsfeeds items diff --git a/administrator/components/com_postinstall/tmpl/messages/default.php b/administrator/components/com_postinstall/tmpl/messages/default.php index dbb010b2865c2..ffe788fb05321 100644 --- a/administrator/components/com_postinstall/tmpl/messages/default.php +++ b/administrator/components/com_postinstall/tmpl/messages/default.php @@ -15,6 +15,7 @@ use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; +$lang = Factory::getLanguage(); $renderer = Factory::getDocument()->loadRenderer('module'); $options = array('style' => 'raw'); $mod = ModuleHelper::getModule('mod_feed'); @@ -25,6 +26,7 @@ 'rssimage' => 1, 'rssitems' => 5, 'rssitemdesc' => 1, + 'rssrtl' => $lang->isRtl() ? 1 : 0, 'word_count' => 200, 'cache' => 0, ); diff --git a/administrator/components/com_templates/tmpl/style/edit_assignment.php b/administrator/components/com_templates/tmpl/style/edit_assignment.php index 0fe705457aa6f..6fd07a930a7d8 100644 --- a/administrator/components/com_templates/tmpl/style/edit_assignment.php +++ b/administrator/components/com_templates/tmpl/style/edit_assignment.php @@ -40,7 +40,7 @@ links as $link) : ?> diff --git a/administrator/components/com_templates/tmpl/template/default_tree.php b/administrator/components/com_templates/tmpl/template/default_tree.php index 7fe629a9d13df..bd76a983fdbea 100644 --- a/administrator/components/com_templates/tmpl/template/default_tree.php +++ b/administrator/components/com_templates/tmpl/template/default_tree.php @@ -11,7 +11,7 @@ use Joomla\CMS\Router\Route; -ksort($this->files, SORT_STRING); +ksort($this->files, SORT_NATURAL); ?>
      diff --git a/administrator/language/en-GB/en-GB.com_content.ini b/administrator/language/en-GB/en-GB.com_content.ini index 3f5bf9392e3b9..6fef77d6fc068 100644 --- a/administrator/language/en-GB/en-GB.com_content.ini +++ b/administrator/language/en-GB/en-GB.com_content.ini @@ -21,7 +21,7 @@ COM_CONTENT_BATCH_TIP="If a category is selected for move/copy, any actions sele COM_CONTENT_CHANGE_STAGE="Change stage" COM_CONTENT_CHANGE_STAGE_AMBIGUOUS_TRANSITIONS="Some transitions are ambiguous for this condition. Please select your preferred transition and proceed." COM_CONTENT_CONFIGURATION="Articles: Options" -COM_CONTENT_CONFIG_ARTICLE_SETTINGS_DESC="These settings apply for article layouts unless they are changed for a specific menu item." +COM_CONTENT_CONFIG_ARTICLE_SETTINGS_DESC="These settings apply for article layouts unless they are changed for a specific menu item or article." COM_CONTENT_CONFIG_BLOG_SETTINGS_DESC="These settings apply for blog or featured layouts unless they are changed for a specific menu item." COM_CONTENT_CONFIG_BLOG_SETTINGS_LABEL="Blog/Featured Layouts" COM_CONTENT_CONFIG_CATEGORIES_SETTINGS_DESC="These settings apply for Articles Categories Options, unless they are changed by the individual category or menu settings." diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini index 3d552adfe1a08..e54ec200d3ca8 100644 --- a/administrator/language/en-GB/en-GB.ini +++ b/administrator/language/en-GB/en-GB.ini @@ -554,7 +554,7 @@ JGLOBAL_SHOW_CATEGORY_HEADING_TITLE_TEXT_DESC="If Show, the "Subcategories& JGLOBAL_SHOW_CATEGORY_LABEL="Category" JGLOBAL_SHOW_CATEGORY_TITLE="Category Title" JGLOBAL_SHOW_CATEGORY_TITLE_DESC="If Show, the Category Title will show as a subheading on the page. The subheading is usually displayed inside the "H2" tag." -JGLOBAL_SHOW_CREATE_DATE_DESC="If set to Show, the date and time an Article was created will be displayed. This is a global setting but can be changed at Menu and Article levels." +JGLOBAL_SHOW_CREATE_DATE_DESC="If set to Show, the date and time an Article was created will be displayed." JGLOBAL_SHOW_CREATE_DATE_LABEL="Create Date" JGLOBAL_SHOW_DATE_DESC="Show or hide a date column in the list of articles, or select which date you wish to show." JGLOBAL_SHOW_DATE_LABEL="Date" @@ -578,7 +578,7 @@ JGLOBAL_SHOW_NAVIGATION_DESC="If set to Show, shows a navigation link (Next, Pre JGLOBAL_SHOW_NAVIGATION_LABEL="Navigation" JGLOBAL_SHOW_PARENT_CATEGORY_DESC="If set to Show, the title of the article’s parent category will show." JGLOBAL_SHOW_PARENT_CATEGORY_LABEL="Parent" -JGLOBAL_SHOW_PUBLISH_DATE_DESC="If set to Show, the date and time an Article was published will be displayed. This is a global setting but can be changed at the Category, Menu and Article levels." +JGLOBAL_SHOW_PUBLISH_DATE_DESC="If set to Show, the date and time an Article was published will be displayed." JGLOBAL_SHOW_PUBLISH_DATE_LABEL="Publish Date" JGLOBAL_SHOW_READMORE_DESC="If set to Show, the Read more ...Link will show if Main text has been provided for the Article." JGLOBAL_SHOW_READMORE_LABEL=""Read More" Link" diff --git a/build/media_source/com_associations/js/sidebyside.es5.js b/build/media_source/com_associations/js/sidebyside.es5.js index 863706e509801..3f0166d4f2c12 100644 --- a/build/media_source/com_associations/js/sidebyside.es5.js +++ b/build/media_source/com_associations/js/sidebyside.es5.js @@ -257,7 +257,7 @@ jQuery(document).ready(function($) { var languageCode = reference.getAttribute('data-language').replace(/-/, '_'); var target = document.getElementById('target-association'); var targetTitle = target.getAttribute('data-title'); - var title = $(this).contents().find('#jform_' + targetTitle).val(); + var title = reference.getAttribute('data-title-value'); var target = $(this).contents(); // - For modal association selectors. diff --git a/build/media_source/com_templates/js/admin-template-toggle-assignment.es6.js b/build/media_source/com_templates/js/admin-template-toggle-assignment.es6.js index 0b23b34e5ff0b..a5c59c976a849 100644 --- a/build/media_source/com_templates/js/admin-template-toggle-assignment.es6.js +++ b/build/media_source/com_templates/js/admin-template-toggle-assignment.es6.js @@ -15,7 +15,7 @@ Joomla = window.Joomla || {}; }; Joomla.toggleMenutype = (a) => { - const checkBox = [].slice.call(document.getElementsByClassName(a)); + const checkBox = [].slice.call(document.getElementsByClassName(`menutype-${a}`)); const value = checkBox[0].checked; checkBox.forEach((element) => { element.checked = !value; diff --git a/build/media_source/legacy/js/joomla-chosen.es5.js b/build/media_source/legacy/js/joomla-chosen.es5.js index 86221dbcb522d..0338cf8b60a24 100644 --- a/build/media_source/legacy/js/joomla-chosen.es5.js +++ b/build/media_source/legacy/js/joomla-chosen.es5.js @@ -33,6 +33,7 @@ var return_value; return_value = JoomlaChosen.__super__.setup.apply(this, arguments); this.allow_custom_value = this.form_field_jq.hasClass("chosen-custom-value") || this.options.allow_custom_value; + this.custom_value_prefix = this.form_field_jq.attr("data-custom_value_prefix") || this.custom_value_prefix; return return_value; }; @@ -49,7 +50,7 @@ if (!this.result_highlight && (!this.is_multiple) && this.allow_custom_value) { value = this.search_field.val(); group = this.add_unique_custom_group(); - option = $(''); + option = $(''); group.append(option); this.form_field_jq.append(group); this.form_field.options[this.form_field.options.length - 1].selected = true; diff --git a/components/com_contact/Controller/ContactController.php b/components/com_contact/Controller/ContactController.php index a2d1846e3bfda..ac9ae6851052f 100644 --- a/components/com_contact/Controller/ContactController.php +++ b/components/com_contact/Controller/ContactController.php @@ -60,7 +60,6 @@ public function submit() $app = Factory::getApplication(); $model = $this->getModel('contact'); - $params = ComponentHelper::getParams('com_contact'); $stub = $this->input->getString('id'); $id = (int) $stub; @@ -105,7 +104,7 @@ public function submit() } // Check for a valid session cookie - if ($params->get('validate_session', 0)) + if ($contact->params->get('validate_session', 0)) { if (Factory::getSession()->getState() !== 'active') { @@ -174,9 +173,9 @@ public function submit() // Send the email $sent = false; - if (!$params->get('custom_reply')) + if (!$contact->params->get('custom_reply')) { - $sent = $this->_sendEmail($data, $contact, $params->get('show_email_copy', 0)); + $sent = $this->_sendEmail($data, $contact, $contact->params->get('show_email_copy', 0)); } // Set the success message if it was a success diff --git a/components/com_fields/forms/filter_fields.xml b/components/com_fields/forms/filter_fields.xml index 5ee502d040f78..ea44375f6f4dc 100644 --- a/components/com_fields/forms/filter_fields.xml +++ b/components/com_fields/forms/filter_fields.xml @@ -78,12 +78,12 @@ - - + + - - + + diff --git a/components/com_menus/Dispatcher/Dispatcher.php b/components/com_menus/Dispatcher/Dispatcher.php index a0f7c5faa5433..aea535fa72b1c 100644 --- a/components/com_menus/Dispatcher/Dispatcher.php +++ b/components/com_menus/Dispatcher/Dispatcher.php @@ -31,7 +31,6 @@ class Dispatcher extends ComponentDispatcher */ protected function loadLanguage() { - $this->app->getLanguage()->load('joomla', JPATH_ADMINISTRATOR); $this->app->getLanguage()->load('com_menus', JPATH_ADMINISTRATOR); } diff --git a/components/com_modules/Dispatcher/Dispatcher.php b/components/com_modules/Dispatcher/Dispatcher.php index 95de39486a2f3..8b9ddf2193537 100644 --- a/components/com_modules/Dispatcher/Dispatcher.php +++ b/components/com_modules/Dispatcher/Dispatcher.php @@ -31,7 +31,6 @@ class Dispatcher extends ComponentDispatcher */ protected function loadLanguage() { - $this->app->getLanguage()->load('joomla', JPATH_ADMINISTRATOR); $this->app->getLanguage()->load('com_modules', JPATH_ADMINISTRATOR); } diff --git a/components/com_tags/Model/TagModel.php b/components/com_tags/Model/TagModel.php index 467bf81d8bfb5..432bf235dffdb 100644 --- a/components/com_tags/Model/TagModel.php +++ b/components/com_tags/Model/TagModel.php @@ -188,7 +188,14 @@ protected function populateState($ordering = 'c.core_title', $direction = 'ASC') $this->setState('params', $params); // Load state from the request. - $ids = ArrayHelper::toInteger($app->input->get('id', array(), 'array')); + $ids = $app->input->get('id', array(), 'array'); + + if (count($ids) == 1) + { + $ids = explode(',', $ids[0]); + } + + $ids = ArrayHelper::toInteger($ids); $pkString = implode(',', $ids); diff --git a/language/en-GB/en-GB.ini b/language/en-GB/en-GB.ini index 1402215079f26..01d6fc272d0a8 100644 --- a/language/en-GB/en-GB.ini +++ b/language/en-GB/en-GB.ini @@ -55,11 +55,19 @@ JALL_LANGUAGE="All" JAPPLY="Save" JARCHIVED="Archived" JASSOCIATIONS="Also available:" +JASSOCIATIONS_ASC="Associations ascending" +JASSOCIATIONS_DESC="Associations descending" JAUTHOR="Author" +JAUTHOR_ASC="Author ascending" +JAUTHOR_DESC="Author descending" JCANCEL="Cancel" JCATEGORY="Category" +JCATEGORY_ASC="Category ascending" +JCATEGORY_DESC="Category descending" JCLEAR="Clear" JDATE="Date" +JDATE_ASC="Date ascending" +JDATE_DESC="Date descending" JDAY="Day" JDEFAULT="Default" JDETAILS="Details" @@ -69,6 +77,8 @@ JENABLED="Enabled" JEXPIRED="Expired" JFALSE="False" JFEATURED="Featured" +JFEATURED_ASC="Featured ascending" +JFEATURED_DESC="Featured descending" JHIDE="Hide" JINVALID_TOKEN="The most recent request was denied because it had an invalid security token. Please refresh the page and try again." JINVALID_TOKEN_NOTICE="The security token did not match. The request was aborted to prevent any security breach. Please try again." @@ -99,6 +109,8 @@ JSHOW="Show" JSITE="Site" JSITEADMIN="Select Site or Administrator" JSTATUS="Status" +JSTATUS_ASC="Status ascending" +JSTATUS_DESC="Status descending" JSUBMIT="Submit" JTAG="Tags" JTAG_FIELD_SELECT_DESC="Select the tag to use." @@ -225,8 +237,9 @@ JGLOBAL_FIELD_CREATED_LABEL="Created Date" JGLOBAL_FIELD_FEATURED_DESC="Assign the article to the featured blog layout." JGLOBAL_FIELD_FEATURED_LABEL="Featured" JGLOBAL_FIELD_FIELD_CACHETIME_DESC="The number of minutes before the cache is refreshed." -JGLOBAL_FIELD_FIELD_ORDERING_LABEL="Order" JGLOBAL_FIELD_FIELD_ORDERING_DESC="Order items will be displayed in." +JGLOBAL_FIELD_FIELD_ORDERING_LABEL="Order" +JGLOBAL_FIELD_GROUPS="Field Groups" JGLOBAL_FIELD_ID_DESC="Record number in the database." JGLOBAL_FIELD_ID_LABEL="ID" JGLOBAL_FIELD_LAYOUT_DESC="Default layout to use for items." @@ -253,12 +266,16 @@ JGLOBAL_GT=">" ; The following string is deprecated and will be removed with 4.0. JGLOBAL_HELPREFRESH_BUTTON="Refresh" JGLOBAL_HITS="Hits" +JGLOBAL_HITS_ASC="Hits ascending" JGLOBAL_HITS_COUNT="Hits: %s" +JGLOBAL_HITS_DESC="Hits descending" JGLOBAL_ICON_SEP="|" JGLOBAL_INHERIT="Inherit" JGLOBAL_INTRO_TEXT="Intro Text" JGLOBAL_KEEP_TYPING="Keep typing ..." JGLOBAL_LEFT="Left" +JGLOBAL_LIST_ALIAS="(Alias: %s)" +JGLOBAL_LIST_ALIAS_NOTE="(Alias: %s, Note: %s)" JGLOBAL_LOOKING_FOR="Looking for" JGLOBAL_LT="<" JGLOBAL_MAXIMUM_UPLOAD_SIZE_LIMIT="Maximum upload size: %s" @@ -284,10 +301,13 @@ JGLOBAL_SELECT_AN_OPTION="Select an option" JGLOBAL_SELECT_NO_RESULTS_MATCH="No results match" JGLOBAL_SELECT_PRESS_TO_SELECT="Press to select" JGLOBAL_SELECT_SOME_OPTIONS="Select some options" +JGLOBAL_SORT_BY="Sort Table By:" JGLOBAL_START_PUBLISH_AFTER_FINISH="Item start publishing date must be before finish publishing date" JGLOBAL_SUBCATEGORIES="Subcategories" JGLOBAL_SUBHEADING_DESC="Optional text to show as a subheading." JGLOBAL_TITLE="Title" +JGLOBAL_TITLE_ASC="Title ascending" +JGLOBAL_TITLE_DESC="Title descending" JGLOBAL_TYPE_OR_SELECT_CATEGORY="Type or Select a Category" JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS="Type or select some options" JGLOBAL_TYPE_OR_SELECT_SOME_TAGS="Type or select some tags" @@ -298,8 +318,16 @@ JGLOBAL_VALIDATION_FORM_FAILED="Invalid form" JGLOBAL_YOU_MUST_LOGIN_FIRST="Please login first" JGRID_HEADING_ACCESS="Access" +JGRID_HEADING_ACCESS_ASC="Access ascending" +JGRID_HEADING_ACCESS_DESC="Access descending" JGRID_HEADING_ID="ID" +JGRID_HEADING_ID_ASC="ID ascending" +JGRID_HEADING_ID_DESC="ID descending" JGRID_HEADING_LANGUAGE="Language" +JGRID_HEADING_LANGUAGE_ASC="Language ascending" +JGRID_HEADING_LANGUAGE_DESC="Language descending" +JGRID_HEADING_ORDERING_ASC="Ordering ascending" +JGRID_HEADING_ORDERING_DESC="Ordering descending" ; if there is an error connecting database before initialisation, en-GB.lib_joomla.ini can't be loaded ; we therefore have to load the strings from en-GB.ini diff --git a/libraries/src/Form/Form.php b/libraries/src/Form/Form.php index 6ae506025f576..4dedec92ceb13 100644 --- a/libraries/src/Form/Form.php +++ b/libraries/src/Form/Form.php @@ -1194,6 +1194,17 @@ public function validate($data, $group = null) foreach ($fields as $field) { $name = (string) $field['name']; + + // Define field name for messages + if ($field['label']) + { + $fieldLabel = \JText::_($field['label']); + } + else + { + $fieldLabel = \JText::_($name); + } + $disabled = ((string) $field['disabled'] == 'true' || (string) $field['disabled'] == 'disabled'); $fieldExistsInRequestData = $input->exists($name) || $input->exists($group . '.' . $name); @@ -1201,7 +1212,7 @@ public function validate($data, $group = null) // If the field is disabled but it is passed in the request this is invalid as disabled fields are not added to the request if ($disabled && $fieldExistsInRequestData) { - throw new \RuntimeException(Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $name)); + throw new \RuntimeException(Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $fieldLabel)); } // Get the field groups for the element. diff --git a/libraries/src/Form/FormField.php b/libraries/src/Form/FormField.php index ca30552033944..44a2df24230ef 100644 --- a/libraries/src/Form/FormField.php +++ b/libraries/src/Form/FormField.php @@ -1077,19 +1077,19 @@ public function validate($value, $group = null, \Joomla\Registry\Registry $input // Check if the field is required. $required = ((string) $this->element['required'] == 'true' || (string) $this->element['required'] == 'required'); + if ($this->element['label']) + { + $fieldLabel = Text::_($this->element['label']); + } + else + { + $fieldLabel = Text::_($this->element['name']); + } + // If the field is required and the value is empty return an error message. if ($required && (($value === '') || ($value === null))) { - if ($this->element['label']) - { - $message = Text::_($this->element['label']); - } - else - { - $message = Text::_($this->element['name']); - } - - $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_REQUIRED', $message); + $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_REQUIRED', $fieldLabel); return new \RuntimeException($message); } @@ -1162,8 +1162,7 @@ public function validate($value, $group = null, \Joomla\Registry\Registry $input } else { - $message = Text::_($this->element['label']); - $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $message); + $message = Text::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', $fieldLabel); } return new \UnexpectedValueException($message); diff --git a/libraries/src/Helper/ModuleHelper.php b/libraries/src/Helper/ModuleHelper.php index d892ff3173d85..4467f4bad2915 100644 --- a/libraries/src/Helper/ModuleHelper.php +++ b/libraries/src/Helper/ModuleHelper.php @@ -538,7 +538,10 @@ public static function moduleCache($module, $moduleparams, $cacheparams) ->createCacheController('callback', ['defaultgroup' => $cacheparams->cachegroup]); // Turn cache off for internal callers if parameters are set to off and for all logged in users - if ($moduleparams->get('owncache') === 0 || $moduleparams->get('owncache') === '0' || $app->get('caching') == 0 || $user->get('id')) + $ownCacheDisabled = $moduleparams->get('owncache') === 0 || $moduleparams->get('owncache') === '0'; + $cacheDisabled = $moduleparams->get('cache') === 0 || $moduleparams->get('cache') === '0'; + + if ($ownCacheDisabled || $cacheDisabled || $app->get('caching') == 0 || $user->get('id')) { $cache->setCaching(false); } diff --git a/libraries/src/MVC/Model/AdminModel.php b/libraries/src/MVC/Model/AdminModel.php index 6265ead079786..da393a1f983ef 100644 --- a/libraries/src/MVC/Model/AdminModel.php +++ b/libraries/src/MVC/Model/AdminModel.php @@ -426,6 +426,7 @@ protected function batchCopy($value, $pks, $contexts) } $newIds = array(); + $db = $this->getDbo(); // Parent exists so let's proceed while (!empty($pks)) @@ -453,6 +454,12 @@ protected function batchCopy($value, $pks, $contexts) } } + // Check for asset_id + if ($this->table->hasField($this->table->getColumnAlias('asset_id'))) + { + $oldAssetId = $this->table->asset_id; + } + $this->generateTitle($categoryId, $this->table); // Reset the ID because we are making a copy @@ -500,6 +507,21 @@ protected function batchCopy($value, $pks, $contexts) // Get the new item ID $newId = $this->table->get('id'); + if (!empty($oldAssetId)) + { + // Copy rules + $query = $db->getQuery(true); + $query->clear() + ->update($db->quoteName('#__assets', 't')) + ->join('INNER', $db->quoteName('#__assets', 's') . + ' ON ' . $db->quoteName('s.id') . ' = ' . $oldAssetId + ) + ->set($db->quoteName('t.rules') . ' = ' . $db->quoteName('s.rules')) + ->where($db->quoteName('t.id') . ' = ' . $this->table->asset_id); + + $db->setQuery($query)->execute(); + } + $this->cleanupPostBatchCopy($this->table, $newId, $pk); // Add the new ID to the array diff --git a/libraries/src/Router/Route.php b/libraries/src/Router/Route.php index 3e14ca46ea168..96fe67a16eb73 100644 --- a/libraries/src/Router/Route.php +++ b/libraries/src/Router/Route.php @@ -10,6 +10,7 @@ defined('JPATH_PLATFORM') or die; +use Joomla\CMS\Log\Log; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Uri\Uri; @@ -75,6 +76,18 @@ public static function _($url, $xhtml = true, $tls = self::TLS_IGNORE, $absolute $tls = self::TLS_DISABLE; } + // @deprecated 4.0 Before 3.9.7 this method silently converted $tls to integer + if (!is_int($tls)) + { + Log::add( + __METHOD__ . '() called with incompatible variable type on parameter $tls.', + Log::WARNING, + 'deprecated' + ); + + $tls = (int) $tls; + } + $app = Factory::getApplication(); $client = $app->getName(); diff --git a/libraries/src/Schema/ChangeItem/MysqlChangeItem.php b/libraries/src/Schema/ChangeItem/MysqlChangeItem.php index 947660a10a224..86451b19dac34 100644 --- a/libraries/src/Schema/ChangeItem/MysqlChangeItem.php +++ b/libraries/src/Schema/ChangeItem/MysqlChangeItem.php @@ -294,32 +294,30 @@ private function fixQuote($string) */ private function fixUtf8mb4TypeChecks($type) { - $fixedType = str_replace(';', '', $type); + $uType = strtoupper(str_replace(';', '', $type)); if ($this->db instanceof UTF8MB4SupportInterface && $this->db->hasUTF8mb4Support()) { - $uType = strtoupper($fixedType); - if ($uType === 'TINYTEXT') { - $typeCheck = 'type IN (' . $this->db->quote('TINYTEXT') . ',' . $this->db->quote('TEXT') . ')'; + $typeCheck = 'UPPER(type) IN (' . $this->db->quote('TINYTEXT') . ',' . $this->db->quote('TEXT') . ')'; } elseif ($uType === 'TEXT') { - $typeCheck = 'type IN (' . $this->db->quote('TEXT') . ',' . $this->db->quote('MEDIUMTEXT') . ')'; + $typeCheck = 'UPPER(type) IN (' . $this->db->quote('TEXT') . ',' . $this->db->quote('MEDIUMTEXT') . ')'; } elseif ($uType === 'MEDIUMTEXT') { - $typeCheck = 'type IN (' . $this->db->quote('MEDIUMTEXT') . ',' . $this->db->quote('LONGTEXT') . ')'; + $typeCheck = 'UPPER(type) IN (' . $this->db->quote('MEDIUMTEXT') . ',' . $this->db->quote('LONGTEXT') . ')'; } else { - $typeCheck = 'type = ' . $this->db->quote($fixedType); + $typeCheck = 'UPPER(type) = ' . $this->db->quote($uType); } } else { - $typeCheck = 'type = ' . $this->db->quote($fixedType); + $typeCheck = 'UPPER(type) = ' . $this->db->quote($uType); } return $typeCheck; diff --git a/libraries/src/Table/Table.php b/libraries/src/Table/Table.php index 0fca1671a359f..0b4bfa329d874 100644 --- a/libraries/src/Table/Table.php +++ b/libraries/src/Table/Table.php @@ -2004,7 +2004,7 @@ protected function _unlock() * * @return boolean * - * @since 4.0.0 + * @since 3.9.11 */ public function hasField($key) { diff --git a/modules/mod_tags_popular/Helper/TagsPopularHelper.php b/modules/mod_tags_popular/Helper/TagsPopularHelper.php index 2e99686d6cf5f..9a4e15fd76b56 100644 --- a/modules/mod_tags_popular/Helper/TagsPopularHelper.php +++ b/modules/mod_tags_popular/Helper/TagsPopularHelper.php @@ -95,8 +95,9 @@ public static function getList(&$params) $query->where($db->quoteName('m.type_alias') . ' = ' . $db->quoteName('c.core_type_alias')); - // Only return tags connected to published articles + // Only return tags connected to published and authorised items $query->where($db->quoteName('c.core_state') . ' = 1') + ->where($db->quoteName('c.core_access') . ' IN (' . $groups . ')') ->where('(' . $db->quoteName('c.core_publish_up') . ' = :nullDate2' . ' OR ' . $db->quoteName('c.core_publish_up') . ' <= :nowDate2)' ) diff --git a/plugins/system/actionlogs/actionlogs.php b/plugins/system/actionlogs/actionlogs.php index be569928739cc..5692687f8ab65 100644 --- a/plugins/system/actionlogs/actionlogs.php +++ b/plugins/system/actionlogs/actionlogs.php @@ -357,7 +357,7 @@ public function onUserAfterSave($user, $isNew, $success, $msg) } // Clear access rights in case user groups were changed. - $userObject = Factory::getUser($user['id']); + $userObject = new User($user['id']); $userObject->clearAccessRights(); $authorised = $userObject->authorise('core.admin'); diff --git a/plugins/system/fields/fields.php b/plugins/system/fields/fields.php index 7f3906c090be4..886331096b167 100644 --- a/plugins/system/fields/fields.php +++ b/plugins/system/fields/fields.php @@ -59,6 +59,13 @@ public function onContentNormaliseRequestData($context, $data, Form $form) * they should NEVER be added by the browser anyway so nothing to check against * as "disabled" means no interaction at all. */ + + // Make sure the data object has an entry before delete it + if (isset($data->com_fields[$field->fieldname])) + { + unset($data->com_fields[$field->fieldname]); + } + continue; }