diff --git a/.appveyor.yml b/.appveyor.yml index 8c9d63f014549..174e9e52c96b2 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -30,7 +30,7 @@ services: ## Install PHP and composer, and run the appropriate composer command install: - IF EXIST C:\tools\php (SET PHP=0) - # TODO: This is a workaround for https://github.com/chocolatey/choco/issues/1843. Once this is fixed we + # @todo: This is a workaround for https://github.com/chocolatey/choco/issues/1843. Once this is fixed we # should go back to latest version in appveyor saving ourselves test time - ps: choco upgrade chocolatey -y --version 0.10.13 --allow-downgrade --no-progress - ps: >- diff --git a/.drone.yml b/.drone.yml index 8b15c95c4d2f0..076b5064f8977 100644 --- a/.drone.yml +++ b/.drone.yml @@ -182,19 +182,20 @@ steps: commands: - bash tests/Codeception/drone-api-run.sh "$(pwd)" mysql - - name: phpnext-api-mysql - depends_on: - - phpmin-api-mysql - image: joomlaprojects/docker-images:systemtests8.2 - failure: ignore - environment: - JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 - commands: - - bash tests/Codeception/drone-api-run.sh "$(pwd)" mysqlphpnext +# - name: phpnext-api-mysql +# depends_on: +# - phpmin-api-mysql +# image: joomlaprojects/docker-images:systemtests8.2 +# failure: ignore +# environment: +# JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 +# commands: +# - bash tests/Codeception/drone-api-run.sh "$(pwd)" mysqlphpnext - name: phpmin-api-postgres depends_on: - - phpnext-api-mysql + # - phpnext-api-mysql + - phpmin-api-mysql image: joomlaprojects/docker-images:systemtests failure: ignore environment: @@ -202,19 +203,20 @@ steps: commands: - bash tests/Codeception/drone-api-run.sh "$(pwd)" postgres - - name: phpnext-api-postgres - depends_on: - - phpmin-api-postgres - image: joomlaprojects/docker-images:systemtests8.2 - failure: ignore - environment: - JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 - commands: - - bash tests/Codeception/drone-api-run.sh "$(pwd)" postgresphpnext +# - name: phpnext-api-postgres +# depends_on: +# - phpmin-api-postgres +# image: joomlaprojects/docker-images:systemtests8.2 +# failure: ignore +# environment: +# JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 +# commands: +# - bash tests/Codeception/drone-api-run.sh "$(pwd)" postgresphpnext - name: phpmax-api-postgres depends_on: - - phpnext-api-postgres +# - phpnext-api-postgres + - phpmin-api-postgres image: joomlaprojects/docker-images:systemtests8.1 failure: ignore environment: @@ -233,17 +235,20 @@ steps: commands: - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysql - - name: phpnext-system-mysql - depends_on: [ phpmin-system-mysql ] - image: joomlaprojects/docker-images:systemtests8.2 - failure: ignore - environment: - JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 - commands: - - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysqlphpnext +# - name: phpnext-system-mysql +# depends_on: +# - phpmin-system-mysql +# image: joomlaprojects/docker-images:systemtests8.2 +# failure: ignore +# environment: +# JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 +# commands: +# - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysqlphpnext - name: phpmax-system-mysql - depends_on: [ phpnext-system-mysql ] + depends_on: +# - phpnext-system-mysql + - phpmin-system-mysql image: joomlaprojects/docker-images:systemtests8.1 failure: ignore environment: @@ -251,17 +256,20 @@ steps: commands: - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysqlphpmax - - name: phpnext-system-mysql8 - depends_on: [ phpmax-system-mysql ] - image: joomlaprojects/docker-images:systemtests8.2 - failure: ignore - environment: - JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 - commands: - - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysql8phpnext +# - name: phpnext-system-mysql8 +# depends_on: +# - phpmax-system-mysql +# image: joomlaprojects/docker-images:systemtests8.2 +# failure: ignore +# environment: +# JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 +# commands: +# - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysql8phpnext - name: phpmax-system-mysql8 - depends_on: [ phpnext-system-mysql ] + depends_on: +# - phpnext-system-mysql + - phpmax-system-mysql image: joomlaprojects/docker-images:systemtests8.1 failure: ignore environment: @@ -269,17 +277,20 @@ steps: commands: - bash tests/Codeception/drone-system-run.sh "$(pwd)" mysql8phpmax - - name: phpnext-system-postgres - depends_on: [ phpmax-system-mysql8 ] - image: joomlaprojects/docker-images:systemtests8.2 - failure: ignore - environment: - JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 - commands: - - bash tests/Codeception/drone-system-run.sh "$(pwd)" postgresphpnext +# - name: phpnext-system-postgres +# depends_on: +# - phpmax-system-mysql8 +# image: joomlaprojects/docker-images:systemtests8.2 +# failure: ignore +# environment: +# JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1 +# commands: +# - bash tests/Codeception/drone-system-run.sh "$(pwd)" postgresphpnext - name: phpmax-system-postgres - depends_on: [ phpnext-system-mysql8 ] + depends_on: +# - phpnext-system-mysql8 + - phpmax-system-mysql8 image: joomlaprojects/docker-images:systemtests8.1 failure: ignore environment: @@ -306,17 +317,17 @@ steps: - name: artifacts-system-tests image: cschlosser/drone-ftps depends_on: - - phpnext-system-mysql - - phpnext-system-mysql8 - - phpnext-system-postgres +# - phpnext-system-mysql +# - phpnext-system-mysql8 +# - phpnext-system-postgres - phpmax-system-mysql - phpmax-system-mysql8 - phpmax-system-postgres - phpmin-system-mysql - phpmin-system-mysql8 - phpmin-system-postgres - - phpnext-api-mysql - - phpnext-api-postgres +# - phpnext-api-mysql +# - phpnext-api-postgres - phpmax-api-mysql - phpmax-api-postgres - phpmin-api-mysql @@ -409,6 +420,6 @@ steps: --- kind: signature -hmac: e93522732dd8607448fa7705982c42c06f9ebf9762023ed1bb2207ee975fee42 +hmac: daa8e5588cc88058bc57aadf35e3d9dd55eefaa9419c457ce374a0dd19eb7cda ... diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index 54e4967630255..9b7df3f8b6684 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -6112,7 +6112,7 @@ public function deleteUnexistingFiles($dryRun = false, $suppressOutput = false) '/media/vendor/codemirror/lib/#codemirror.js#', // From 4.0.5 to 4.0.6 '/media/vendor/mediaelement/css/mejs-controls.png', - // From 4.0.x to 4.1.0 + // From 4.0.x to 4.1.0-beta1 '/administrator/templates/atum/css/system/searchtools/searchtools.css', '/administrator/templates/atum/css/system/searchtools/searchtools.min.css', '/administrator/templates/atum/css/system/searchtools/searchtools.min.css.gz', @@ -6327,6 +6327,8 @@ public function deleteUnexistingFiles($dryRun = false, $suppressOutput = false) '/templates/system/scss/general.scss', '/templates/system/scss/offline.scss', '/templates/system/scss/offline_rtl.scss', + // From 4.1.0-beta3 to 4.1.0-rc1 + '/api/components/com_media/src/Helper/AdapterTrait.php', ); $folders = array( @@ -7586,7 +7588,7 @@ public function deleteUnexistingFiles($dryRun = false, $suppressOutput = false) '/libraries/vendor/algo26-matthias/idna-convert/tests', // From 4.0.3 to 4.0.4 '/templates/cassiopeia/images/system', - // From 4.0.5 to 4.1.0 + // From 4.0.x to 4.1.0-beta1 '/templates/system/scss', '/templates/system/css', '/templates/cassiopeia/scss/vendor/metismenu', @@ -7637,6 +7639,8 @@ public function deleteUnexistingFiles($dryRun = false, $suppressOutput = false) '/administrator/templates/atum/css/system/searchtools', '/administrator/templates/atum/css/system', '/administrator/templates/atum/css', + // From 4.1.0-beta3 to 4.1.0-rc1 + '/api/components/com_media/src/Helper', ); $status['files_checked'] = $files; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-11-20.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-11-20.sql index 93edfa3968f84..a1ae75ba0b248 100644 --- a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-11-20.sql +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2021-11-20.sql @@ -59,5 +59,5 @@ INSERT INTO `#__action_log_config` (`type_title`, `type_alias`, `id_holder`, `ti INSERT INTO `#__mail_templates` (`template_id`, `extension`, `language`, `subject`, `body`, `htmlbody`, `attachments`, `params`) VALUES ('plg_system_tasknotification.failure_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title", "exit_code", "exec_data_time", "task_output"]}'), ('plg_system_tasknotification.fatal_recovery_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title"]}'), -('plg_system_tasknotification.orphan_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title", ""]}'), +('plg_system_tasknotification.orphan_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title"]}'), ('plg_system_tasknotification.success_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_BODY', '', '', '{"tags":["task_id", "task_title", "exec_data_time", "task_output"]}'); diff --git a/administrator/components/com_admin/sql/updates/mysql/4.1.0-2022-01-08.sql b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2022-01-08.sql new file mode 100644 index 0000000000000..62e70589f01f3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.1.0-2022-01-08.sql @@ -0,0 +1,3 @@ +UPDATE `#__mail_templates` + SET `params` = '{"tags": ["task_id", "task_title"]}' + WHERE `template_id`= 'plg_system_tasknotification.orphan_mail' AND `params` = '{"tags": ["task_id", "task_title", ""]}'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-11-20.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-11-20.sql index fa299c626cd8e..02ab2e7033278 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-11-20.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2021-11-20.sql @@ -60,5 +60,5 @@ INSERT INTO "#__action_log_config" ("type_title", "type_alias", "id_holder", "ti INSERT INTO "#__mail_templates" ("template_id", "extension", "language", "subject", "body", "htmlbody", "attachments", "params") VALUES ('plg_system_tasknotification.failure_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title", "exit_code", "exec_data_time", "task_output"]}'), ('plg_system_tasknotification.fatal_recovery_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title"]}'), -('plg_system_tasknotification.orphan_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title", ""]}'), +('plg_system_tasknotification.orphan_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_BODY', '', '', '{"tags": ["task_id", "task_title"]}'), ('plg_system_tasknotification.success_mail', 'plg_system_tasknotification', '', 'PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_SUBJECT', 'PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_BODY', '', '', '{"tags":["task_id", "task_title", "exec_data_time", "task_output"]}'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2022-01-08.sql b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2022-01-08.sql new file mode 100644 index 0000000000000..962e149a86948 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.1.0-2022-01-08.sql @@ -0,0 +1,3 @@ +UPDATE "#__mail_templates" + SET "params" = '{"tags": ["task_id", "task_title"]}' + WHERE "template_id"= 'plg_system_tasknotification.orphan_mail' AND "params" = '{"tags": ["task_id", "task_title", ""]}'; diff --git a/administrator/components/com_banners/tmpl/clients/default.php b/administrator/components/com_banners/tmpl/clients/default.php index 27f0d737f6a44..fc7e5392d1479 100644 --- a/administrator/components/com_banners/tmpl/clients/default.php +++ b/administrator/components/com_banners/tmpl/clients/default.php @@ -123,20 +123,40 @@ contact; ?> - - count_published; ?> + + count_published; ?> + + - - count_unpublished; ?> + + count_unpublished; ?> + + - - count_archived; ?> + + count_archived; ?> + + - - count_trashed; ?> + + count_trashed; ?> + + purchase_type < 0) : ?> diff --git a/administrator/components/com_categories/tmpl/category/edit.php b/administrator/components/com_categories/tmpl/category/edit.php index 26dfa454f4ac8..448b4a18d5832 100644 --- a/administrator/components/com_categories/tmpl/category/edit.php +++ b/administrator/components/com_categories/tmpl/category/edit.php @@ -124,6 +124,7 @@ form->getInput('extension'); ?> + diff --git a/administrator/components/com_config/src/Field/FiltersField.php b/administrator/components/com_config/src/Field/FiltersField.php index 328300440cd5a..bd93d5cdef376 100644 --- a/administrator/components/com_config/src/Field/FiltersField.php +++ b/administrator/components/com_config/src/Field/FiltersField.php @@ -34,7 +34,7 @@ class FiltersField extends FormField /** * Method to get the field input markup. * - * TODO: Add access check. + * @todo: Add access check. * * @return string The field input markup. * diff --git a/administrator/components/com_contact/src/Model/ContactsModel.php b/administrator/components/com_contact/src/Model/ContactsModel.php index cd24dc0066e37..edd39679a2c98 100644 --- a/administrator/components/com_contact/src/Model/ContactsModel.php +++ b/administrator/components/com_contact/src/Model/ContactsModel.php @@ -346,7 +346,7 @@ protected function getListQuery() $categoryTable = Table::getInstance('Category', 'JTable'); $subCatItemsWhere = array(); - // TODO: Convert to prepared statement + // @todo: Convert to prepared statement foreach ($categoryId as $filter_catid) { $categoryTable->load($filter_catid); diff --git a/administrator/components/com_contact/src/View/Contacts/HtmlView.php b/administrator/components/com_contact/src/View/Contacts/HtmlView.php index ff8aee3ab133a..a03a9a060d153 100644 --- a/administrator/components/com_contact/src/View/Contacts/HtmlView.php +++ b/administrator/components/com_contact/src/View/Contacts/HtmlView.php @@ -98,7 +98,7 @@ public function display($tpl = null) } // Preprocess the list of items to find ordering divisions. - // TODO: Complete the ordering stuff with nested sets + // @todo: Complete the ordering stuff with nested sets foreach ($this->items as &$item) { $item->order_up = true; diff --git a/administrator/components/com_content/forms/article.xml b/administrator/components/com_content/forms/article.xml index a71ec8438528c..6c9189d19404f 100644 --- a/administrator/components/com_content/forms/article.xml +++ b/administrator/components/com_content/forms/article.xml @@ -909,7 +909,7 @@
+ label="JGLOBAL_FIELDSET_METADATA_OPTIONS"> + urls); $item->urls = $registry->toArray(); - $item->articletext = trim($item->fulltext) != '' ? $item->introtext . "
" . $item->fulltext : $item->introtext; + $item->articletext = ($item->fulltext !== null && trim($item->fulltext) != '') ? $item->introtext . "
" . $item->fulltext : $item->introtext; if (!empty($item->id)) { @@ -499,7 +499,9 @@ public function getForm($data = array(), $loadData = true) $record = new \stdClass; // Get ID of the article from input, for frontend, we use a_id while backend uses id - $articleIdFromInput = (int) $app->input->getInt('a_id') ?: $app->input->getInt('id', 0); + $articleIdFromInput = $app->isClient('site') + ? $app->input->getInt('a_id', 0) + : $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); diff --git a/administrator/components/com_content/src/Model/ArticlesModel.php b/administrator/components/com_content/src/Model/ArticlesModel.php index ea629cbb71fb6..963f489807665 100644 --- a/administrator/components/com_content/src/Model/ArticlesModel.php +++ b/administrator/components/com_content/src/Model/ArticlesModel.php @@ -352,7 +352,7 @@ protected function getListQuery() // Filter by featured. $featured = (string) $this->getState('filter.featured'); - if (in_array($featured, ['0','1'])) + if (\in_array($featured, ['0','1'])) { $featured = (int) $featured; $query->where($db->quoteName('a.featured') . ' = :featured') @@ -462,6 +462,14 @@ protected function getListQuery() } elseif (is_array($authorId)) { + // Check to see if by_me is in the array + if (\in_array('by_me', $authorId)) + + // Replace by_me with the current user id in the array + { + $authorId['by_me'] = $user->id; + } + $authorId = ArrayHelper::toInteger($authorId); $query->whereIn($db->quoteName('a.created_by'), $authorId); } diff --git a/administrator/components/com_content/tmpl/articles/default.xml b/administrator/components/com_content/tmpl/articles/default.xml index 79885752f859c..c0f6b39be802d 100644 --- a/administrator/components/com_content/tmpl/articles/default.xml +++ b/administrator/components/com_content/tmpl/articles/default.xml @@ -43,9 +43,10 @@ multiple="true" layout="joomla.form.field.list-fancy-select" class="multipleAuthors" - filter="intarray" + filter="array" > +
input->getCmd('dashboard'); + $dashboard = $app->input->getCmd('dashboard', ''); $position = ApplicationHelper::stringURLSafe($dashboard); diff --git a/administrator/components/com_fields/src/Plugin/FieldsPlugin.php b/administrator/components/com_fields/src/Plugin/FieldsPlugin.php index 2c674e5a06cef..a77e45fda7172 100644 --- a/administrator/components/com_fields/src/Plugin/FieldsPlugin.php +++ b/administrator/components/com_fields/src/Plugin/FieldsPlugin.php @@ -200,6 +200,11 @@ public function onCustomFieldsPrepareDom($field, \DOMElement $parent, Form $form $node->setAttribute('hint', $field->params->get('hint', '')); $node->setAttribute('required', $field->required ? 'true' : 'false'); + if ($layout = $field->params->get('form_layout')) + { + $node->setAttribute('layout', $layout); + } + if ($field->default_value !== '') { $defaultNode = $node->appendChild(new \DOMElement('default')); diff --git a/administrator/components/com_finder/src/Indexer/Helper.php b/administrator/components/com_finder/src/Indexer/Helper.php index 49de78ca1ed57..fc3f13ab97794 100644 --- a/administrator/components/com_finder/src/Indexer/Helper.php +++ b/administrator/components/com_finder/src/Indexer/Helper.php @@ -112,7 +112,7 @@ public static function tokenize($input, $lang, $phrase = false) $tokens = array(); $terms = $language->tokenise($input); - // TODO: array_filter removes any number 0's from the terms. Not sure this is entirely intended + // @todo: array_filter removes any number 0's from the terms. Not sure this is entirely intended $terms = array_filter($terms); $terms = array_values($terms); diff --git a/administrator/components/com_finder/src/Indexer/Query.php b/administrator/components/com_finder/src/Indexer/Query.php index 952dddb0cc169..0f867f2043e48 100644 --- a/administrator/components/com_finder/src/Indexer/Query.php +++ b/administrator/components/com_finder/src/Indexer/Query.php @@ -1004,7 +1004,7 @@ protected function processString($input, $lang, $mode) // Tokenize the current term. $token = Helper::tokenize($terms[$i], $lang, true); - // Todo: The previous function call may return an array, which seems not to be handled by the next one, which expects an object + // @todo: The previous function call may return an array, which seems not to be handled by the next one, which expects an object $token = $this->getTokenData(array_shift($token)); if ($params->get('filter_commonwords', 0) && $token->common) diff --git a/administrator/components/com_finder/src/Indexer/Taxonomy.php b/administrator/components/com_finder/src/Indexer/Taxonomy.php index 297b26b573437..c19653cb52443 100644 --- a/administrator/components/com_finder/src/Indexer/Taxonomy.php +++ b/administrator/components/com_finder/src/Indexer/Taxonomy.php @@ -188,7 +188,7 @@ protected static function storeNode($node, $parentId) * The database did not match the input. This could be because the * state has changed or because the node does not exist. Let's figure * out which case is true and deal with it. - * TODO: use factory? + * @todo: use factory? */ $nodeTable = new MapTable($db); diff --git a/administrator/components/com_installer/src/Controller/InstallController.php b/administrator/components/com_installer/src/Controller/InstallController.php index af365d779415e..bf972409ed1a1 100644 --- a/administrator/components/com_installer/src/Controller/InstallController.php +++ b/administrator/components/com_installer/src/Controller/InstallController.php @@ -46,7 +46,7 @@ public function install() /** @var \Joomla\Component\Installer\Administrator\Model\InstallModel $model */ $model = $this->getModel('install'); - // TODO: Reset the users acl here as well to kill off any missing bits. + // @todo: Reset the users acl here as well to kill off any missing bits. $result = $model->install(); $app = $this->app; diff --git a/administrator/components/com_installer/src/Model/DiscoverModel.php b/administrator/components/com_installer/src/Model/DiscoverModel.php index 17dcd4495964a..681874a9892b5 100644 --- a/administrator/components/com_installer/src/Model/DiscoverModel.php +++ b/administrator/components/com_installer/src/Model/DiscoverModel.php @@ -242,7 +242,7 @@ public function discover_install() } } - // TODO - We are only receiving the message for the last Installer instance + // @todo - We are only receiving the message for the last Installer instance $this->setState('action', 'remove'); $this->setState('name', $installer->get('name')); $app->setUserState('com_installer.message', $installer->message); diff --git a/administrator/components/com_installer/src/Model/ManageModel.php b/administrator/components/com_installer/src/Model/ManageModel.php index 310fa733536f8..7d43ecc26dd4e 100644 --- a/administrator/components/com_installer/src/Model/ManageModel.php +++ b/administrator/components/com_installer/src/Model/ManageModel.php @@ -118,7 +118,7 @@ public function publish(&$eid = array(), $value = 1) /* * Ensure eid is an array of extension ids - * TODO: If it isn't an array do we want to set an error and fail? + * @todo: If it isn't an array do we want to set an error and fail? */ if (!is_array($eid)) { @@ -234,7 +234,7 @@ public function remove($eid = array()) /* * Ensure eid is an array of extension ids in the form id => client_id - * TODO: If it isn't an array do we want to set an error and fail? + * @todo: If it isn't an array do we want to set an error and fail? */ if (!is_array($eid)) { diff --git a/administrator/components/com_installer/src/Model/UpdateModel.php b/administrator/components/com_installer/src/Model/UpdateModel.php index 799779cef8079..15e0e17c4736b 100644 --- a/administrator/components/com_installer/src/Model/UpdateModel.php +++ b/administrator/components/com_installer/src/Model/UpdateModel.php @@ -508,7 +508,7 @@ private function install($update) // Quick change $this->type = $package['type']; - // TODO: Reconfigure this code when you have more battery life left + // @todo: Reconfigure this code when you have more battery life left $this->setState('name', $installer->get('name')); $this->setState('result', $result); $app->setUserState('com_installer.message', $installer->message); diff --git a/administrator/components/com_installer/src/Model/WarningsModel.php b/administrator/components/com_installer/src/Model/WarningsModel.php index 395add43e35ad..ff3d20e5d1ce5 100644 --- a/administrator/components/com_installer/src/Model/WarningsModel.php +++ b/administrator/components/com_installer/src/Model/WarningsModel.php @@ -98,76 +98,99 @@ public function getItems() $messages = []; // 16MB - $minMemory = 16 * 1024 * 1024; + $minLimit = 16 * 1024 * 1024; $file_uploads = ini_get('file_uploads'); if (!$file_uploads) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC')); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC'), + ]; } $upload_dir = ini_get('upload_tmp_dir'); if (!$upload_dir) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC')); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC'), + ]; } elseif (!is_writable($upload_dir)) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE'), - 'description' => Text::sprintf('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC', $upload_dir)); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE'), + 'description' => Text::sprintf('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC', $upload_dir), + ]; } $tmp_path = Factory::getApplication()->get('tmp_path'); if (!$tmp_path) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC')); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC'), + ]; } elseif (!is_writable($tmp_path)) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE'), - 'description' => Text::sprintf('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC', $tmp_path)); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE'), + 'description' => Text::sprintf('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC', $tmp_path), + ]; } $memory_limit = $this->return_bytes(ini_get('memory_limit')); - if ($memory_limit < $minMemory && $memory_limit != -1) + if ($memory_limit > -1) { - // 16MB - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC')); - } - elseif ($memory_limit < ($minMemory * 1.5) && $memory_limit != -1) - { - // 24MB - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC')); + if ($memory_limit < $minLimit) + { + // 16MB + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC'), + ]; + } + elseif ($memory_limit < ($minLimit * 1.5)) + { + // 24MB + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC'), + ]; + } } - $post_max_size = $this->return_bytes(ini_get('post_max_size')); + $post_max_size = $this->return_bytes(ini_get('post_max_size')); $upload_max_filesize = $this->return_bytes(ini_get('upload_max_filesize')); - if ($post_max_size < $upload_max_filesize) + if ($post_max_size > 0 && $post_max_size < $upload_max_filesize) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC')); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC'), + ]; } - if ($post_max_size < $minMemory) + if ($post_max_size > 0 && $post_max_size < $minLimit) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC')); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC'), + ]; } - if ($upload_max_filesize < $minMemory) + if ($upload_max_filesize > 0 && $upload_max_filesize < $minLimit) { - $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), - 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC')); + $messages[] = [ + 'message' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC'), + ]; } return $messages; diff --git a/administrator/components/com_joomlaupdate/extract.php b/administrator/components/com_joomlaupdate/extract.php index 549206777f89d..c59dc7b01625f 100644 --- a/administrator/components/com_joomlaupdate/extract.php +++ b/administrator/components/com_joomlaupdate/extract.php @@ -525,7 +525,7 @@ public function enforceMinimumExecutionTime() return; } - $sleepMillisec = $minExecTime - $elapsed; + $sleepMillisec = intval($minExecTime - $elapsed); /** * If we need to sleep for more than 1 second we should be using sleep() or time_sleep_until() to prevent high diff --git a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php index bb3ef52db9b6c..5f33eaed2141d 100644 --- a/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php +++ b/administrator/components/com_joomlaupdate/src/Model/UpdateModel.php @@ -72,7 +72,7 @@ public function applyUpdateSite() break; // "Custom" - // TODO: check if the customurl is valid and not just "not empty". + // @todo: check if the customurl is valid and not just "not empty". case 'custom': if (trim($params->get('customurl', '')) != '') { @@ -1082,7 +1082,7 @@ public function removePackageFiles() /** * Gets PHP options. - * TODO: Outsource, build common code base for pre install and pre update check + * @todo: Outsource, build common code base for pre install and pre update check * * @return array Array of PHP config options * @@ -1174,7 +1174,7 @@ public function getPhpOptions() /** * Gets PHP Settings. - * TODO: Outsource, build common code base for pre install and pre update check + * @todo: Outsource, build common code base for pre install and pre update check * * @return array * @@ -1312,7 +1312,7 @@ private function getTargetMinimumPHPVersion() /** * Checks the availability of the parse_ini_file and parse_ini_string functions. - * TODO: Outsource, build common code base for pre install and pre update check + * @todo: Outsource, build common code base for pre install and pre update check * * @return boolean True if the method exists. * @@ -1706,7 +1706,7 @@ private function checkCompatibility($updateFileUrl, $joomlaTargetVersion) */ protected function translateExtensionName(&$item) { - // ToDo: Cleanup duplicated code. from com_installer/models/extension.php + // @todo: Cleanup duplicated code. from com_installer/models/extension.php $lang = Factory::getLanguage(); $path = $item->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE; diff --git a/administrator/components/com_joomlaupdate/src/View/Joomlaupdate/HtmlView.php b/administrator/components/com_joomlaupdate/src/View/Joomlaupdate/HtmlView.php index 4d171af9c3512..f116aa9e65063 100644 --- a/administrator/components/com_joomlaupdate/src/View/Joomlaupdate/HtmlView.php +++ b/administrator/components/com_joomlaupdate/src/View/Joomlaupdate/HtmlView.php @@ -296,6 +296,12 @@ protected function addToolbar() */ public function shouldDisplayPreUpdateCheck() { + // When the download URL is not found there is no core upgrade path + if (!isset($this->updateInfo['object']->downloadurl->_data)) + { + return false; + } + $nextMinor = Version::MAJOR_VERSION . '.' . (Version::MINOR_VERSION + 1); // Show only when we found a download URL, we have an update and when we update to the next minor or greater. 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 fc9a556b91056..ad117dc1ade50 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 @@ -69,7 +69,7 @@ export default { }, /* Edit an item */ editItem() { - // TODO should we use relative urls here? + // @todo should we use relative urls here? const fileBaseUrl = `${Joomla.getOptions('com_media').editViewUrl}&path=`; window.location.href = fileBaseUrl + this.item.path; diff --git a/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue index 23d77836120ca..c2302dd67d6c0 100644 --- a/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue +++ b/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue @@ -79,8 +79,8 @@ export default { save() { // Check if the form is valid if (!this.isValid()) { - // TODO show an error message to user for insert a folder name - // TODO mark the field as invalid + // @todo show an error message to user for insert a folder name + // @todo mark the field as invalid return; } diff --git a/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue index 978d3dd4142ac..4d3bee44458cc 100644 --- a/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue +++ b/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue @@ -101,7 +101,7 @@ export default { save() { // Check if the form is valid if (!this.isValid()) { - // TODO mark the field as invalid + // @todo mark the field as invalid return; } let newName = this.$refs.nameField.value; diff --git a/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue index 0842b51eab5eb..12ceac1e2616d 100644 --- a/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue +++ b/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue @@ -107,7 +107,7 @@ export default { try { document.execCommand('copy'); } catch (err) { - // TODO Error handling in joomla way + // @todo Error handling in joomla way // eslint-disable-next-line no-undef alert(translate('COM_MEDIA_SHARE_COPY_FAILED_ERROR')); } diff --git a/administrator/components/com_media/resources/scripts/store/actions.es6.js b/administrator/components/com_media/resources/scripts/store/actions.es6.js index c14752396b3ec..58db65fc97919 100644 --- a/administrator/components/com_media/resources/scripts/store/actions.es6.js +++ b/administrator/components/com_media/resources/scripts/store/actions.es6.js @@ -38,7 +38,7 @@ export const getContents = (context, payload) => { context.commit(types.SET_IS_LOADING, false); }) .catch((error) => { - // TODO error handling + // @todo error handling context.commit(types.SET_IS_LOADING, false); // eslint-disable-next-line no-console console.log('error', error); @@ -58,7 +58,7 @@ export const getFullContents = (context, payload) => { context.commit(types.SET_IS_LOADING, false); }) .catch((error) => { - // TODO error handling + // @todo error handling context.commit(types.SET_IS_LOADING, false); // eslint-disable-next-line no-console console.log('error', error); @@ -137,7 +137,7 @@ export const createDirectory = (context, payload) => { context.commit(types.SET_IS_LOADING, false); }) .catch((error) => { - // TODO error handling + // @todo error handling context.commit(types.SET_IS_LOADING, false); // eslint-disable-next-line no-console console.log('error', error); @@ -187,7 +187,7 @@ export const renameItem = (context, payload) => { context.commit(types.SET_IS_LOADING, false); }) .catch((error) => { - // TODO error handling + // @todo error handling context.commit(types.SET_IS_LOADING, false); // eslint-disable-next-line no-console console.log('error', error); @@ -211,13 +211,13 @@ export const deleteSelectedItems = (context) => { context.commit(types.SET_IS_LOADING, false); }) .catch((error) => { - // TODO error handling + // @todo error handling context.commit(types.SET_IS_LOADING, false); // eslint-disable-next-line no-console console.log('error', error); }); }); } else { - // TODO notify the user that he has to select at least one item + // @todo notify the user that he has to select at least one item } }; diff --git a/administrator/components/com_media/resources/scripts/store/mutations.es6.js b/administrator/components/com_media/resources/scripts/store/mutations.es6.js index f35a2316d6160..deae7826afcb7 100644 --- a/administrator/components/com_media/resources/scripts/store/mutations.es6.js +++ b/administrator/components/com_media/resources/scripts/store/mutations.es6.js @@ -159,7 +159,7 @@ export default { const file = payload; const isNew = (!state.files.some((existing) => (existing.path === file.path))); - // TODO handle file_exists + // @todo handle file_exists if (isNew) { const parentDirectory = state.directories .find((existing) => (existing.path === file.directory)); diff --git a/administrator/components/com_media/src/Controller/ApiController.php b/administrator/components/com_media/src/Controller/ApiController.php index ff9568617f998..3fab0b90b5b79 100644 --- a/administrator/components/com_media/src/Controller/ApiController.php +++ b/administrator/components/com_media/src/Controller/ApiController.php @@ -359,15 +359,19 @@ public function getModel($name = 'Api', $prefix = 'Administrator', $config = []) */ private function checkContent() { - $params = ComponentHelper::getParams('com_media'); - - $helper = new MediaHelper; - $serverlength = $this->input->server->getInt('CONTENT_LENGTH'); - - if (($params->get('upload_maxsize', 0) > 0 && $serverlength > ($params->get('upload_maxsize', 0) * 1024 * 1024)) - || $serverlength > $helper->toBytes(ini_get('upload_max_filesize')) - || $serverlength > $helper->toBytes(ini_get('post_max_size')) - || $serverlength > $helper->toBytes(ini_get('memory_limit'))) + $helper = new MediaHelper; + $contentLength = $this->input->server->getInt('CONTENT_LENGTH'); + $params = ComponentHelper::getParams('com_media'); + $paramsUploadMaxsize = $params->get('upload_maxsize', 0) * 1024 * 1024; + $uploadMaxFilesize = $helper->toBytes(ini_get('upload_max_filesize')); + $postMaxSize = $helper->toBytes(ini_get('post_max_size')); + $memoryLimit = $helper->toBytes(ini_get('memory_limit')); + + if (($paramsUploadMaxsize > 0 && $contentLength > $paramsUploadMaxsize) + || ($uploadMaxFilesize > 0 && $contentLength > $uploadMaxFilesize) + || ($postMaxSize > 0 && $contentLength > $postMaxSize) + || ($memoryLimit > -1 && $contentLength > $memoryLimit) + ) { throw new \Exception(Text::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), 403); } diff --git a/administrator/components/com_media/src/Model/ApiModel.php b/administrator/components/com_media/src/Model/ApiModel.php index f0808f81f76c4..473b543754cdd 100644 --- a/administrator/components/com_media/src/Model/ApiModel.php +++ b/administrator/components/com_media/src/Model/ApiModel.php @@ -17,15 +17,13 @@ use Joomla\CMS\MVC\Model\BaseDatabaseModel; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Plugin\PluginHelper; -use Joomla\Component\Media\Administrator\Adapter\AdapterInterface; use Joomla\Component\Media\Administrator\Event\FetchMediaItemEvent; use Joomla\Component\Media\Administrator\Event\FetchMediaItemsEvent; use Joomla\Component\Media\Administrator\Event\FetchMediaItemUrlEvent; -use Joomla\Component\Media\Administrator\Event\MediaProviderEvent; use Joomla\Component\Media\Administrator\Exception\FileExistsException; use Joomla\Component\Media\Administrator\Exception\FileNotFoundException; use Joomla\Component\Media\Administrator\Exception\InvalidPathException; -use Joomla\Component\Media\Administrator\Provider\ProviderManager; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Api Model @@ -34,13 +32,7 @@ */ class ApiModel extends BaseDatabaseModel { - /** - * Holds the available media file adapters. - * - * @var ProviderManager - * @since 4.0.0 - */ - private $providerManager = null; + use ProviderManagerHelperTrait; /** * The available extensions. @@ -50,32 +42,6 @@ class ApiModel extends BaseDatabaseModel */ private $allowedExtensions = null; - /** - * Return the requested adapter - * - * @param string $name Name of the provider - * - * @since 4.0.0 - * @return AdapterInterface - * - * @throws \Exception - */ - private function getAdapter($name) - { - if ($this->providerManager == null) - { - $this->providerManager = new ProviderManager; - - // Fire the event to get the results - $eventParameters = ['context' => 'AdapterManager', 'providerManager' => $this->providerManager]; - $event = new MediaProviderEvent('onSetupProviders', $eventParameters); - PluginHelper::importPlugin('filesystem'); - Factory::getApplication()->triggerEvent('onSetupProviders', $event); - } - - return $this->providerManager->getAdapter($name); - } - /** * Returns the requested file or folder information. More information * can be found in AdapterInterface::getFile(). diff --git a/administrator/components/com_media/src/Model/MediaModel.php b/administrator/components/com_media/src/Model/MediaModel.php index 01a49be87fd10..257113bc153fe 100644 --- a/administrator/components/com_media/src/Model/MediaModel.php +++ b/administrator/components/com_media/src/Model/MediaModel.php @@ -11,11 +11,8 @@ \defined('_JEXEC') or die; -use Joomla\CMS\Factory; use Joomla\CMS\MVC\Model\BaseDatabaseModel; -use Joomla\CMS\Plugin\PluginHelper; -use Joomla\Component\Media\Administrator\Event\MediaProviderEvent; -use Joomla\Component\Media\Administrator\Provider\ProviderManager; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media View Model @@ -24,6 +21,8 @@ */ class MediaModel extends BaseDatabaseModel { + use ProviderManagerHelperTrait; + /** * Obtain list of supported providers * @@ -33,17 +32,9 @@ class MediaModel extends BaseDatabaseModel */ public function getProviders() { - // Setup provider manager and event parameters - $providerManager = new ProviderManager; - $eventParameters = ['context' => 'AdapterManager', 'providerManager' => $providerManager]; - $event = new MediaProviderEvent('onSetupProviders', $eventParameters); - $results = []; - - // Import plugin group and fire the event - PluginHelper::importPlugin('filesystem'); - Factory::getApplication()->triggerEvent('onSetupProviders', $event); + $results = []; - foreach ($providerManager->getProviders() as $provider) + foreach ($this->getProviderManager()->getProviders() as $provider) { $result = new \stdClass; $result->name = $provider->getID(); diff --git a/administrator/components/com_media/src/Provider/ProviderManager.php b/administrator/components/com_media/src/Provider/ProviderManager.php index 2f7563e5ee92b..8f2c38d228ba4 100644 --- a/administrator/components/com_media/src/Provider/ProviderManager.php +++ b/administrator/components/com_media/src/Provider/ProviderManager.php @@ -55,6 +55,32 @@ public function registerProvider(ProviderInterface $provider) $this->providers[$provider->getID()] = $provider; } + /** + * Unregister a provider from the ProviderManager. + * When no provider, or null is passed in, then all providers are cleared. + * + * @param ProviderInterface|null $provider The provider to be unregistered + * + * @return void + * + * @since 4.0.6 + */ + public function unregisterProvider(ProviderInterface $provider = null): void + { + if ($provider === null) + { + $this->providers = []; + return; + } + + if (!array_key_exists($provider->getID(), $this->providers)) + { + return; + } + + unset($this->providers[$provider->getID()]); + } + /** * Returns the provider for a particular ID * diff --git a/api/components/com_media/src/Helper/AdapterTrait.php b/administrator/components/com_media/src/Provider/ProviderManagerHelperTrait.php similarity index 85% rename from api/components/com_media/src/Helper/AdapterTrait.php rename to administrator/components/com_media/src/Provider/ProviderManagerHelperTrait.php index 6c1297a25f3d7..87bb64afebd92 100644 --- a/api/components/com_media/src/Helper/AdapterTrait.php +++ b/administrator/components/com_media/src/Provider/ProviderManagerHelperTrait.php @@ -7,7 +7,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\Component\Media\Api\Helper; +namespace Joomla\Component\Media\Administrator\Provider; \defined('_JEXEC') or die; @@ -24,7 +24,7 @@ * * @since 4.1.0 */ -trait AdapterTrait +trait ProviderManagerHelperTrait { /** * Holds the available media file adapters. @@ -45,40 +45,25 @@ trait AdapterTrait private $defaultAdapterName = null; /** - * Returns an array with the adapter name as key and the path of the file. - * - * @return array + * Return a provider manager. * - * @throws \Exception + * @return ProviderManager * * @since 4.1.0 */ - private function resolveAdapterAndPath(String $path): array + public function getProviderManager(): ProviderManager { - $result = []; - $parts = explode(':', $path, 2); - - // If we have 2 parts, we have both an adapter name and a file path - if (\count($parts) == 2) - { - $result['adapter'] = $parts[0]; - $result['path'] = $parts[1]; - - return $result; - } - - if (!$this->getDefaultAdapterName()) + if (!$this->providerManager) { - throw new \InvalidArgumentException('No adapter found'); + // Fire the event to get the results + $eventParameters = ['context' => 'AdapterManager', 'providerManager' => new ProviderManager]; + $event = new MediaProviderEvent('onSetupProviders', $eventParameters); + PluginHelper::importPlugin('filesystem'); + Factory::getApplication()->triggerEvent('onSetupProviders', $event); + $this->providerManager = $event->getProviderManager(); } - // If we have less than 2 parts, we return a default adapter name - $result['adapter'] = $this->getDefaultAdapterName(); - - // If we have 1 part, we return it as the path. Otherwise we return a default path - $result['path'] = \count($parts) ? $parts[0] : '/'; - - return $result; + return $this->providerManager; } /** @@ -90,7 +75,7 @@ private function resolveAdapterAndPath(String $path): array * * @since 4.1.0 */ - private function getProvider(String $id): ProviderInterface + public function getProvider(String $id): ProviderInterface { return $this->getProviderManager()->getProvider($id); } @@ -104,11 +89,48 @@ private function getProvider(String $id): ProviderInterface * * @since 4.1.0 */ - private function getAdapter(String $name): AdapterInterface + public function getAdapter(String $name): AdapterInterface { return $this->getProviderManager()->getAdapter($name); } + /** + * Returns an array with the adapter name as key and the path of the file. + * + * @return array + * + * @throws \InvalidArgumentException + * + * @since __DEPLOY_VERSION__ + */ + protected function resolveAdapterAndPath(String $path): array + { + $result = []; + $parts = explode(':', $path, 2); + + // If we have 2 parts, we have both an adapter name and a file path + if (\count($parts) === 2) + { + $result['adapter'] = $parts[0]; + $result['path'] = $parts[1]; + + return $result; + } + + if (!$this->getDefaultAdapterName()) + { + throw new \InvalidArgumentException('No adapter found'); + } + + // If we have less than 2 parts, we return a default adapter name + $result['adapter'] = $this->getDefaultAdapterName(); + + // If we have 1 part, we return it as the path. Otherwise we return a default path + $result['path'] = \count($parts) ? $parts[0] : '/'; + + return $result; + } + /** * Returns the default adapter name. * @@ -118,7 +140,7 @@ private function getAdapter(String $name): AdapterInterface * * @since 4.1.0 */ - private function getDefaultAdapterName(): ?string + protected function getDefaultAdapterName(): ?string { if ($this->defaultAdapterName) { @@ -143,27 +165,4 @@ private function getDefaultAdapterName(): ?string return $this->defaultAdapterName; } - - /** - * Return a provider manager. - * - * @return ProviderManager - * - * @since 4.1.0 - */ - private function getProviderManager(): ProviderManager - { - if (!$this->providerManager) - { - $this->providerManager = new ProviderManager; - - // Fire the event to get the results - $eventParameters = ['context' => 'AdapterManager', 'providerManager' => $this->providerManager]; - $event = new MediaProviderEvent('onSetupProviders', $eventParameters); - PluginHelper::importPlugin('filesystem'); - Factory::getApplication()->triggerEvent('onSetupProviders', $event); - } - - return $this->providerManager; - } } diff --git a/administrator/components/com_menus/forms/item.xml b/administrator/components/com_menus/forms/item.xml index db0570dc2c2ef..984ae531e0d57 100644 --- a/administrator/components/com_menus/forms/item.xml +++ b/administrator/components/com_menus/forms/item.xml @@ -97,7 +97,7 @@ showtime="true" size="22" filter="user_utc" - showon="home:0" + showon="home:0" /> registerTask('unsetDefault', 'setDefault'); + $this->registerTask('unsetDefault', 'setDefault'); } /** diff --git a/administrator/components/com_menus/src/Model/ItemModel.php b/administrator/components/com_menus/src/Model/ItemModel.php index 0961974acb470..53b5049044d81 100644 --- a/administrator/components/com_menus/src/Model/ItemModel.php +++ b/administrator/components/com_menus/src/Model/ItemModel.php @@ -287,7 +287,7 @@ protected function batchCopy($value, $pks, $contexts) // Set the new location in the tree for the node. $table->setLocation($table->parent_id, 'last-child'); - // TODO: Deal with ordering? + // @todo: Deal with ordering? // $table->ordering = 1; $table->level = null; $table->lft = null; diff --git a/administrator/components/com_menus/src/Model/MenuModel.php b/administrator/components/com_menus/src/Model/MenuModel.php index 16da0ff0479af..b6ab33409f91a 100644 --- a/administrator/components/com_menus/src/Model/MenuModel.php +++ b/administrator/components/com_menus/src/Model/MenuModel.php @@ -334,7 +334,7 @@ public function delete($itemIds) // Trigger the after delete event. Factory::getApplication()->triggerEvent('onContentAfterDelete', array($this->_context, $table)); - // TODO: Delete the menu associations - Menu items and Modules + // @todo: Delete the menu associations - Menu items and Modules } } diff --git a/administrator/components/com_menus/src/Model/MenutypesModel.php b/administrator/components/com_menus/src/Model/MenutypesModel.php index 7dd30d37a0630..6df02675b4cea 100644 --- a/administrator/components/com_menus/src/Model/MenutypesModel.php +++ b/administrator/components/com_menus/src/Model/MenutypesModel.php @@ -521,7 +521,7 @@ protected function getTypeOptionsFromLayouts($component, $view) } // Get the template layouts - // TODO: This should only search one template -- the current template for this item (default of specified) + // @todo: This should only search one template -- the current template for this item (default of specified) $folders = Folder::folders($client->path . '/templates', '', false, true); // Array to hold association between template file names and templates diff --git a/administrator/components/com_modules/src/Model/SelectModel.php b/administrator/components/com_modules/src/Model/SelectModel.php index b6a0a1c699c00..70257eaecbba6 100644 --- a/administrator/components/com_modules/src/Model/SelectModel.php +++ b/administrator/components/com_modules/src/Model/SelectModel.php @@ -160,7 +160,7 @@ public function getItems() $items = ArrayHelper::sortObjects($items, 'name', 1, true, true); - // TODO: Use the cached XML from the extensions table? + // @todo: Use the cached XML from the extensions table? return $items; } diff --git a/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php b/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php index af4264c51ee89..b971f8bd2a52a 100644 --- a/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php +++ b/administrator/components/com_newsfeeds/src/Model/NewsfeedModel.php @@ -292,7 +292,7 @@ public function getItem($pk = null) $item->tags = new TagsHelper; $item->tags->getTagIds($item->id, 'com_newsfeeds.newsfeed'); - // TODO: We probably don't need this in any client - but needs careful validation + // @todo: We probably don't need this in any client - but needs careful validation if (!Factory::getApplication()->isClient('api')) { $item->metadata['tags'] = $item->tags; diff --git a/administrator/components/com_scheduler/src/Model/TaskModel.php b/administrator/components/com_scheduler/src/Model/TaskModel.php index d623618b0b08d..5e98e0a79fa56 100644 --- a/administrator/components/com_scheduler/src/Model/TaskModel.php +++ b/administrator/components/com_scheduler/src/Model/TaskModel.php @@ -28,6 +28,7 @@ use Joomla\Component\Scheduler\Administrator\Helper\ExecRuleHelper; use Joomla\Component\Scheduler\Administrator\Helper\SchedulerHelper; use Joomla\Component\Scheduler\Administrator\Table\TaskTable; +use Joomla\Component\Scheduler\Administrator\Task\TaskOption; use Joomla\Database\ParameterType; use Symfony\Component\OptionsResolver\Exception\AccessException; use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; @@ -413,6 +414,18 @@ public function getTask(array $options = []): ?\stdClass ->set($db->quoteName('locked') . ' = :now1') ->bind(':now1', $now); + // Array of all active routine ids + $activeRoutines = array_map( + static function (TaskOption $taskOption): string + { + return $taskOption->type; + }, + SchedulerHelper::getTaskOptions()->options + ); + + // "Orphaned" tasks are not a part of the task queue! + $lockQuery->whereIn($db->quoteName('type'), $activeRoutines, ParameterType::STRING); + // If directed, exclude CLI exclusive tasks if (!$options['includeCliExclusive']) { diff --git a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php index 48d55765bb148..c422e72626604 100644 --- a/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php +++ b/administrator/components/com_scheduler/src/View/Tasks/HtmlView.php @@ -162,8 +162,8 @@ protected function addToolbar(): void // Add the batch Enable, Disable and Trash buttons if privileged if ($canDo->get('core.edit.state')) { - $childBar->addNew('tasks.publish', 'JTOOLBAR_ENABLE')->listCheck(true)->icon('icon-publish'); - $childBar->addNew('tasks.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true)->icon('icon-unpublish'); + $childBar->publish('tasks.publish', 'JTOOLBAR_ENABLE')->listCheck(true); + $childBar->unpublish('tasks.unpublish', 'JTOOLBAR_DISABLE')->listCheck(true); $childBar->checkin('tasks.unlock', 'COM_SCHEDULER_TOOLBAR_UNLOCK')->listCheck(true)->icon('icon-unlock'); diff --git a/administrator/components/com_scheduler/tmpl/task/edit.php b/administrator/components/com_scheduler/tmpl/task/edit.php index 87aab93f00e94..42dc080dc7950 100644 --- a/administrator/components/com_scheduler/tmpl/task/edit.php +++ b/administrator/components/com_scheduler/tmpl/task/edit.php @@ -32,7 +32,7 @@ $input = $app->getInput(); // Fieldsets to be ignored by the `joomla.edit.params` template. -$this->ignore_fieldsets = ['aside', 'details', 'exec_hist', 'custom-cron-rules', 'basic', 'advanced', 'priority', 'task-params']; +$this->ignore_fieldsets = ['aside', 'details', 'exec_hist', 'custom-cron-rules', 'basic', 'advanced', 'priority']; // Used by the `joomla.edit.params` template to render the right template for UI tabs. $this->useCoreUI = true; @@ -40,8 +40,9 @@ $advancedFieldsets = $this->form->getFieldsets('params'); // Don't show the params fieldset, they will be loaded later -foreach ($advancedFieldsets as $fieldset) : - if (!empty($fieldset->showFront) || $fieldset->name === 'task_params') : +foreach ($advancedFieldsets as $name => $fieldset) : + if ($name === 'task_params') : + unset($advancedFieldsets[$name]); continue; endif; @@ -128,9 +129,6 @@ class="form-validate"> form->renderFieldset('priority') ?>
- showFront)) : - continue; - endif; ?>
label ?: 'COM_SCHEDULER_FIELDSET_' . $fieldset->name) ?> form->renderFieldset($fieldset->name) ?> diff --git a/administrator/components/com_scheduler/tmpl/tasks/default.php b/administrator/components/com_scheduler/tmpl/tasks/default.php index 03a50d6167fe4..68ef862eb3222 100644 --- a/administrator/components/com_scheduler/tmpl/tasks/default.php +++ b/administrator/components/com_scheduler/tmpl/tasks/default.php @@ -10,6 +10,7 @@ // Restrict direct access defined('_JEXEC') or die; +use Joomla\CMS\Application\CMSWebApplicationInterface; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; @@ -37,8 +38,10 @@ try { + /** @var CMSWebApplicationInterface $app */ $app = Factory::getApplication(); -} catch (Exception $e) +} +catch (Exception $e) { die('Failed to get app'); } @@ -57,7 +60,9 @@ HTMLHelper::_('draggablelist.draggable'); } -$app->getDocument()->getWebAssetManager()->useScript('com_scheduler.test-task'); +$document = $app->getDocument(); +$document->addScriptOptions('com_scheduler.test-task.token', Session::getFormToken()); +$document->getWebAssetManager()->useScript('com_scheduler.test-task'); ?>
- - + + - - + +
diff --git a/administrator/components/com_templates/tmpl/template/default.php b/administrator/components/com_templates/tmpl/template/default.php index 3cd903272c80e..a1157149446c2 100644 --- a/administrator/components/com_templates/tmpl/template/default.php +++ b/administrator/components/com_templates/tmpl/template/default.php @@ -79,8 +79,8 @@ type == 'file' && !empty($this->source->coreFile)) : ?>
- form->getInput('show_core'); ?> - form->getInput('show_diff'); ?> + form->renderField('show_core'); ?> + form->renderField('show_diff'); ?>
diff --git a/administrator/components/com_users/src/Model/LevelModel.php b/administrator/components/com_users/src/Model/LevelModel.php index d92e87809384b..d01d4c4dc7723 100644 --- a/administrator/components/com_users/src/Model/LevelModel.php +++ b/administrator/components/com_users/src/Model/LevelModel.php @@ -109,7 +109,7 @@ protected function canDelete($record) $this->levelsInUse = array_merge($this->levelsInUse, $values); - // TODO Could assemble an array of the tables used by each view level list those, + // @todo Could assemble an array of the tables used by each view level list those, // giving the user a clue in the error where to look. } } diff --git a/administrator/components/com_users/src/Model/LevelsModel.php b/administrator/components/com_users/src/Model/LevelsModel.php index e29ac3c0f0412..0a94fa595ca11 100644 --- a/administrator/components/com_users/src/Model/LevelsModel.php +++ b/administrator/components/com_users/src/Model/LevelsModel.php @@ -177,7 +177,7 @@ public function reorder($pk, $direction = 0) } // Move the row. - // TODO: Where clause to restrict category. + // @todo: Where clause to restrict category. $table->move($pk); return true; diff --git a/administrator/components/com_workflow/src/Controller/StagesController.php b/administrator/components/com_workflow/src/Controller/StagesController.php index 5cd19a2fb7e50..e7af94b3b2372 100644 --- a/administrator/components/com_workflow/src/Controller/StagesController.php +++ b/administrator/components/com_workflow/src/Controller/StagesController.php @@ -103,7 +103,7 @@ public function __construct(array $config = array(), MVCFactoryInterface $factor } } - $this->registerTask('unsetDefault', 'setDefault'); + $this->registerTask('unsetDefault', 'setDefault'); } /** diff --git a/administrator/components/com_workflow/src/Controller/WorkflowsController.php b/administrator/components/com_workflow/src/Controller/WorkflowsController.php index 9c698600ff0ae..9739d666dba2c 100644 --- a/administrator/components/com_workflow/src/Controller/WorkflowsController.php +++ b/administrator/components/com_workflow/src/Controller/WorkflowsController.php @@ -76,7 +76,7 @@ public function __construct($config = array(), MVCFactoryInterface $factory = nu } } - $this->registerTask('unsetDefault', 'setDefault'); + $this->registerTask('unsetDefault', 'setDefault'); } /** diff --git a/administrator/components/com_workflow/src/Model/WorkflowModel.php b/administrator/components/com_workflow/src/Model/WorkflowModel.php index beb71976e59d2..dec07533ed127 100644 --- a/administrator/components/com_workflow/src/Model/WorkflowModel.php +++ b/administrator/components/com_workflow/src/Model/WorkflowModel.php @@ -297,7 +297,12 @@ public function setDefault($pk, $value = 1) if ($value) { // Unset other default item - if ($table->load(array('default' => '1'))) + if ($table->load( + [ + 'default' => '1', + 'extension' => $table->get('extension') + ] + )) { $table->default = 0; $table->modified = $date; diff --git a/administrator/components/com_workflow/src/Table/WorkflowTable.php b/administrator/components/com_workflow/src/Table/WorkflowTable.php index faedf915b6f12..a9f7267bb39b7 100644 --- a/administrator/components/com_workflow/src/Table/WorkflowTable.php +++ b/administrator/components/com_workflow/src/Table/WorkflowTable.php @@ -144,7 +144,7 @@ public function check() } else { - $db = $this->getDbo(); + $db = $this->getDbo(); $query = $db->getQuery(true); $query @@ -192,7 +192,7 @@ public function store($updateNulls = true) { // Existing item $this->modified_by = $user->id; - $this->modified = $date->toSql(); + $this->modified = $date->toSql(); } else { @@ -219,10 +219,15 @@ public function store($updateNulls = true) $this->modified_by = $this->created_by; } - if ($this->default == '1') + if ((int) $this->default === 1) { // Verify that the default is unique for this workflow - if ($table->load(array('default' => '1'))) + if ($table->load( + [ + 'default' => '1', + 'extension' => $this->extension + ] + )) { $table->default = 0; $table->store(); diff --git a/administrator/language/en-GB/com_config.ini b/administrator/language/en-GB/com_config.ini index f63f6739dc5b4..ddfd1a734709c 100644 --- a/administrator/language/en-GB/com_config.ini +++ b/administrator/language/en-GB/com_config.ini @@ -59,28 +59,28 @@ COM_CONFIG_FIELD_DATABASE_NAME_LABEL="Database Name" COM_CONFIG_FIELD_DATABASE_PASSWORD_DESC="Do not edit this field unless absolutely necessary (eg after the transfer of the database to a new hosting provider)." COM_CONFIG_FIELD_DATABASE_PASSWORD_LABEL="Database Password" COM_CONFIG_FIELD_DATABASE_PREFIX_LABEL="Database Tables Prefix" -COM_CONFIG_FIELD_DATABASE_TYPE_LABEL="Database Type" COM_CONFIG_FIELD_DATABASE_TYPE_DESC="Do not change this to a different database technology e.g. from MySQLi (MySQL database technology) to PostgreSQL (Postgres database technology); it will break your site." +COM_CONFIG_FIELD_DATABASE_TYPE_LABEL="Database Type" COM_CONFIG_FIELD_DATABASE_USERNAME_LABEL="Database Username" COM_CONFIG_FIELD_DEBUG_CONST="Constant" COM_CONFIG_FIELD_DEBUG_CONST_LANG_DESC="Select if you should display the language constant or the language value when debugging the language strings." COM_CONFIG_FIELD_DEBUG_CONST_LANG_LABEL="Language Display" -COM_CONFIG_FIELD_DEBUG_LANG_LABEL="Debug Language" COM_CONFIG_FIELD_DEBUG_LANG_DESC="Displays ?? around a language string constant when the string is not present in the currently loaded language files or ** around the string value when the string is present. If none of the above is displayed, it could mean the text is hardcoded and needs a language string." -COM_CONFIG_FIELD_DEBUG_SYSTEM_LABEL="Debug System" +COM_CONFIG_FIELD_DEBUG_LANG_LABEL="Debug Language" COM_CONFIG_FIELD_DEBUG_SYSTEM_DESC="Use it only for troubleshooting, ideally on private copies of your site. The more technical information displayed in this mode can be a security risk if left enabled on live sites. Remember to publish the “System - Debug” plugin to get detailed information on each page being loaded." +COM_CONFIG_FIELD_DEBUG_SYSTEM_LABEL="Debug System" COM_CONFIG_FIELD_DEBUG_VALUE="Value" -COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_LABEL="Default Access Level" COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_DESC="Set the Access Level which will be assigned by default to newly created items." -COM_CONFIG_FIELD_DEFAULT_CAPTCHA_LABEL="Default Captcha" +COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_LABEL="Default Access Level" COM_CONFIG_FIELD_DEFAULT_CAPTCHA_DESC="Joomla and third party extensions can use a CAPTCHA to prevent abuse (spam) on public forms. Each extension can choose to use a different CAPTCHA, if more than one are available. If no selection is made this will be used by default. You can enable additional CAPTCHA methods in System, Manage, Plugins." -COM_CONFIG_FIELD_DEFAULT_EDITOR_LABEL="Default Editor" +COM_CONFIG_FIELD_DEFAULT_CAPTCHA_LABEL="Default Captcha" COM_CONFIG_FIELD_DEFAULT_EDITOR_DESC="This editor will be used for editing content and other rich text areas in third party extensions unless a user has chosen a different one in their user profile . This will also be the only editor available and used for users who are not already logged in (the Guest user group)." -COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_LABEL="Default Feed Limit" +COM_CONFIG_FIELD_DEFAULT_EDITOR_LABEL="Default Editor" COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_DESC="How many items will be published by default in RSS and Atom feeds." +COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_LABEL="Default Feed Limit" COM_CONFIG_FIELD_DEFAULT_LIST_LIMIT_LABEL="Default List Limit" -COM_CONFIG_FIELD_ERROR_REPORTING_LABEL="Error Reporting" COM_CONFIG_FIELD_ERROR_REPORTING_DESC="Control whether PHP error messages should be displayed at all and how verbose they will be. On live sites use None for security reasons. Only use Maximum while troubleshooting — remember to set that back to None when you're done!" +COM_CONFIG_FIELD_ERROR_REPORTING_LABEL="Error Reporting" COM_CONFIG_FIELD_FEED_EMAIL_LABEL="Feed Email Address" COM_CONFIG_FIELD_FILESYSTEM_PATH_DESC="The filesystem path where session data will be stored.
If empty, the system's temporary directory will be used." COM_CONFIG_FIELD_FILESYSTEM_PATH_LABEL="Session Save Path" @@ -91,10 +91,10 @@ COM_CONFIG_FIELD_FILTERS_NO_HTML="No HTML" COM_CONFIG_FIELD_FILTERS_ALLOWED_LIST="Allowed List" COM_CONFIG_FIELD_FLOC_BLOCKER_DESC="Send a header to not support the tracking through the FLoC method." COM_CONFIG_FIELD_FLOC_BLOCKER_LABEL="Block FLoC" -COM_CONFIG_FIELD_FORCE_SSL_LABEL="Force HTTPS" COM_CONFIG_FIELD_FORCE_SSL_DESC="HTTPS must be enabled on your server or load balancer to utilise this option. Enable 'Behind Load Balancer' if your SSL terminates on your load balancer but your site is served on http on its webserver." -COM_CONFIG_FIELD_GZIP_COMPRESSION_LABEL="Gzip Page Compression" +COM_CONFIG_FIELD_FORCE_SSL_LABEL="Force HTTPS" COM_CONFIG_FIELD_GZIP_COMPRESSION_DESC="Joomla can automatically compress the generated HTML pages with GZip, making them smaller and increasing your site's speed score. Disable it if your server is already doing that for you or if it conflicts with third party extensions." +COM_CONFIG_FIELD_GZIP_COMPRESSION_LABEL="Gzip Page Compression" COM_CONFIG_FIELD_HTMLBODY_LABEL="HTML Body" COM_CONFIG_FIELD_LOADBALANCER_ENABLE_DESC="If your site is behind a load balancer or reverse proxy, enable this setting so that IP addresses and other configurations within Joomla automatically take this into account." COM_CONFIG_FIELD_LOADBALANCER_ENABLE_LABEL="Behind Load Balancer" @@ -104,10 +104,10 @@ COM_CONFIG_FIELD_LOG_CATEGORY_MODE_EXCLUDE="Exclude" COM_CONFIG_FIELD_LOG_CATEGORY_MODE_INCLUDE="Include" COM_CONFIG_FIELD_LOG_CATEGORY_MODE_LABEL="Log Category Mode" COM_CONFIG_FIELD_LOG_DEPRECATED_LABEL="Log Deprecated API" -COM_CONFIG_FIELD_LOG_EVERYTHING_LABEL="Log Almost Everything" COM_CONFIG_FIELD_LOG_EVERYTHING_DESC="Logs everything, except deprecated APIs." -COM_CONFIG_FIELD_LOG_PATH_LABEL="Path to Log Folder" +COM_CONFIG_FIELD_LOG_EVERYTHING_LABEL="Log Almost Everything" COM_CONFIG_FIELD_LOG_PATH_DESC="Joomla can optionally keep a log file of its own and third party extensions' operations. Provide the absolute path to a folder that is writeable by PHP; if it's missing or is not writeable Joomla will not load at all. For security reasons you must not use a folder with system–wide access such as /tmp." +COM_CONFIG_FIELD_LOG_PATH_LABEL="Path to Log Folder" COM_CONFIG_FIELD_LOG_PRIORITIES_ALERT="Alert" COM_CONFIG_FIELD_LOG_PRIORITIES_ALL="All" COM_CONFIG_FIELD_LOG_PRIORITIES_CRITICAL="Critical" @@ -122,8 +122,8 @@ COM_CONFIG_FIELD_MAIL_FROM_EMAIL_LABEL="From Email" COM_CONFIG_FIELD_MAIL_FROM_NAME_LABEL="From Name" COM_CONFIG_FIELD_MAIL_MAILER_LABEL="Mailer" COM_CONFIG_FIELD_MAIL_MAILONLINE_LABEL="Send Mail" -COM_CONFIG_FIELD_MAIL_MASSMAILOFF_LABEL="Disable Mass Mail" COM_CONFIG_FIELD_MAIL_MASSMAILOFF_DESC="Joomla offers a Mass Mail feature which allows a user with administrator access to send an email to all users of the site. On sites with more than a few dozen users this can be problematic or time out." +COM_CONFIG_FIELD_MAIL_MASSMAILOFF_LABEL="Disable Mass Mail" COM_CONFIG_FIELD_MAIL_REPLY_TO_EMAIL_LABEL="Reply To Email" COM_CONFIG_FIELD_MAIL_REPLY_TO_NAME_LABEL="Reply To Name" COM_CONFIG_FIELD_MAIL_SENDMAIL_PATH_LABEL="Sendmail Path" @@ -139,18 +139,18 @@ COM_CONFIG_FIELD_MEMCACHE_PERSISTENT_LABEL="Persistent Memcache(d)" COM_CONFIG_FIELD_MEMCACHE_PORT_LABEL="Memcache(d) Server Port" COM_CONFIG_FIELD_METAAUTHOR_LABEL="Author Meta Tag" COM_CONFIG_FIELD_METADESC_LABEL="Site Meta Description" -COM_CONFIG_FIELD_METAVERSION_LABEL="Joomla Version" COM_CONFIG_FIELD_METAVERSION_DESC="Controls whether the generator meta tag in the HTML document's header in the front-end and in Atom feeds includes the exact version of your Joomla site. It is recommended to hide it for security reasons." +COM_CONFIG_FIELD_METAVERSION_LABEL="Joomla Version" COM_CONFIG_FIELD_OFFLINE_IMAGE_LABEL="Offline Image" COM_CONFIG_FIELD_OFFLINE_MESSAGE_LABEL="Custom Message" -COM_CONFIG_FIELD_PROXY_ENABLE_LABEL="Enable Outbound Proxy" COM_CONFIG_FIELD_PROXY_ENABLE_DESC="Some hosts do not allow any network access from your site to the outside world by default and require you to manually configure an outbound proxy." -COM_CONFIG_FIELD_PROXY_HOST_LABEL="Outbound Proxy Host" +COM_CONFIG_FIELD_PROXY_ENABLE_LABEL="Enable Outbound Proxy" COM_CONFIG_FIELD_PROXY_HOST_DESC="Host (domain) name or IP address." +COM_CONFIG_FIELD_PROXY_HOST_LABEL="Outbound Proxy Host" COM_CONFIG_FIELD_PROXY_PASSWORD_LABEL="Outbound Proxy Password" COM_CONFIG_FIELD_PROXY_PORT_LABEL="Outbound Proxy Port" -COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Outbound Proxy Username" COM_CONFIG_FIELD_PROXY_USERNAME_DESC="Leave blank if your outbound proxy does not require authentication." +COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Outbound Proxy Username" COM_CONFIG_FIELD_REDIS_AUTH_LABEL="Redis Server Authentication" COM_CONFIG_FIELD_REDIS_DB_LABEL="Redis Database" COM_CONFIG_FIELD_REDIS_HOST_LABEL="Redis Server Host/Sock" @@ -158,14 +158,14 @@ COM_CONFIG_FIELD_REDIS_PERSISTENT_LABEL="Persistent Redis" COM_CONFIG_FIELD_REDIS_PORT_DESC="Port discarded if connecting to Redis server over Unix sockets." COM_CONFIG_FIELD_REDIS_PORT_LABEL="Redis Server Port" COM_CONFIG_FIELD_SEF_REWRITE_NOTE="Apache and Litespeed: Rename htaccess.txt to .htaccess
IIS: Rename web.config.txt to web.config
NginX: you must configure your server.
Other servers or if unsure: please consult your hosting company." -COM_CONFIG_FIELD_SEF_REWRITE_LABEL="Use URL Rewriting" COM_CONFIG_FIELD_SEF_REWRITE_DESC="Removes the index.php/ part from the URLs." -COM_CONFIG_FIELD_SEF_SUFFIX_LABEL="Add Suffix to URL" +COM_CONFIG_FIELD_SEF_REWRITE_LABEL="Use URL Rewriting" COM_CONFIG_FIELD_SEF_SUFFIX_DESC="By default, Joomla URLs are “bare”, without an extension. This options tells Joomla to add an extension such as .html, .feed etc based on the type of content being displayed by the URL." -COM_CONFIG_FIELD_SEF_URL_LABEL="Search Engine Friendly URLs" +COM_CONFIG_FIELD_SEF_SUFFIX_LABEL="Add Suffix to URL" COM_CONFIG_FIELD_SEF_URL_DESC="Joomla URLs normally look like index.php?option=com_example&task=item.display&id=1 which isn't easy to convey verbally or in writing. Search Engine Friendly (SEF) URLs are more human–readable, e.g. index.php/example/display/something." -COM_CONFIG_FIELD_SERVER_TIMEZONE_LABEL="Website Time Zone" +COM_CONFIG_FIELD_SEF_URL_LABEL="Search Engine Friendly URLs" COM_CONFIG_FIELD_SERVER_TIMEZONE_DESC="Used by default to display dates and times (Joomla stores them internally as UTC). This can be different than the time zone of your server. Users can override their preferred time zone in their user profile." +COM_CONFIG_FIELD_SERVER_TIMEZONE_LABEL="Website Time Zone" COM_CONFIG_FIELD_SESSION_HANDLER_LABEL="Session Handler" COM_CONFIG_FIELD_SESSION_METADATA_DESC="If enabled, additional metadata about a user's session (including their username, user ID, and which application they are logged into) will be logged to the session database table.
If disabled, features dependent on this data will be unavailable." COM_CONFIG_FIELD_SESSION_METADATA_LABEL="Track Session Metadata" @@ -177,10 +177,10 @@ COM_CONFIG_FIELD_SITE_NAME_LABEL="Site Name" COM_CONFIG_FIELD_SITE_OFFLINE_LABEL="Site Offline" COM_CONFIG_FIELD_SITENAME_PAGETITLES_LABEL="Site Name in Page Titles" COM_CONFIG_FIELD_SUBJECT_LABEL="Subject" -COM_CONFIG_FIELD_TEMP_PATH_LABEL="Path to Temp Folder" COM_CONFIG_FIELD_TEMP_PATH_DESC="Joomla needs to temporarily store some files to perform actions such as installing / updating extensions or uploading files. Enter the absolute path of a directory that is writeable be PHP. Do not use the system–wide temporary folder (e.g. /tmp) for security reasons." -COM_CONFIG_FIELD_UNICODESLUGS_LABEL="Unicode Aliases" +COM_CONFIG_FIELD_TEMP_PATH_LABEL="Path to Temp Folder" COM_CONFIG_FIELD_UNICODESLUGS_DESC="No: Joomla transliterates aliases which contain non–latin-1 characters using the transliteration engine provided by the Joomla language pack for the content's selected language, e.g. über becomes ueber for en-GB (English, Great Britain). Yes: Joomla does not transliterate aliases; the alias is used as is, e.g. über remains as–is." +COM_CONFIG_FIELD_UNICODESLUGS_LABEL="Unicode Aliases" COM_CONFIG_FIELD_VALUE_ADMINISTRATOR_ONLY="Administrator Only" COM_CONFIG_FIELD_VALUE_AFTER="After" COM_CONFIG_FIELD_VALUE_AUTHOR_EMAIL="Author Email" @@ -209,8 +209,8 @@ 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="Frontend Editing" COM_CONFIG_FRONTEDITING_DESC="Joomla can show an overlay in the public front–end, visible only to users with edit privileges, to directly modify the configuration of each module and/or menu displayed on the site. Set to “None” to disable this feature." +COM_CONFIG_FRONTEDITING_LABEL="Frontend Editing" COM_CONFIG_FRONTEDITING_MENUSANDMODULES="Modules & Menus" COM_CONFIG_FRONTEDITING_MODULES="Modules" COM_CONFIG_GLOBAL_CONFIGURATION="Global Configuration" diff --git a/administrator/language/en-GB/com_content.ini b/administrator/language/en-GB/com_content.ini index 23dcc8ccc7d5c..e7186424eeeff 100644 --- a/administrator/language/en-GB/com_content.ini +++ b/administrator/language/en-GB/com_content.ini @@ -97,6 +97,7 @@ COM_CONTENT_FIELDS_TYPE_MODAL_ARTICLE="Article" COM_CONTENT_FIELDSET_PUBLISHING="Publishing" COM_CONTENT_FIELDSET_RULES="Permissions" COM_CONTENT_FIELDSET_URLS_AND_IMAGES="Images and Links" +COM_CONTENT_FILTER_AUTHORS_BY_ME="Created by me" COM_CONTENT_FILTER_FEATURED_NO="Unfeatured Articles" COM_CONTENT_FILTER_FEATURED_YES="Featured Articles" COM_CONTENT_FILTER_SEARCH_DESC="Search in title, alias and note. Prefix with ID: or AUTHOR: or CONTENT: to search for an article ID, article author or search in article content." diff --git a/administrator/language/en-GB/com_fields.ini b/administrator/language/en-GB/com_fields.ini index f020bac7822e9..1d65e31a4445c 100644 --- a/administrator/language/en-GB/com_fields.ini +++ b/administrator/language/en-GB/com_fields.ini @@ -21,6 +21,7 @@ COM_FIELDS_FIELD_EDITABLE_IN_BOTH="Both" COM_FIELDS_FIELD_EDITABLE_IN_LABEL="Editable In" COM_FIELDS_FIELD_EDITABLE_IN_SITE="Site" COM_FIELDS_FIELD_FORM_EDIT="Edit Field" +COM_FIELDS_FIELD_FORM_LAYOUT_LABEL="Layout" COM_FIELDS_FIELD_FORM_NEW="New Field" COM_FIELDS_FIELD_FORMOPTIONS_HEADING="Form Options" COM_FIELDS_FIELD_GROUP_LABEL="Field Group" diff --git a/administrator/language/en-GB/com_joomlaupdate.ini b/administrator/language/en-GB/com_joomlaupdate.ini index 06aecff2d5b28..b4502450d0ce1 100644 --- a/administrator/language/en-GB/com_joomlaupdate.ini +++ b/administrator/language/en-GB/com_joomlaupdate.ini @@ -59,7 +59,7 @@ COM_JOOMLAUPDATE_SELF_EMPTYSTATE_TITLE="A new version of the Joomla Update Compo COM_JOOMLAUPDATE_SYSTEM_CHECK="System Check" COM_JOOMLAUPDATE_TOOLBAR_CHECK="Check for Updates" COM_JOOMLAUPDATE_UPDATE_CHECK="Update Check" -COM_JOOMLAUPDATE_UPDATE_CONFIRM_BACKUP="I'm prepared for the update and have made a backup." +COM_JOOMLAUPDATE_UPDATE_CONFIRM_BACKUP="I'm prepared for the update and have made a backup of the files and database." COM_JOOMLAUPDATE_UPDATE_EMPTYSTATE_TITLE="Update your site to \"Joomla! %s\"" COM_JOOMLAUPDATE_UPDATE_EMPTYSTATE_BUTTON_ADD="Start update" COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP="Cleaning up after installation." @@ -121,7 +121,7 @@ COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALLAGAIN="Reinstall Joomla core files" COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALLED="Installed Joomla version" COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALLUPDATE="Update" COM_JOOMLAUPDATE_VIEW_DEFAULT_LATEST="Latest Joomla version" -COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL="We can't find a download URL" +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL="Update unavailable" COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL_DESC="An update to Joomla %1$s was found, but it wasn't possible to fetch the download URL for that update. Either the update to Joomla %1$s is not available for your stability level or there is a problem with the Joomla Update Server.
Please try to download the update package from the official Joomla download page and use the Upload and Update tab." COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE="A new version of the Joomla Update Component is available." COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE_DESC="You must update this component first before you can update Joomla! Click here to update the component." diff --git a/administrator/language/en-GB/com_scheduler.ini b/administrator/language/en-GB/com_scheduler.ini index 42bcbf67dbd81..6c31fa2ce9cf1 100644 --- a/administrator/language/en-GB/com_scheduler.ini +++ b/administrator/language/en-GB/com_scheduler.ini @@ -15,7 +15,7 @@ COM_SCHEDULER_CONFIG_HASH_PROTECTION_DESC="If enabled, tasks will only be trigge COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_ENABLED_DESC="If disabled, scheduled tasks will not be triggered by visitors on the site.
Recommended if triggering with native cron." COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_ENABLED_LABEL="Lazy Scheduler" COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_INTERVAL_DESC="Interval between scheduler trigger requests from the client." -COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_INTERVAL_LABEL="Request Interval" +COM_SCHEDULER_CONFIG_LAZY_SCHEDULER_INTERVAL_LABEL="Request Interval (seconds)" COM_SCHEDULER_CONFIG_RESET_WEBCRON_KEY_LABEL="Reset Access Key" COM_SCHEDULER_CONFIG_TASKS_FIELDSET_LABEL="Configure Tasks" COM_SCHEDULER_CONFIG_TASK_TIMEOUT_LABEL="Task Timeout (seconds)" @@ -59,7 +59,7 @@ COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_HOURS="Hours" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MINUTES="Minutes" COM_SCHEDULER_FIELD_OPTION_INTERVAL_MATCH_MONTHS="Months" COM_SCHEDULER_FIELD_TASK_TYPE="Type ID" -COM_SCHEDULER_FILTER_SEARCH_DESC="Search in Task title and note. Prefix with 'ID:' to search for a task ID" +COM_SCHEDULER_FILTER_SEARCH_DESC="Search in task title and note. Prefix with ID: to search for a task ID." COM_SCHEDULER_FILTER_SEARCH_LABEL="Search Tasks" COM_SCHEDULER_FORM_TITLE_EDIT="Edit Task" COM_SCHEDULER_FORM_TITLE_NEW="New Task" @@ -109,7 +109,7 @@ COM_SCHEDULER_SCHEDULER_TASK_ROUTINE_NA="Task#%1$02d has no corresponding plugin COM_SCHEDULER_SCHEDULER_TASK_START="Running task#%1$02d '%2$s'." COM_SCHEDULER_SCHEDULER_TASK_UNKNOWN_EXIT="Task#%1$02d exited with code %4$d in %2$.2f (net %3$.2f) seconds." COM_SCHEDULER_SCHEDULER_TASK_UNLOCKED="Task#%1$02d was unlocked." -COM_SCHEDULER_SELECT_INTERVAL_MINUTES="- Select Interval in Minutes -" +COM_SCHEDULER_SELECT_INTERVAL_MINUTES="- Select interval in Minutes -" COM_SCHEDULER_SELECT_TASK_TYPE="Select task, %s" COM_SCHEDULER_SELECT_TYPE="- Task Type -" COM_SCHEDULER_TABLE_CAPTION="Tasks List" @@ -121,8 +121,8 @@ COM_SCHEDULER_TASK_PRIORITY_ASC="Task Priority ascending" COM_SCHEDULER_TASK_PRIORITY_DESC="Task Priority descending" COM_SCHEDULER_TASK_ROUTINE_EXCEPTION="Routine threw exception: %1$s" COM_SCHEDULER_TASK_TYPE="Task Type" -COM_SCHEDULER_TASK_TYPE_ASC="Task Type ascending" -COM_SCHEDULER_TASK_TYPE_DESC="Task Type descending" +COM_SCHEDULER_TASK_TYPE_ASC="Task type ascending" +COM_SCHEDULER_TASK_TYPE_DESC="Task type descending" COM_SCHEDULER_TEST_RUN="Run Test" COM_SCHEDULER_TEST_RUN_DURATION="Duration: %s seconds" COM_SCHEDULER_TEST_RUN_OUTPUT="Output:
%s" diff --git a/administrator/language/en-GB/com_templates.ini b/administrator/language/en-GB/com_templates.ini index e0b5094a4d695..1b2211b710697 100644 --- a/administrator/language/en-GB/com_templates.ini +++ b/administrator/language/en-GB/com_templates.ini @@ -147,10 +147,8 @@ COM_TEMPLATES_IMAGE_WIDTH="Width" COM_TEMPLATES_INVALID_FILE_NAME="Invalid file name. Please choose a file name with a-z, A-Z, 0-9, - and _." COM_TEMPLATES_INVALID_FILE_TYPE="File type not selected." COM_TEMPLATES_INVALID_FOLDER_NAME="Invalid folder name. Please choose a folder name with a-z, A-Z, 0-9, - and _." -COM_TEMPLATES_LAYOUTS_DIFFVIEW_HIDE_CORE="Hide Original" -COM_TEMPLATES_LAYOUTS_DIFFVIEW_HIDE_DIFF="Hide Differences" -COM_TEMPLATES_LAYOUTS_DIFFVIEW_SHOW_CORE="Show Original" -COM_TEMPLATES_LAYOUTS_DIFFVIEW_SHOW_DIFF="Show Differences" +COM_TEMPLATES_LAYOUTS_DIFFVIEW_CORE="Original File" +COM_TEMPLATES_LAYOUTS_DIFFVIEW_DIFF="Differences" COM_TEMPLATES_MANAGE_FOLDERS="Manage Folders" COM_TEMPLATES_MANAGER_ADD_STYLE="Templates: Add Style" COM_TEMPLATES_MANAGER_EDIT_STYLE="Templates: Edit Style" diff --git a/administrator/language/en-GB/install.xml b/administrator/language/en-GB/install.xml index 87c6747a74e56..c8659ad484aeb 100644 --- a/administrator/language/en-GB/install.xml +++ b/administrator/language/en-GB/install.xml @@ -3,7 +3,7 @@ English (en-GB) en-GB 4.1.0 - December 2021 + January 2022 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/language/en-GB/langmetadata.xml b/administrator/language/en-GB/langmetadata.xml index b96d1a7f24af8..2e8da753bf0a5 100644 --- a/administrator/language/en-GB/langmetadata.xml +++ b/administrator/language/en-GB/langmetadata.xml @@ -2,7 +2,7 @@ English (en-GB) 4.1.0 - December 2021 + January 2022 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/language/en-GB/lib_joomla.ini b/administrator/language/en-GB/lib_joomla.ini index 4cebf64ed4ef4..2fe27310d9012 100644 --- a/administrator/language/en-GB/lib_joomla.ini +++ b/administrator/language/en-GB/lib_joomla.ini @@ -649,6 +649,10 @@ JLIB_INSTALLER_NOT_ERROR="If the error is related to the installation of TinyMCE JLIB_INSTALLER_NOTICE_LANG_RESET_USERS="Language set to Default for %d users." JLIB_INSTALLER_NOTICE_LANG_RESET_USERS_1="Language set to Default for the user." JLIB_INSTALLER_PURGED_UPDATES="Cleared updates." +JLIB_INSTALLER_SQL_BEGIN="Start of SQL updates." +JLIB_INSTALLER_SQL_BEGIN_SCHEMA="The current database version (schema) is %s." +JLIB_INSTALLER_SQL_END="End of SQL updates." +JLIB_INSTALLER_SQL_END_NOT_COMPLETE="End of SQL updates - INCOMPLETE." JLIB_INSTALLER_UNINSTALL="Uninstall" JLIB_INSTALLER_UPDATE="Update" JLIB_INSTALLER_UPDATE_LOG_QUERY="Ran query from file %1$s. Query text: %2$s." diff --git a/administrator/language/en-GB/plg_editors_tinymce.ini b/administrator/language/en-GB/plg_editors_tinymce.ini index 6c2df01727fa8..ee02bd148c403 100644 --- a/administrator/language/en-GB/plg_editors_tinymce.ini +++ b/administrator/language/en-GB/plg_editors_tinymce.ini @@ -46,6 +46,7 @@ PLG_TINY_FIELD_LANGCODE_LABEL="Language Code" PLG_TINY_FIELD_LANGSELECT_LABEL="Automatic Language Selection" PLG_TINY_FIELD_NEWLINES_LABEL="New Lines" PLG_TINY_FIELD_NUMBER_OF_SETS_LABEL="Number of Sets" +PLG_TINY_FIELD_PASTE_AS_TEXT_LABEL="Paste As Text" PLG_TINY_FIELD_PATH_LABEL="Element Path" PLG_TINY_FIELD_PROHIBITED_LABEL="Prohibited Elements" PLG_TINY_FIELD_RESIZE_HORIZONTAL_LABEL="Horizontal Resizing" diff --git a/administrator/language/en-GB/plg_fields_list.ini b/administrator/language/en-GB/plg_fields_list.ini index f3b4e535323f2..5eeb5f3d4b567 100644 --- a/administrator/language/en-GB/plg_fields_list.ini +++ b/administrator/language/en-GB/plg_fields_list.ini @@ -5,6 +5,7 @@ PLG_FIELDS_LIST="Fields - List" PLG_FIELDS_LIST_LABEL="List (%s)" +PLG_FIELDS_LIST_PARAMS_FORM_LAYOUT_FANCY_SELECT="Enhanced select" PLG_FIELDS_LIST_PARAMS_MULTIPLE_LABEL="Multiple" PLG_FIELDS_LIST_PARAMS_OPTIONS_LABEL="List Values" PLG_FIELDS_LIST_PARAMS_OPTIONS_NAME_LABEL="Text" diff --git a/administrator/language/en-GB/plg_fields_radio.ini b/administrator/language/en-GB/plg_fields_radio.ini index fb82a5bfd0114..bd3fa1089e2ae 100644 --- a/administrator/language/en-GB/plg_fields_radio.ini +++ b/administrator/language/en-GB/plg_fields_radio.ini @@ -5,6 +5,8 @@ PLG_FIELDS_RADIO="Fields - Radio" PLG_FIELDS_RADIO_LABEL="Radio (%s)" +PLG_FIELDS_RADIO_PARAMS_FORM_LAYOUT_BUTTONS="Buttons" +PLG_FIELDS_RADIO_PARAMS_FORM_LAYOUT_SWITCHER="Switcher" PLG_FIELDS_RADIO_PARAMS_OPTIONS_LABEL="Radio Values" PLG_FIELDS_RADIO_PARAMS_OPTIONS_NAME_LABEL="Text" PLG_FIELDS_RADIO_PARAMS_OPTIONS_VALUE_LABEL="Value" diff --git a/administrator/language/en-GB/plg_fields_sql.ini b/administrator/language/en-GB/plg_fields_sql.ini index 5744e7f541109..26552719cbb48 100644 --- a/administrator/language/en-GB/plg_fields_sql.ini +++ b/administrator/language/en-GB/plg_fields_sql.ini @@ -6,6 +6,7 @@ PLG_FIELDS_SQL="Fields - SQL" PLG_FIELDS_SQL_CREATE_NOT_POSSIBLE="Only a Super User can create or edit an SQL field!" PLG_FIELDS_SQL_LABEL="SQL (%s)" +PLG_FIELDS_SQL_PARAMS_FORM_LAYOUT_FANCY_SELECT="Enhanced select" PLG_FIELDS_SQL_PARAMS_MULTIPLE_LABEL="Multiple" PLG_FIELDS_SQL_PARAMS_QUERY_DESC="The SQL query which will provide the data for the dropdown list. The query must return two columns; one called 'value' which will hold the values of the list items; the other called 'text' with the text in the dropdown list." ; The terms 'value' and 'text' should not be translated PLG_FIELDS_SQL_PARAMS_QUERY_LABEL="Query" diff --git a/administrator/language/en-GB/plg_system_stats.ini b/administrator/language/en-GB/plg_system_stats.ini index c322fd4d7e50b..60ef4610ae074 100644 --- a/administrator/language/en-GB/plg_system_stats.ini +++ b/administrator/language/en-GB/plg_system_stats.ini @@ -4,24 +4,24 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SYSTEM_STATS="System - Joomla! Statistics" -PLG_SYSTEM_STATS_BTN_NEVER_SEND="Never" -PLG_SYSTEM_STATS_BTN_SEND_ALWAYS="Always" +PLG_SYSTEM_STATS_BTN_NEVER_SEND="No" +PLG_SYSTEM_STATS_BTN_SEND_ALWAYS="Yes, I'll help Joomla!" PLG_SYSTEM_STATS_BTN_SEND_NOW="Once" PLG_SYSTEM_STATS_INTERVAL_LABEL="Interval (hours)" PLG_SYSTEM_STATS_LABEL_CMS_VERSION="CMS Version" PLG_SYSTEM_STATS_LABEL_DB_TYPE="DB Type" PLG_SYSTEM_STATS_LABEL_DB_VERSION="DB Version" -PLG_SYSTEM_STATS_LABEL_MESSAGE_TITLE="Joomla! would like your permission to collect some basic statistics." +PLG_SYSTEM_STATS_LABEL_MESSAGE_TITLE="Help us make Joomla! better!" PLG_SYSTEM_STATS_LABEL_PHP_VERSION="PHP Version" PLG_SYSTEM_STATS_LABEL_SERVER_OS="Server OS" PLG_SYSTEM_STATS_LABEL_UNIQUE_ID="Unique ID" PLG_SYSTEM_STATS_MODE_LABEL="Mode" PLG_SYSTEM_STATS_MODE_OPTION_ALWAYS_SEND="Always send" PLG_SYSTEM_STATS_MODE_OPTION_NEVER_SEND="Never send" -PLG_SYSTEM_STATS_MODE_OPTION_ON_DEMAND="On demand" +PLG_SYSTEM_STATS_MODE_OPTION_ON_DEMAND="Ask again" PLG_SYSTEM_STATS_MSG_ALLOW_SENDING_DATA="Enable Joomla Statistics?" -PLG_SYSTEM_STATS_MSG_JOOMLA_WANTS_TO_SEND_DATA="To better understand our install base and end user environments it is helpful if you send some site information back to a Joomla! controlled central server. No identifying data is captured at any point. You can change these settings later from Plugins → System - Joomla! Statistics." -PLG_SYSTEM_STATS_MSG_WHAT_DATA_WILL_BE_SENT="Select here to see the information that will be sent." +PLG_SYSTEM_STATS_MSG_JOOMLA_WANTS_TO_SEND_DATA="We want to increase the compatibility of our Joomla! software with our user's server settings. Therefore we need anonymous data from your site to better understand the install base and end user environments. All data is anonymised and only sent to a Joomla! controlled central server. You can change these settings later from Plugins → System - Joomla! Statistics." +PLG_SYSTEM_STATS_MSG_WHAT_DATA_WILL_BE_SENT="No identifying data is captured at any point. Select here to review." PLG_SYSTEM_STATS_RESET_UNIQUE_ID="Reset Unique ID" PLG_SYSTEM_STATS_SETTING="Setting" PLG_SYSTEM_STATS_STATISTICS="Statistics" diff --git a/administrator/language/en-GB/plg_task_checkfiles.ini b/administrator/language/en-GB/plg_task_checkfiles.ini index ec31695e03b97..cee47448cc908 100644 --- a/administrator/language/en-GB/plg_task_checkfiles.ini +++ b/administrator/language/en-GB/plg_task_checkfiles.ini @@ -4,13 +4,15 @@ ; Note : All ini files need to be saved as UTF-8 PLG_TASK_CHECK_FILES="Task - Check Files" -PLG_TASK_CHECK_FILES_LABEL_DIMENSION_LIMIT="Limit" +PLG_TASK_CHECK_FILES_LABEL_DIMENSION_LIMIT="Limit (px)" +PLG_TASK_CHECK_FILES_LABEL_MAXIMAGES="Maximum Images" +PLG_TASK_CHECK_FILES_LABEL_MAXIMAGES_DESC="The maximum number of images to be processed in a single run. Setting this number too high may cause the task to timeout." PLG_TASK_CHECK_FILES_LABEL_DIRECTORY="Directory" PLG_TASK_CHECK_FILES_LABEL_IMAGE_DIMENSION="Dimension" PLG_TASK_CHECK_FILES_LOG_IMAGE_PATH_NA="Image path does exist!" PLG_TASK_CHECK_FILES_LOG_IMAGE_SAVE_FAIL="Failed to save image file" PLG_TASK_CHECK_FILES_LOG_RESIZE_FAIL="Failed to resize image due to an error in plugin logic..." PLG_TASK_CHECK_FILES_LOG_RESIZING_IMAGE="Found image of size %1$sx%2$s px; resizing to %3$sx%4$s px. File: %5$s" -PLG_TASK_CHECK_FILES_TASK_IMAGE_SIZE_DESC="Check images, resize if larger than allowed." +PLG_TASK_CHECK_FILES_TASK_IMAGE_SIZE_DESC="Check images, resize if larger than allowed. Attention: The original file will be overwritten!" PLG_TASK_CHECK_FILES_TASK_IMAGE_SIZE_TITLE="Image Size Check" PLG_TASK_CHECK_FILES_XML_DESCRIPTION="Offers task routines for checking for oversized files, and related actions if possible." diff --git a/administrator/language/en-GB/plg_task_sitestatus.ini b/administrator/language/en-GB/plg_task_sitestatus.ini index 7cf4d22e86257..4d57ca42c11eb 100644 --- a/administrator/language/en-GB/plg_task_sitestatus.ini +++ b/administrator/language/en-GB/plg_task_sitestatus.ini @@ -10,7 +10,7 @@ PLG_TASK_SITE_STATUS_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configu PLG_TASK_SITE_STATUS_ERROR_WRITE_FAILED="Could not write to the configuration file!" PLG_TASK_SITE_STATUS_ROUTINE_END_LOG_MESSAGE="ToggleOffline return code is: %1$d. Processing Time: %2$.2f seconds." PLG_TASK_SITE_STATUS_TASK_LOG_SITE_STATUS="Site was %1$s, is now %2$s." -PLG_TASK_SITE_STATUS_SET_OFFLINE_DESC="Sets site status to online on each run." +PLG_TASK_SITE_STATUS_SET_OFFLINE_DESC="Sets site status to offline on each run." PLG_TASK_SITE_STATUS_SET_OFFLINE_ROUTINE_END_LOG_MESSAGE="SetOffline return code is: %1$d. Processing Time: %2$.2f seconds." PLG_TASK_SITE_STATUS_SET_OFFLINE_TITLE="Set Site Offline" PLG_TASK_SITE_STATUS_SET_ONLINE_DESC="Sets site status to online on each run." diff --git a/administrator/manifests/files/joomla.xml b/administrator/manifests/files/joomla.xml index caa01fe6e44a0..77e57ae86ed26 100644 --- a/administrator/manifests/files/joomla.xml +++ b/administrator/manifests/files/joomla.xml @@ -7,7 +7,7 @@ (C) 2019 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt 4.1.0-dev - December 2021 + January 2022 FILES_JOOMLA_XML_DESCRIPTION administrator/components/com_admin/script.php diff --git a/administrator/manifests/packages/pkg_en-GB.xml b/administrator/manifests/packages/pkg_en-GB.xml index 23e3134adce9c..a2d47e858cbda 100644 --- a/administrator/manifests/packages/pkg_en-GB.xml +++ b/administrator/manifests/packages/pkg_en-GB.xml @@ -3,7 +3,7 @@ English (en-GB) Language Pack en-GB 4.1.0.1 - December 2021 + January 2022 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/modules/mod_latest/src/Helper/LatestHelper.php b/administrator/modules/mod_latest/src/Helper/LatestHelper.php index 4063ed752c04f..5353913a538db 100644 --- a/administrator/modules/mod_latest/src/Helper/LatestHelper.php +++ b/administrator/modules/mod_latest/src/Helper/LatestHelper.php @@ -96,7 +96,8 @@ public static function getList(Registry &$params, ArticlesModel $model) { $item->link = ''; - if ($user->authorise('core.edit', 'com_content.article.' . $item->id)) + if ($user->authorise('core.edit', 'com_content.article.' . $item->id) + || ($user->authorise('core.edit.own', 'com_content.article.' . $item->id) && ($userId === $item->created_by))) { $item->link = Route::_('index.php?option=com_content&task=article.edit&id=' . $item->id); } diff --git a/administrator/modules/mod_popular/src/Helper/PopularHelper.php b/administrator/modules/mod_popular/src/Helper/PopularHelper.php index 83d9fd226c424..1572b9b821013 100644 --- a/administrator/modules/mod_popular/src/Helper/PopularHelper.php +++ b/administrator/modules/mod_popular/src/Helper/PopularHelper.php @@ -87,7 +87,8 @@ public static function getList(Registry &$params, ArticlesModel $model) { $item->link = ''; - if ($user->authorise('core.edit', 'com_content.article.' . $item->id)) + if ($user->authorise('core.edit', 'com_content.article.' . $item->id) + || ($user->authorise('core.edit.own', 'com_content.article.' . $item->id) && ($userId === $item->created_by))) { $item->link = Route::_('index.php?option=com_content&task=article.edit&id=' . $item->id); } diff --git a/api/components/com_categories/src/Controller/CategoriesController.php b/api/components/com_categories/src/Controller/CategoriesController.php index 71ed5fae6007b..e0c7b8d29ded1 100644 --- a/api/components/com_categories/src/Controller/CategoriesController.php +++ b/api/components/com_categories/src/Controller/CategoriesController.php @@ -65,7 +65,7 @@ protected function preprocessSaveData(array $data): array * * @return integer The record ID on success, false on failure * - * @since __DEPLOY_VERSION__ + * @since 4.0.6 */ protected function save($recordKey = null) { diff --git a/api/components/com_config/src/Controller/ApplicationController.php b/api/components/com_config/src/Controller/ApplicationController.php index 038b2df81972a..164f9d30a2328 100644 --- a/api/components/com_config/src/Controller/ApplicationController.php +++ b/api/components/com_config/src/Controller/ApplicationController.php @@ -115,7 +115,7 @@ public function edit() $oldData = $model->getData(); $data = array_replace($oldData, $data); - // TODO: Not the cleanest thing ever but it works... + // @todo: Not the cleanest thing ever but it works... Form::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/forms'); // Must load after serving service-requests diff --git a/api/components/com_config/src/Controller/ComponentController.php b/api/components/com_config/src/Controller/ComponentController.php index 484433aad254a..523bceb5907ec 100644 --- a/api/components/com_config/src/Controller/ComponentController.php +++ b/api/components/com_config/src/Controller/ComponentController.php @@ -114,7 +114,7 @@ public function edit() $option = $this->input->get('component_name'); - // TODO: Not the cleanest thing ever but it works... + // @todo: Not the cleanest thing ever but it works... Form::addFormPath(JPATH_ADMINISTRATOR . '/components/' . $option); // Must load after serving service-requests diff --git a/api/components/com_config/src/View/Component/JsonapiView.php b/api/components/com_config/src/View/Component/JsonapiView.php index 97d6bc3c31529..613af3e74b946 100644 --- a/api/components/com_config/src/View/Component/JsonapiView.php +++ b/api/components/com_config/src/View/Component/JsonapiView.php @@ -43,7 +43,7 @@ public function displayList(array $items = null) if ($component === null || !$component->enabled) { - // TODO: exception component unavailable + // @todo: exception component unavailable throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_INVALID_COMPONENT_NAME'), 400); } diff --git a/api/components/com_contact/src/Serializer/ContactSerializer.php b/api/components/com_contact/src/Serializer/ContactSerializer.php index 06231aa2f09e3..23fe7333f3b40 100644 --- a/api/components/com_contact/src/Serializer/ContactSerializer.php +++ b/api/components/com_contact/src/Serializer/ContactSerializer.php @@ -40,7 +40,7 @@ public function languageAssociations($model) { $resources = []; - // TODO: This can't be hardcoded in the future? + // @todo: This can't be hardcoded in the future? $serializer = new JoomlaSerializer($this->type); foreach ($model->associations as $association) diff --git a/api/components/com_content/src/Serializer/ContentSerializer.php b/api/components/com_content/src/Serializer/ContentSerializer.php index a3f74829e9ac6..5bf5fff93024f 100644 --- a/api/components/com_content/src/Serializer/ContentSerializer.php +++ b/api/components/com_content/src/Serializer/ContentSerializer.php @@ -37,7 +37,7 @@ public function languageAssociations($model) { $resources = []; - // TODO: This can't be hardcoded in the future? + // @todo: This can't be hardcoded in the future? $serializer = new JoomlaSerializer($this->type); foreach ($model->associations as $association) diff --git a/api/components/com_languages/src/Controller/OverridesController.php b/api/components/com_languages/src/Controller/OverridesController.php index 9ebb27ff5db9c..91a4c557d87fb 100644 --- a/api/components/com_languages/src/Controller/OverridesController.php +++ b/api/components/com_languages/src/Controller/OverridesController.php @@ -87,17 +87,17 @@ protected function save($recordKey = null) /** @var \Joomla\CMS\MVC\Model\AdminModel $model */ $model = $this->getModel(Inflector::singularize($this->contentType)); - $model->setState('filter.language', $this->input->post->get('lang_code')); - $model->setState('filter.client', $this->input->post->get('app')); - if (!$model) { throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_MODEL_CREATE')); } + $model->setState('filter.language', $this->input->post->get('lang_code')); + $model->setState('filter.client', $this->input->post->get('app')); + $data = $this->input->get('data', json_decode($this->input->json->getRaw(), true), 'array'); - // TODO: Not the cleanest thing ever but it works... + // @todo: Not the cleanest thing ever but it works... Form::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/forms'); // Validate the posted data. diff --git a/api/components/com_media/src/Controller/AdaptersController.php b/api/components/com_media/src/Controller/AdaptersController.php index 1831173a1ce72..a48950a03070d 100644 --- a/api/components/com_media/src/Controller/AdaptersController.php +++ b/api/components/com_media/src/Controller/AdaptersController.php @@ -13,7 +13,7 @@ use Joomla\CMS\MVC\Controller\ApiController; use Joomla\Component\Media\Administrator\Exception\InvalidPathException; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service controller. @@ -22,7 +22,7 @@ */ class AdaptersController extends ApiController { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * The content type of the item. diff --git a/api/components/com_media/src/Controller/MediaController.php b/api/components/com_media/src/Controller/MediaController.php index b9ed3e18023aa..e12c4c46db3a4 100644 --- a/api/components/com_media/src/Controller/MediaController.php +++ b/api/components/com_media/src/Controller/MediaController.php @@ -18,7 +18,7 @@ use Joomla\CMS\MVC\Controller\ApiController; use Joomla\Component\Media\Administrator\Exception\FileExistsException; use Joomla\Component\Media\Administrator\Exception\InvalidPathException; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; use Joomla\Component\Media\Api\Model\MediumModel; use Joomla\String\Inflector; use Tobscure\JsonApi\Exception\InvalidParameterException; @@ -30,7 +30,7 @@ */ class MediaController extends ApiController { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * The content type of the item. @@ -130,7 +130,7 @@ public function displayList() $filter = InputFilter::getInstance(); // Search for files matching (part of) a name or glob pattern. - if ($doSearch = array_key_exists('search', $apiFilterInfo)) + if (\array_key_exists('search', $apiFilterInfo)) { $this->modelState->set('search', $filter->clean($apiFilterInfo['search'], 'STRING')); diff --git a/api/components/com_media/src/Model/AdapterModel.php b/api/components/com_media/src/Model/AdapterModel.php index 4141a6c3cdccc..2ddd9743ec657 100644 --- a/api/components/com_media/src/Model/AdapterModel.php +++ b/api/components/com_media/src/Model/AdapterModel.php @@ -12,7 +12,7 @@ \defined('_JEXEC') or die; use Joomla\CMS\MVC\Model\BaseModel; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service model supporting a single adapter item. @@ -21,7 +21,7 @@ */ class AdapterModel extends BaseModel { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * Method to get a single adapter. diff --git a/api/components/com_media/src/Model/AdaptersModel.php b/api/components/com_media/src/Model/AdaptersModel.php index db3f885057cfe..c102c175ce168 100644 --- a/api/components/com_media/src/Model/AdaptersModel.php +++ b/api/components/com_media/src/Model/AdaptersModel.php @@ -14,7 +14,7 @@ use Joomla\CMS\MVC\Model\BaseModel; use Joomla\CMS\MVC\Model\ListModelInterface; use Joomla\CMS\Pagination\Pagination; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service model supporting lists of media adapters. @@ -23,7 +23,7 @@ */ class AdaptersModel extends BaseModel implements ListModelInterface { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * A hacky way to enable the standard jsonapiView::displayList() to create a Pagination object, diff --git a/api/components/com_media/src/Model/MediaModel.php b/api/components/com_media/src/Model/MediaModel.php index 50d37fa8e9855..ef0612191072b 100644 --- a/api/components/com_media/src/Model/MediaModel.php +++ b/api/components/com_media/src/Model/MediaModel.php @@ -18,7 +18,7 @@ use Joomla\CMS\Pagination\Pagination; use Joomla\Component\Media\Administrator\Exception\FileNotFoundException; use Joomla\Component\Media\Administrator\Model\ApiModel; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service model supporting lists of media items. @@ -27,7 +27,7 @@ */ class MediaModel extends BaseModel implements ListModelInterface { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * Instance of com_media's ApiModel diff --git a/api/components/com_media/src/Model/MediumModel.php b/api/components/com_media/src/Model/MediumModel.php index e30ec88d3681b..d2a9e651848e9 100644 --- a/api/components/com_media/src/Model/MediumModel.php +++ b/api/components/com_media/src/Model/MediumModel.php @@ -19,7 +19,7 @@ use Joomla\Component\Media\Administrator\Exception\FileNotFoundException; use Joomla\Component\Media\Administrator\Exception\InvalidPathException; use Joomla\Component\Media\Administrator\Model\ApiModel; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service model supporting a single media item. @@ -28,7 +28,7 @@ */ class MediumModel extends BaseModel { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * Instance of com_media's ApiModel @@ -97,6 +97,18 @@ public function save($path = null): string ['adapter' => $adapterName, 'path' => $path] = $this->resolveAdapterAndPath($path); + // Trim adapter information from path + if ($pos = strpos($path, ':/')) + { + $path = substr($path, $pos + 1); + } + + // Trim adapter information from old path + if ($pos = strpos($oldPath, ':/')) + { + $oldPath = substr($oldPath, $pos + 1); + } + $resultPath = ''; /** diff --git a/api/components/com_media/src/View/Adapters/JsonapiView.php b/api/components/com_media/src/View/Adapters/JsonapiView.php index 7f4e7a3de084c..7c059674a9aa9 100644 --- a/api/components/com_media/src/View/Adapters/JsonapiView.php +++ b/api/components/com_media/src/View/Adapters/JsonapiView.php @@ -12,7 +12,7 @@ \defined('_JEXEC') or die; use Joomla\CMS\MVC\View\JsonApiView as BaseApiView; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service view @@ -21,7 +21,7 @@ */ class JsonapiView extends BaseApiView { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * The fields to render item in the documents diff --git a/api/components/com_media/src/View/Media/JsonapiView.php b/api/components/com_media/src/View/Media/JsonapiView.php index 69169719fae24..bc8d0db67ccec 100644 --- a/api/components/com_media/src/View/Media/JsonapiView.php +++ b/api/components/com_media/src/View/Media/JsonapiView.php @@ -12,7 +12,7 @@ \defined('_JEXEC') or die; use Joomla\CMS\MVC\View\JsonApiView as BaseApiView; -use Joomla\Component\Media\Api\Helper\AdapterTrait; +use Joomla\Component\Media\Administrator\Provider\ProviderManagerHelperTrait; /** * Media web service view @@ -21,7 +21,7 @@ */ class JsonapiView extends BaseApiView { - use AdapterTrait; + use ProviderManagerHelperTrait; /** * The fields to render item in the documents diff --git a/api/components/com_newsfeeds/src/Serializer/NewsfeedSerializer.php b/api/components/com_newsfeeds/src/Serializer/NewsfeedSerializer.php index 2571e85e61cd4..ed37348216069 100644 --- a/api/components/com_newsfeeds/src/Serializer/NewsfeedSerializer.php +++ b/api/components/com_newsfeeds/src/Serializer/NewsfeedSerializer.php @@ -40,7 +40,7 @@ public function languageAssociations($model) { $resources = []; - // TODO: This can't be hardcoded in the future? + // @todo: This can't be hardcoded in the future? $serializer = new JoomlaSerializer($this->type); foreach ($model->associations as $association) diff --git a/api/language/en-GB/install.xml b/api/language/en-GB/install.xml index 4a0ff0fa19e11..7a97416e4d1e9 100644 --- a/api/language/en-GB/install.xml +++ b/api/language/en-GB/install.xml @@ -3,7 +3,7 @@ English (en-GB) en-GB 4.1.0 - December 2021 + January 2022 Joomla! Project admin@joomla.org www.joomla.org diff --git a/api/language/en-GB/langmetadata.xml b/api/language/en-GB/langmetadata.xml index d334090823c7f..c71909c412579 100644 --- a/api/language/en-GB/langmetadata.xml +++ b/api/language/en-GB/langmetadata.xml @@ -2,7 +2,7 @@ English (en-GB) 4.1.0 - December 2021 + January 2022 Joomla! Project admin@joomla.org www.joomla.org diff --git a/build/build-modules-js/init/exemptions/tinymce.es6.js b/build/build-modules-js/init/exemptions/tinymce.es6.js index ab74b5225ca1c..3c2d4e28bc7f4 100644 --- a/build/build-modules-js/init/exemptions/tinymce.es6.js +++ b/build/build-modules-js/init/exemptions/tinymce.es6.js @@ -74,17 +74,17 @@ module.exports.tinyMCE = async (packageName, version) => { let cssContent = await readFile('build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.css', { encoding: 'utf8' }); cssContent = await Postcss([CssNano()]).process(cssContent, { from: undefined }); // Get the JS - let jsContent = await readFile('build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es5.js', { encoding: 'utf8' }); + let jsContent = await readFile('build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es6.js', { encoding: 'utf8' }); jsContent = await minify(jsContent, { sourceMap: false, format: { comments: false } }); // Write the HTML file const htmlContent = ` - + - + `; diff --git a/build/media_source/com_content/js/admin-article-readmore.es6.js b/build/media_source/com_content/js/admin-article-readmore.es6.js index 7494ff1ee73e3..6b569f1597647 100644 --- a/build/media_source/com_content/js/admin-article-readmore.es6.js +++ b/build/media_source/com_content/js/admin-article-readmore.es6.js @@ -20,7 +20,7 @@ } else if (content && !content.match(//i)) { Joomla.editors.instances[editor].replaceSelection('
'); } else { - // TODO replace with joomla-alert + // @todo replace with joomla-alert alert(options.exists); return false; } diff --git a/build/media_source/com_finder/js/index.es6.js b/build/media_source/com_finder/js/index.es6.js index bc805cefa1ce0..b409b0c665724 100644 --- a/build/media_source/com_finder/js/index.es6.js +++ b/build/media_source/com_finder/js/index.es6.js @@ -10,11 +10,11 @@ Joomla = window.Joomla || {}; document.addEventListener('DOMContentLoaded', () => { Joomla.submitbutton = (pressbutton) => { - // TODO replace with joomla-alert + // @todo replace with joomla-alert if (pressbutton === 'index.purge' && !window.confirm(Joomla.Text._('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'))) { return false; } - // TODO replace with joomla-alert + // @todo replace with joomla-alert if (pressbutton === 'index.delete' && !window.confirm(Joomla.Text._('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'))) { return false; } diff --git a/build/media_source/com_finder/js/maps.es6.js b/build/media_source/com_finder/js/maps.es6.js index 73446c9641da8..0b5f74afbd0e7 100644 --- a/build/media_source/com_finder/js/maps.es6.js +++ b/build/media_source/com_finder/js/maps.es6.js @@ -10,7 +10,7 @@ Joomla = window.Joomla || {}; document.addEventListener('DOMContentLoaded', () => { Joomla.submitbutton = (pressbutton) => { - // TODO replace with joomla-alert + // @todo replace with joomla-alert if (pressbutton === 'map.delete' && !window.confirm(Joomla.Text._('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'))) { return false; } diff --git a/build/media_source/com_media/scss/components/_media-breadcrumb.scss b/build/media_source/com_media/scss/components/_media-breadcrumb.scss index 21fdc086d519a..faffa71558c62 100644 --- a/build/media_source/com_media/scss/components/_media-breadcrumb.scss +++ b/build/media_source/com_media/scss/components/_media-breadcrumb.scss @@ -1,11 +1,11 @@ .media-breadcrumb { display: flex; padding: 0; - margin: 0 auto 0 0; + margin-inline-end: auto; font-size: .9rem; line-height: $toolbar-height; background: transparent; - border-left: 1px solid $border-color; + border-inline-start: 1px solid $border-color; ol { display: flex; @@ -20,15 +20,16 @@ } .media-breadcrumb-item { - padding: 0 8px 0 22px; + padding-inline-end: 8px; + padding-inline-start: 22px; background-color: $breadcrumbs-bg; &:first-of-type { - padding-left: 16px; + padding-inline-start: 16px; } &:last-of-type { background-color: $breadcrumbs-current-bg; &::after { - border-left-color: $breadcrumbs-current-bg; + border-inline-start-color: $breadcrumbs-current-bg; } } &:hover { @@ -42,7 +43,7 @@ position: absolute; top: 0; bottom: 0; - left: 100%; + inset-inline-start: 100%; z-index: 2; display: block; width: 0; @@ -51,45 +52,12 @@ content: "" !important; border-top: 23px solid transparent; border-bottom: 23px solid transparent; - border-left: 10px solid transparent; + border-inline-start: 10px solid transparent; } &::before { - border-left-color: $border-color; + border-inline-start-color: $border-color; } &::after { - border-left-color: $breadcrumbs-bg; + border-inline-start-color: $breadcrumbs-bg; } } - -.breadcrumb-item + .breadcrumb-item::before { - display: none; -} - -// RTL override - -html[dir=rtl] .media-breadcrumb { - margin: 0 0 0 auto; -} - -html[dir=rtl] .media-breadcrumb-item::after, .media-breadcrumb-item::before { - right: 100%; - border-right: 10px solid transparent; - border-left: 0; -} - -html[dir=rtl] .media-breadcrumb-item { - padding: 0 22px 0 8px; -} - -html[dir=rtl] .media-breadcrumb-item::before { - border-right-color: #fafafa; -} - -html[dir=rtl] .media-breadcrumb-item:first-of-type { - padding-right: 16px; - padding-left: 0; -} - -html[dir=rtl] .media-breadcrumb-item:last-of-type::after { - border-right: 10px solid #fff; -} diff --git a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js index 9ecee7af98c26..53c06e11bc1e0 100644 --- a/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js +++ b/build/media_source/com_scheduler/js/admin-view-run-test-task.es6.js @@ -17,7 +17,8 @@ if (!window.Joomla) { const initRunner = () => { const paths = Joomla.getOptions('system.paths'); - const uri = `${paths ? `${paths.base}/index.php` : window.location.pathname}?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=%d`; + const token = Joomla.getOptions('com_scheduler.test-task.token'); + const uri = `${paths ? `${paths.base}/index.php` : window.location.pathname}?option=com_ajax&format=json&plugin=RunSchedulerTest&group=system&id=%d${token ? `&${token}=1` : ''}`; const modal = document.getElementById('scheduler-test-modal'); // Task output template @@ -41,7 +42,7 @@ const initRunner = () => { const id = parseInt(button.dataset.id, 10); const { title } = button.dataset; - modal.querySelector('.modal-title').innerHTML = Joomla.Text._('COM_SCHEDULER_TEST_RUN_TITLE').replace('%d', id); + modal.querySelector('.modal-title').innerHTML = Joomla.Text._('COM_SCHEDULER_TEST_RUN_TITLE').replace('%d', id.toString()); modal.querySelector('.modal-body > div').innerHTML = template.replace('%s', title); Joomla.request({ diff --git a/build/media_source/com_templates/css/admin-templates-default.css b/build/media_source/com_templates/css/admin-templates-default.css index 5f930753fff38..a92aa1935c07a 100644 --- a/build/media_source/com_templates/css/admin-templates-default.css +++ b/build/media_source/com_templates/css/admin-templates-default.css @@ -92,15 +92,6 @@ background-color: #F0F0EE; } -#jform_show_core { - display: inline; -} - -#jform_show_diff { - display: inline; - margin-left: 3.5em; -} - .switcher-label-0, .switcher-label-1 { white-space: nowrap; } diff --git a/build/media_source/com_users/js/admin-users-groups.es6.js b/build/media_source/com_users/js/admin-users-groups.es6.js index dd4c843f5edcd..becbe3fb3793b 100644 --- a/build/media_source/com_users/js/admin-users-groups.es6.js +++ b/build/media_source/com_users/js/admin-users-groups.es6.js @@ -14,7 +14,7 @@ Joomla = window.Joomla || {}; const cids = document.getElementsByName('cid[]'); for (let i = 0; i < cids.length; i += 1) { if (cids[i].checked && cids[i].parentNode.getAttribute('data-usercount') !== '0') { - // TODO replace with joomla-alert + // @todo replace with joomla-alert if (window.confirm(Joomla.Text._('COM_USERS_GROUPS_CONFIRM_DELETE'))) { Joomla.submitform(task); } diff --git a/build/media_source/plg_editors_codemirror/js/joomla-editor-codemirror.w-c.es6.js b/build/media_source/plg_editors_codemirror/js/joomla-editor-codemirror.w-c.es6.js index ecef691e569ec..ddb2ded4c2331 100644 --- a/build/media_source/plg_editors_codemirror/js/joomla-editor-codemirror.w-c.es6.js +++ b/build/media_source/plg_editors_codemirror/js/joomla-editor-codemirror.w-c.es6.js @@ -6,6 +6,13 @@ class CodemirrorEditor extends HTMLElement { this.host = window.location.origin; this.element = this.querySelector('textarea'); this.refresh = this.refresh.bind(this); + + // Observer instance to refresh the Editor when it become visible, eg after Tab switching + this.intersectionObserver = new IntersectionObserver((entries) => { + if (entries[0].isIntersecting && this.instance) { + this.instance.refresh(); + } + }, { threshold: 0 }); } static get observedAttributes() { @@ -124,11 +131,17 @@ class CodemirrorEditor extends HTMLElement { this.instance = window.CodeMirror.fromTextArea(this.element, this.options); this.instance.disable = (disabled) => this.setOption('readOnly', disabled ? 'nocursor' : false); Joomla.editors.instances[this.element.id] = this.instance; + + // Watch when the element in viewport, and refresh the editor + this.intersectionObserver.observe(this); } disconnectedCallback() { // Remove from the Joomla API delete Joomla.editors.instances[this.element.id]; + + // Remove from observer + this.intersectionObserver.unobserve(this); } refresh(element) { diff --git a/build/media_source/plg_editors_tinymce/js/plugins/highlighter/plugin.es5.js b/build/media_source/plg_editors_tinymce/js/plugins/highlighter/plugin.es5.js deleted file mode 100644 index 910370e37e2d7..0000000000000 --- a/build/media_source/plg_editors_tinymce/js/plugins/highlighter/plugin.es5.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * plugin.js - * - * Original code by Arjan Haverkamp - * Copyright 2013-2015 Arjan Haverkamp (arjan@webgear.nl) - * - * Adapted for use in Joomla by Dimitrios Grammatikogiannis - */ - /* eslint-disable no-undef */ - tinymce.PluginManager.add('highlightPlus', function(editor, url) { - function showSourceEditor() { - editor.focus(); - editor.selection.collapse(true); - - if (!editor.settings.codemirror) editor.settings.codemirror = {}; - - // Insert caret marker - if (editor.settings.codemirror && editor.settings.codemirror.saveCursorPosition) { - editor.selection.setContent(''); - } - - let codemirrorWidth = 800; - if (editor.settings.codemirror.width) { - codemirrorWidth = editor.settings.codemirror.width; - } - - let codemirrorHeight = 550; - if (editor.settings.codemirror.height) { - codemirrorHeight = editor.settings.codemirror.height; - } - - const buttonsConfig = [ - { - type: 'custom', - text: 'Ok', - name: 'codemirrorOk', - primary: true - }, - { - type: 'cancel', - text: 'Cancel', - name: 'codemirrorCancel' - } - ] - - const config = { - title: 'Source code', - url: url + '/source.html', - width: codemirrorWidth, - height: codemirrorHeight, - resizable: true, - maximizable: true, - fullScreen: editor.settings.codemirror.fullscreen, - saveCursorPosition: false, - buttons: buttonsConfig - } - - config.onAction = function (dialogApi, actionData) { - if (actionData.name === 'codemirrorOk') { - const doc = document.querySelectorAll('.tox-dialog__body-iframe iframe')[0]; - doc.contentWindow.tinymceHighlighterSubmit(); - editor.undoManager.add(); - win.close(); - } - } - - const win = editor.windowManager.openUrl(config); - - if (editor.settings.codemirror.fullscreen) { - win.fullscreen(true); - } - } - - editor.ui.registry.addButton('code', { - icon: 'sourcecode', - title: 'Source code+', - tooltip: 'Source code+', - onAction: showSourceEditor - }); - - editor.ui.registry.addMenuItem('code', { - icon: 'sourcecode', - text: 'Source code+', - onAction: showSourceEditor, - context: 'tools' - }); - }); diff --git a/build/media_source/plg_editors_tinymce/js/plugins/highlighter/plugin.es6.js b/build/media_source/plg_editors_tinymce/js/plugins/highlighter/plugin.es6.js new file mode 100644 index 0000000000000..8287139cb2a58 --- /dev/null +++ b/build/media_source/plg_editors_tinymce/js/plugins/highlighter/plugin.es6.js @@ -0,0 +1,85 @@ +/** + * plugin.js + * + * Original code by Arjan Haverkamp + * Copyright 2013-2015 Arjan Haverkamp (arjan@webgear.nl) + */ +window.tinymce.PluginManager.add('highlightPlus', (editor, url) => { + const showSourceEditor = () => { + editor.focus(); + editor.selection.collapse(true); + + if (!editor.settings.codemirror) editor.settings.codemirror = {}; + + // Insert caret marker + if (editor.settings.codemirror && editor.settings.codemirror.saveCursorPosition) { + editor.selection.setContent(''); + } + + let codemirrorWidth = 800; + if (editor.settings.codemirror.width) { + codemirrorWidth = editor.settings.codemirror.width; + } + + let codemirrorHeight = 550; + if (editor.settings.codemirror.height) { + codemirrorHeight = editor.settings.codemirror.height; + } + + const buttonsConfig = [ + { + type: 'custom', + text: 'Ok', + name: 'codemirrorOk', + primary: true, + }, + { + type: 'cancel', + text: 'Cancel', + name: 'codemirrorCancel', + }, + ]; + + const config = { + title: 'Source code', + url: `${url}/source.html`, + width: codemirrorWidth, + height: codemirrorHeight, + resizable: true, + maximizable: true, + fullScreen: editor.settings.codemirror.fullscreen, + saveCursorPosition: false, + buttons: buttonsConfig, + }; + + config.onAction = (dialogApi, actionData) => { + if (actionData.name === 'codemirrorOk') { + const doc = document.querySelectorAll('.tox-dialog__body-iframe iframe')[0]; + doc.contentWindow.tinymceHighlighterSubmit(); + editor.undoManager.add(); + // eslint-disable-next-line no-use-before-define + win.close(); + } + }; + + const win = editor.windowManager.openUrl(config); + + if (editor.settings.codemirror.fullscreen) { + win.fullscreen(true); + } + }; + + editor.ui.registry.addButton('code', { + icon: 'sourcecode', + title: 'Source code+', + tooltip: 'Source code+', + onAction: showSourceEditor, + }); + + editor.ui.registry.addMenuItem('code', { + icon: 'sourcecode', + text: 'Source code+', + onAction: showSourceEditor, + context: 'tools', + }); +}); diff --git a/build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es5.js b/build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es6.js similarity index 54% rename from build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es5.js rename to build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es6.js index 0f72ffd2b605d..eb8b89046165b 100644 --- a/build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es5.js +++ b/build/media_source/plg_editors_tinymce/js/plugins/highlighter/source.es6.js @@ -3,13 +3,17 @@ * * Original code by Arjan Haverkamp * Copyright 2013-2015 Arjan Haverkamp (arjan@webgear.nl) - * - * Adapted for use in Joomla by Dimitrios Grammatikogiannis */ +if (!window.parent.Joomla || typeof window.parent.Joomla.getOptions !== 'function') { + throw new Error('Joomla API not found'); +} + +// Get the base path for CodeMirror +const rootPath = window.parent.Joomla.getOptions('system.paths').rootFull; +const cmPath = `${rootPath}/media/vendor/codemirror`; // CodeMirror settings -const CMsettings = { - path: '../../../../vendor/codemirror', +let CMsettings = { indentOnInit: true, config: { mode: 'htmlmixed', @@ -23,54 +27,66 @@ const CMsettings = { saveCursorPosition: true, styleActiveLine: true, }, - jsFiles: [// Default JS files - 'lib/codemirror.min.js', - 'addon/edit/matchbrackets.min.js', - 'mode/xml/xml.min.js', - 'mode/javascript/javascript.min.js', - 'mode/css/css.min.js', - 'mode/htmlmixed/htmlmixed.min.js', - 'addon/dialog/dialog.min.js', - 'addon/search/searchcursor.min.js', - 'addon/search/search.min.js', - 'addon/selection/active-line.min.js', + jsFiles: [ + // Default JS files + `${cmPath}/lib/codemirror.min.js`, + `${cmPath}/addon/edit/matchbrackets.min.js`, + `${cmPath}/mode/xml/xml.min.js`, + `${cmPath}/mode/javascript/javascript.min.js`, + `${cmPath}/mode/css/css.min.js`, + `${cmPath}/mode/htmlmixed/htmlmixed.min.js`, + `${cmPath}/addon/dialog/dialog.min.js`, + `${cmPath}/addon/search/searchcursor.min.js`, + `${cmPath}/addon/search/search.min.js`, + `${cmPath}/addon/selection/active-line.min.js`, ], - cssFiles: [// Default CSS files - 'lib/codemirror.css', - 'addon/dialog/dialog.css', + cssFiles: [ + // Default CSS files + `${cmPath}/lib/codemirror.css`, + `${cmPath}/addon/dialog/dialog.css`, ], }; -// Global vars: -let tinymce; // Reference to TinyMCE -let editor; // Reference to TinyMCE editor -let codemirror; // CodeMirror instance -let chr = 0; // Unused utf-8 character, placeholder for cursor +// Declare some variables: +let tinymce; // Reference to TinyMCE +let editor; // Reference to TinyMCE editor +let codemirror; // CodeMirror instance +const chr = 0; // Unused utf-8 character, placeholder for cursor const isMac = /macintosh|mac os/i.test(navigator.userAgent); +// Utility function to load CodeMirror script files +const loadScript = (url) => new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.src = url; + script.onload = () => resolve(); + script.onerror = () => reject(new Error(`Failed to load the script ${url}`)); + document.head.appendChild(script); +}); + /** * Find the depth level */ const findDepth = (haystack, needle) => { const idx = haystack.indexOf(needle); let depth = 0; - for (let x = idx -1; x >= 0; x--) { - switch(haystack.charAt(x)) { - case '<': depth--; break; - case '>': depth++; break; - case '&': depth++; break; + for (let x = idx - 1; x >= 0; x -= 1) { + switch (haystack.charAt(x)) { + case '<': depth -= 1; break; + case '>': depth += 1; break; + case '&': depth += 1; break; + default: break; } } return depth; -} +}; /** * This function is called by plugin.js, when user clicks 'Ok' button */ window.tinymceHighlighterSubmit = () => { const cc = '�'; - const isDirty = codemirror.isDirty; - const doc = codemirror.doc; + const { isDirty } = codemirror; + const { doc } = codemirror; if (doc.somethingSelected()) { // Clear selection: @@ -80,13 +96,13 @@ window.tinymceHighlighterSubmit = () => { // Insert cursor placeholder (�) doc.replaceSelection(cc); - var pos = codemirror.getCursor(), - curLineHTML = doc.getLine(pos.line); + const pos = codemirror.getCursor(); + let curLineHTML = doc.getLine(pos.line); if (findDepth(curLineHTML, cc) !== 0) { // Cursor is inside a , don't set cursor: curLineHTML = curLineHTML.replace(cc, ''); - doc.replaceRange(curLineHTML, CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line)); + doc.replaceRange(curLineHTML, window.CodeMirror.Pos(pos.line, 0), window.CodeMirror.Pos(pos.line)); } // Submit HTML to TinyMCE: @@ -95,17 +111,17 @@ window.tinymceHighlighterSubmit = () => { const code = codemirror.getValue(); /* Regex to check if inside script or style tags */ - const ccScript = new RegExp("(.*?)" + cc + "(.*?)<\/script>", "ms"); - const ccStyle = new RegExp("(.*?)" + cc + "(.*?)<\/style>", "ms"); + const ccScript = new RegExp(`(.*?)${cc}(.*?)`, 'ms'); + const ccStyle = new RegExp(`(.*?)${cc}(.*?)`, 'ms'); /* Regex to check if in beginning or end or if between < & > */ - const ccLocationCheck = new RegExp("<[^>]*(" + cc + ").*>|^(" + cc + ")|(" + cc + ")$"); + const ccLocationCheck = new RegExp(`<[^>]*(${cc}).*>|^(${cc})|(${cc})$`); if ( - code.search(ccScript) !== -1 || - code.search(ccStyle) !== -1 || - code.search(ccLocationCheck) !== -1 - ){ + code.search(ccScript) !== -1 + || code.search(ccStyle) !== -1 + || code.search(ccLocationCheck) !== -1 + ) { editor.setContent(code.replace(cc, '')); } else { editor.setContent(code.replace(cc, '')); @@ -117,26 +133,40 @@ window.tinymceHighlighterSubmit = () => { } // Set cursor: - var el = editor.dom.select('span#CmCaReT')[0]; + const el = editor.dom.select('span#CmCaReT')[0]; if (el) { editor.selection.scrollIntoView(el); - editor.selection.setCursorLocation(el,0); + editor.selection.setCursorLocation(el, 0); editor.dom.remove(el); } -} +}; + +/** + * Listen for the escape key and close the modal + * + * @param {Event} evt + */ +document.addEventListener('keydown', (evt) => { + const event = evt || window.event; + let isEscape = false; + if ('key' in event) isEscape = (event.key === 'Escape' || event.key === 'Esc'); + else isEscape = (event.keyCode === 27); + + if (isEscape) tinymce.activeEditor.windowManager.close(); +}); /** * Append some help text in the modal footer */ const start = () => { // Initialise (on load) - if (typeof(window.CodeMirror) !== 'function') { + if (typeof (window.CodeMirror) !== 'function') { throw new Error(`CodeMirror not found in "${CMsettings.path}", aborting...`); } // Create legend for keyboard shortcuts for find & replace: - const head = parent.document.querySelectorAll('.tox-dialog__footer')[0]; - const div = parent.document.createElement('div'); + const head = window.parent.document.querySelectorAll('.tox-dialog__footer')[0]; + const div = window.parent.document.createElement('div'); const td1 = ''; const td2 = ''; div.innerHTML = ` @@ -156,11 +186,12 @@ const start = () => { `; div.style.position = 'absolute'; - div.style.left = div.style.bottom = '5px'; + div.style.left = '5px'; + div.style.bottom = '5px'; head.appendChild(div); // Set CodeMirror cursor and bookmark to same position as cursor was in TinyMCE: - let html = editor.getContent({source_view: true}); + let html = editor.getContent({ source_view: true }); // [FIX] #6 z-index issue with table panel and source code dialog // editor.selection.getBookmark(); @@ -171,8 +202,7 @@ const start = () => { // Hide TinyMCE toolbar panels, [FIX] #6 z-index issue with table panel and source code dialog // https://github.com/christiaan/tinymce-codemirror/issues/6 tinymce.each(editor.contextToolbars, (toolbar) => { if (toolbar.panel) { toolbar.panel.hide(); } }); - - CodeMirror.defineInitHook((inst) => { + window.CodeMirror.defineInitHook((inst) => { // Move cursor to correct position: inst.focus(); const cursor = inst.getSearchCursor(String.fromCharCode(chr), false); @@ -184,7 +214,8 @@ const start = () => { // Indent all code, if so requested: if (editor.settings.codemirror.indentOnInit) { const last = inst.lineCount(); - inst.operation(function() { + inst.operation(() => { + // eslint-disable-next-line no-plusplus for (let i = 0; i < last; ++i) { inst.indentLine(i); } @@ -195,85 +226,50 @@ const start = () => { CMsettings.config.value = html; // Instantiate CodeMirror: - codemirror = CodeMirror(document.body, CMsettings.config); + codemirror = window.CodeMirror(document.body, CMsettings.config); codemirror.isDirty = false; codemirror.on('change', (inst) => { inst.isDirty = true; }); -} - -/** - * Listen for the escape key and close the modal - * - * @param {Event} evt - */ -document.addEventListener('keydown', (evt) => { - evt = evt || window.event; - let isEscape = false; - if ("key" in evt) - isEscape = (evt.key === "Escape" || evt.key === "Esc"); - else - isEscape = (evt.keyCode === 27); - - if (isEscape) - tinymce.activeEditor.windowManager.close(); -}); - -(() => { - // Initialise (before load) - tinymce = parent.tinymce; - if (!tinymce) { - throw new Error('tinyMCE not found'); - } - - editor = tinymce.activeEditor; - const userSettings = editor.settings.codemirror; - - if (userSettings.fullscreen) { - CMsettings.jsFiles.push('addon/display/fullscreen.min.js'); - CMsettings.cssFiles.push('addon/display/fullscreen.css'); - } - - // Merge config - for (const i in userSettings.config) { - CMsettings.config[i] = userSettings.config[i]; - } + codemirror.setSize('100%', '100%'); + codemirror.refresh(); +}; - // Merge jsFiles - for (const i in userSettings.jsFiles) { - if (!CMsettings.jsFiles.includes(userSettings.jsFiles[i])) { - CMsettings.jsFiles.push(userSettings.jsFiles[i]); - } - } +// Initialise +tinymce = window.parent.tinymce; +if (!tinymce) { + throw new Error('tinyMCE not found'); +} - // Merge cssFiles - for (const i in userSettings.cssFiles) { - if (!CMsettings.cssFiles.includes(userSettings.cssFiles[i])) { - CMsettings.cssFiles.push(userSettings.cssFiles[i]); - } - } +editor = tinymce.activeEditor; +const userSettings = editor.settings.codemirror; - // Add trailing slash to path - if (!/\/$/.test(CMsettings.path)) { - CMsettings.path += '/'; - } +if (userSettings.fullscreen) { + CMsettings.jsFiles.push(`${cmPath}/addon/display/fullscreen.min.js`); + CMsettings.cssFiles.push(`${cmPath}/addon/display/fullscreen.css`); +} - // Write stylesheets - for (let i = 0; i < CMsettings.cssFiles.length; i++) { - document.write(''); - } +// Merge config +CMsettings = { ...CMsettings, ...userSettings }; - // Write JS source files. Needs to be synchronous to ensure the correct order. - for (let i = 0; i < CMsettings.jsFiles.length; i++) { - document.write(''); - } +// Append the stylesheets +CMsettings.cssFiles.forEach((css) => { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = css; + document.head.appendChild(link); +}); +/** + * Append javascript files ensuring the order of execution. + * Then execute the start function. + */ +CMsettings.jsFiles.reduce((p, item) => p.then(() => loadScript(item)), Promise.resolve(true)).then(() => { // Borrowed from codemirror.js themeChanged function. Sets the theme's class names to the html element. // Without this, the background color outside of the codemirror wrapper element remains white. // [TMP] commented temporary, cause JS error: Uncaught TypeError: Cannot read property 'replace' of undefined if (CMsettings.config.theme) { document.documentElement.className += CMsettings.config.theme.replace(/(^|\s)\s*/g, ' cm-s-'); } - - window.onload = start; -})(); + start(); +}); diff --git a/build/media_source/plg_editors_tinymce/js/tinymce.es6.js b/build/media_source/plg_editors_tinymce/js/tinymce.es6.js index 795dc92d7f13b..aad5d4592ef9b 100644 --- a/build/media_source/plg_editors_tinymce/js/tinymce.es6.js +++ b/build/media_source/plg_editors_tinymce/js/tinymce.es6.js @@ -33,12 +33,14 @@ toggleButton.removeAttribute('disabled'); toggleButton.addEventListener('click', () => { if (Joomla.editors.instances[currentEditor.id].instance.isHidden()) { - toggleIcon.setAttribute('class', 'icon-eye'); Joomla.editors.instances[currentEditor.id].instance.show(); } else { - toggleIcon.setAttribute('class', 'icon-eye-slash'); Joomla.editors.instances[currentEditor.id].instance.hide(); } + + if (toggleIcon) { + toggleIcon.setAttribute('class', Joomla.editors.instances[currentEditor.id].instance.isHidden() ? 'icon-eye' : 'icon-eye-slash'); + } }); } }); diff --git a/build/media_source/plg_system_stats/js/stats-message.es6.js b/build/media_source/plg_system_stats/js/stats-message.es6.js index 8fc75fa01aede..31a9e4c3e4852 100644 --- a/build/media_source/plg_system_stats/js/stats-message.es6.js +++ b/build/media_source/plg_system_stats/js/stats-message.es6.js @@ -47,18 +47,6 @@ Joomla = window.Joomla || {}; } }); - // Allow once - document.addEventListener('click', (event) => { - if (event.target.classList.contains('js-pstats-btn-allow-once')) { - event.preventDefault(); - - // Remove message - joomlaAlert.close(); - - callback({ plugin: 'sendOnce' }); - } - }); - // Never allow document.addEventListener('click', (event) => { if (event.target.classList.contains('js-pstats-btn-allow-never')) { diff --git a/build/media_source/system/js/showon.es6.js b/build/media_source/system/js/showon.es6.js index 8d3ba4da4d161..d675c60e6ac9f 100644 --- a/build/media_source/system/js/showon.es6.js +++ b/build/media_source/system/js/showon.es6.js @@ -209,7 +209,7 @@ class Showon { })); } } else { - // TODO: If chosen or choices.js is active we should update them + // @todo: If chosen or choices.js is active we should update them field.disabled = !showfield; } }); diff --git a/build/media_source/templates/administrator/atum/scss/blocks/_icons.scss b/build/media_source/templates/administrator/atum/scss/blocks/_icons.scss index 671ac513c78b5..5528b46ec864a 100644 --- a/build/media_source/templates/administrator/atum/scss/blocks/_icons.scss +++ b/build/media_source/templates/administrator/atum/scss/blocks/_icons.scss @@ -38,7 +38,6 @@ border-color: $warning; } - .#{$jicon-css-prefix}-archive, .#{$jicon-css-prefix}-folder, .#{$fa-css-prefix}-folder { color: var(--template-text-dark); diff --git a/build/media_source/templates/administrator/atum/scss/blocks/_login.scss b/build/media_source/templates/administrator/atum/scss/blocks/_login.scss index 08a068b30771f..dd28e05015eb1 100644 --- a/build/media_source/templates/administrator/atum/scss/blocks/_login.scss +++ b/build/media_source/templates/administrator/atum/scss/blocks/_login.scss @@ -84,30 +84,18 @@ .form-control-feedback { position: absolute; - right: 0; + inset-inline-end: 0; bottom: -1.5rem; font-size: ($font-size-base * .75); - text-align: right; - - [dir=rtl] & { - right: auto; - left: 0; - text-align: left; - } + text-align: end; } .form-control-hint { position: absolute; top: .1rem; - right: 0; + inset-inline-end: 0; font-size: ($font-size-base * .75); - text-align: right; - - [dir=rtl] & { - right: auto; - left: 0; - text-align: left; - } + text-align: end; } } diff --git a/build/stubGenerator.php b/build/stubGenerator.php index d93b8d2f2d6de..f4b899cdece1a 100644 --- a/build/stubGenerator.php +++ b/build/stubGenerator.php @@ -61,6 +61,7 @@ class StubGenerator extends CliApplication public function doExecute() { $this->createExtensionNamespaceMap(); + $contentsByNamespace = []; $file = "isInterface() && $reflection->isFinal()) ? 'final ' : ''; $modifier = ($reflection->isAbstract() && !$reflection->isInterface()) ? $modifier . 'abstract ' : $modifier; + $namespaceSegments = explode('\\', $oldName); + $className = array_pop($namespaceSegments); + $targetNamespace = ltrim(implode('\\', $namespaceSegments), '\\'); + // If a deprecated version is available, write a stub class doc block with a deprecated tag if ($deprecatedVersion !== false) { - $file .= << $contents) + { + $file .= "namespace $namespace {\n"; + $file .= $contents; + $file .= "}\n\n"; } // And save the file locally diff --git a/components/com_config/src/View/Modules/HtmlView.php b/components/com_config/src/View/Modules/HtmlView.php index 77eb3743b1aa0..e5e3f5be92925 100644 --- a/components/com_config/src/View/Modules/HtmlView.php +++ b/components/com_config/src/View/Modules/HtmlView.php @@ -56,7 +56,7 @@ public function display($tpl = null) $lang->load('', JPATH_ADMINISTRATOR, $lang->getTag()); $lang->load('com_modules', JPATH_ADMINISTRATOR, $lang->getTag()); - // TODO Move and clean up + // @todo Move and clean up $module = (new \Joomla\Component\Modules\Administrator\Model\ModuleModel)->getItem(Factory::getApplication()->input->getInt('id')); $moduleData = $module->getProperties(); diff --git a/components/com_contact/src/Model/CategoryModel.php b/components/com_contact/src/Model/CategoryModel.php index 3c2cd902f5826..5726362dd1f6b 100644 --- a/components/com_contact/src/Model/CategoryModel.php +++ b/components/com_contact/src/Model/CategoryModel.php @@ -166,7 +166,7 @@ protected function getListQuery() ->select($this->getSlugColumn($query, 'a.id', 'a.alias') . ' AS slug') ->select($this->getSlugColumn($query, 'c.id', 'c.alias') . ' AS catslug') /** - * TODO: we actually should be doing it but it's wrong this way + * @todo: we actually should be doing it but it's wrong this way * . ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug, ' * . ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END AS catslug '); */ diff --git a/components/com_contact/src/Model/ContactModel.php b/components/com_contact/src/Model/ContactModel.php index 9fd7ba55de057..94795dc4bbddf 100644 --- a/components/com_contact/src/Model/ContactModel.php +++ b/components/com_contact/src/Model/ContactModel.php @@ -72,7 +72,7 @@ protected function populateState() if (Factory::getApplication()->isClient('api')) { - // TODO: remove this + // @todo: remove this $app->loadLanguage(); $this->setState('contact.id', Factory::getApplication()->input->post->getInt('id')); } diff --git a/components/com_contact/tmpl/category/default_items.php b/components/com_contact/tmpl/category/default_items.php index 02bbbd0d48aa8..b8936a325f095 100644 --- a/components/com_contact/tmpl/category/default_items.php +++ b/components/com_contact/tmpl/category/default_items.php @@ -12,6 +12,7 @@ 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\CMS\Uri\Uri; use Joomla\Component\Contact\Administrator\Helper\ContactHelper; @@ -99,7 +100,14 @@ class="inputbox" onchange="document.adminForm.submit();" params->get('show_image_heading')) : ?> image) : ?> - image, '', array('class' => 'contact-thumbnail img-thumbnail')); ?> + $item->image, + 'alt' => '', + 'class' => 'contact-thumbnail img-thumbnail', + ] + ); ?> escape($item->name); ?> diff --git a/components/com_contact/tmpl/contact/default.php b/components/com_contact/tmpl/contact/default.php index 0299548b3421e..24d326583bdbe 100644 --- a/components/com_contact/tmpl/contact/default.php +++ b/components/com_contact/tmpl/contact/default.php @@ -14,6 +14,7 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\FileLayout; +use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Router\Route; use Joomla\Component\Contact\Site\Helper\RouteHelper; @@ -97,11 +98,13 @@ item->image && $tparams->get('show_image')) : ?>
- item->image, - htmlspecialchars($this->item->name, ENT_QUOTES, 'UTF-8'), - array('itemprop' => 'image') + $this->item->image, + 'alt' => $this->item->name, + 'itemprop' => 'image', + ] ); ?>
diff --git a/components/com_content/src/Controller/ArticleController.php b/components/com_content/src/Controller/ArticleController.php index b180c8db37485..2c440673ce2ee 100644 --- a/components/com_content/src/Controller/ArticleController.php +++ b/components/com_content/src/Controller/ArticleController.php @@ -294,7 +294,7 @@ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'a_id') $append .= '&tmpl=' . $tmpl; } - // TODO This is a bandaid, not a long term solution. + // @todo This is a bandaid, not a long term solution. /** * if ($layout) * { diff --git a/components/com_content/src/Model/CategoryModel.php b/components/com_content/src/Model/CategoryModel.php index d75e439964654..10954b28e852b 100644 --- a/components/com_content/src/Model/CategoryModel.php +++ b/components/com_content/src/Model/CategoryModel.php @@ -395,7 +395,7 @@ public function getCategory() $this->_item->getParams()->set('access-create', true); } - // TODO: Why aren't we lazy loading the children and siblings? + // @todo: Why aren't we lazy loading the children and siblings? $this->_children = $this->_item->getChildren(); $this->_parent = false; diff --git a/components/com_content/tmpl/category/blog.php b/components/com_content/tmpl/category/blog.php index 5456cf33e9d61..cd6d656572c82 100644 --- a/components/com_content/tmpl/category/blog.php +++ b/components/com_content/tmpl/category/blog.php @@ -13,6 +13,7 @@ use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\FileLayout; +use Joomla\CMS\Layout\LayoutHelper; $app = Factory::getApplication(); @@ -54,8 +55,13 @@ params->get('show_description', 1) || $this->params->def('show_description_image', 1)) : ?>
params->get('show_description_image') && $this->category->getParams()->get('image')) : ?> - category->getParams()->get('image_alt')) && empty($this->category->getParams()->get('image_alt_empty')) ? '' : 'alt="' . htmlspecialchars($this->category->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8') . '"'; ?> - > + $this->category->getParams()->get('image'), + 'alt' => empty($this->category->getParams()->get('image_alt')) && empty($this->category->getParams()->get('image_alt_empty')) ? false : $this->category->getParams()->get('image_alt'), + ] + ); ?> params->get('show_description') && $this->category->description) : ?> @@ -78,12 +84,11 @@ lead_items)) : ?>