From 8ab9fd8e9a44b518859a7f40e2388eb2a7dab891 Mon Sep 17 00:00:00 2001 From: Stefan Wendhausen Date: Mon, 4 Sep 2023 16:26:15 +0200 Subject: [PATCH 01/21] [4.x] Remove punctuation marks Remember username E-mail (#41503) --- language/en-GB/com_users.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language/en-GB/com_users.ini b/language/en-GB/com_users.ini index fb506aeb48408..2ff24bcfa8d52 100644 --- a/language/en-GB/com_users.ini +++ b/language/en-GB/com_users.ini @@ -21,7 +21,7 @@ COM_USERS_EMAIL_REGISTERED_WITH_ACTIVATION_BODY="Hello {NAME},\n\nThank you for COM_USERS_EMAIL_REGISTERED_WITH_ACTIVATION_BODY_NOPW="Hello {NAME},\n\nThank you for registering at {SITENAME}. Your account is created and must be activated before you can use it.\nTo activate the account select the following link or copy-paste it in your browser:\n{ACTIVATE} \n\nAfter activation you may login to {SITEURL} using the following username and the password you entered during registration:\n\nUsername: {USERNAME}" COM_USERS_EMAIL_REGISTERED_WITH_ADMIN_ACTIVATION_BODY="Hello {NAME},\n\nThank you for registering at {SITENAME}. Your account is created and must be verified before you can use it.\n\nTo verify the account select the following link or copy-paste it in your browser:\n{ACTIVATE} \n\nAfter verification an administrator will be notified to activate your account. You'll receive a confirmation when it's done.\n\nOnce that account has been activated you may login to {SITEURL} using the following username and password:\n\nUsername: {USERNAME}\nPassword: {PASSWORD_CLEAR}" COM_USERS_EMAIL_REGISTERED_WITH_ADMIN_ACTIVATION_BODY_NOPW="Hello {NAME},\n\nThank you for registering at {SITENAME}. Your account is created and must be verified before you can use it.\n\nTo verify the account select the following link or copy-paste it in your browser:\n{ACTIVATE} \n\nAfter verification an administrator will be notified to activate your account. You'll receive a confirmation when it's done.\n\nOnce that account has been activated you may login to {SITEURL} using the following username and the password you entered during registration:\n\nUsername: {USERNAME}" -COM_USERS_EMAIL_USERNAME_REMINDER_BODY="Hello,\n\nA username reminder has been requested for your {SITENAME} account.\n\nYour username is {USERNAME}.\n\nTo login to your account, select the link below.\n\n{LINK_TEXT} \n\nThank you." +COM_USERS_EMAIL_USERNAME_REMINDER_BODY="Hello,\n\nA username reminder has been requested for your {SITENAME} account.\n\nYour username: {USERNAME}\n\nTo login to your account, select the link below.\n\n{LINK_TEXT} \n\nThank you." COM_USERS_EMAIL_USERNAME_REMINDER_SUBJECT="Your {SITENAME} username" COM_USERS_FIELD_PASSWORD_RESET_LABEL="Email Address" COM_USERS_FIELD_REMIND_EMAIL_LABEL="Email Address" From c71964df93ab9b1d9fc4b033eb87a4151e887a3d Mon Sep 17 00:00:00 2001 From: Christiane Maier-Stadtherr Date: Mon, 4 Sep 2023 18:33:21 +0200 Subject: [PATCH 02/21] Remove filter="url" for wrapper iframe (#37547) * Remove filter="url" for wrapper iframe * remove validate --------- --- components/com_wrapper/tmpl/wrapper/default.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/com_wrapper/tmpl/wrapper/default.xml b/components/com_wrapper/tmpl/wrapper/default.xml index c9598fd7e622a..7c04e6653ac44 100644 --- a/components/com_wrapper/tmpl/wrapper/default.xml +++ b/components/com_wrapper/tmpl/wrapper/default.xml @@ -18,8 +18,6 @@ type="url" label="COM_WRAPPER_FIELD_URL_LABEL" required="true" - filter="url" - validate="url" /> From f8858b3c82241b65fa180b4d25640af5afe407cb Mon Sep 17 00:00:00 2001 From: heelc29 <66922325+heelc29@users.noreply.github.com> Date: Mon, 4 Sep 2023 23:46:47 +0200 Subject: [PATCH 03/21] [4.3] add blank line eof (#41591) --- administrator/language/en-GB/com_actionlogs.sys.ini | 2 +- administrator/language/en-GB/com_associations.sys.ini | 2 +- administrator/language/en-GB/mod_toolbar.ini | 2 +- administrator/language/en-GB/plg_content_joomla.sys.ini | 2 +- administrator/language/en-GB/plg_content_vote.sys.ini | 2 +- administrator/language/en-GB/plg_extension_joomla.sys.ini | 2 +- administrator/language/en-GB/plg_extension_namespacemap.ini | 2 +- administrator/language/en-GB/plg_system_sef.sys.ini | 2 +- administrator/language/en-GB/plg_user_terms.sys.ini | 2 +- language/en-GB/mod_breadcrumbs.ini | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/administrator/language/en-GB/com_actionlogs.sys.ini b/administrator/language/en-GB/com_actionlogs.sys.ini index ef7ee6c78f570..8b66db209ac16 100644 --- a/administrator/language/en-GB/com_actionlogs.sys.ini +++ b/administrator/language/en-GB/com_actionlogs.sys.ini @@ -6,4 +6,4 @@ COM_ACTIONLOGS="User Actions Log" COM_ACTIONLOGS_VIEW_DEFAULT_DESC="Shows a list of user actions." COM_ACTIONLOGS_VIEW_DEFAULT_TITLE="User Action Log" -COM_ACTIONLOGS_XML_DESCRIPTION="Displays a log of actions performed by users on your website." \ No newline at end of file +COM_ACTIONLOGS_XML_DESCRIPTION="Displays a log of actions performed by users on your website." diff --git a/administrator/language/en-GB/com_associations.sys.ini b/administrator/language/en-GB/com_associations.sys.ini index 9e7d978ab5a83..ea124624a0773 100644 --- a/administrator/language/en-GB/com_associations.sys.ini +++ b/administrator/language/en-GB/com_associations.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 COM_ASSOCIATIONS="Multilingual Associations" -COM_ASSOCIATIONS_XML_DESCRIPTION="Improved multilingual content management component" \ No newline at end of file +COM_ASSOCIATIONS_XML_DESCRIPTION="Improved multilingual content management component" diff --git a/administrator/language/en-GB/mod_toolbar.ini b/administrator/language/en-GB/mod_toolbar.ini index 880c42614dad2..bc6cec4aad8c3 100644 --- a/administrator/language/en-GB/mod_toolbar.ini +++ b/administrator/language/en-GB/mod_toolbar.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 MOD_TOOLBAR="Toolbar" -MOD_TOOLBAR_XML_DESCRIPTION="This module shows the toolbar icons used to control actions throughout the Administrator area." \ No newline at end of file +MOD_TOOLBAR_XML_DESCRIPTION="This module shows the toolbar icons used to control actions throughout the Administrator area." diff --git a/administrator/language/en-GB/plg_content_joomla.sys.ini b/administrator/language/en-GB/plg_content_joomla.sys.ini index f1617db909a52..bb15f45c376d1 100644 --- a/administrator/language/en-GB/plg_content_joomla.sys.ini +++ b/administrator/language/en-GB/plg_content_joomla.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_CONTENT_JOOMLA="Content - Joomla" -PLG_CONTENT_JOOMLA_XML_DESCRIPTION="This plugin does category processing for core extensions; sends an email when new article is submitted in the Frontend." \ No newline at end of file +PLG_CONTENT_JOOMLA_XML_DESCRIPTION="This plugin does category processing for core extensions; sends an email when new article is submitted in the Frontend." diff --git a/administrator/language/en-GB/plg_content_vote.sys.ini b/administrator/language/en-GB/plg_content_vote.sys.ini index 089d239acf156..ef4b09ab0575e 100644 --- a/administrator/language/en-GB/plg_content_vote.sys.ini +++ b/administrator/language/en-GB/plg_content_vote.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_CONTENT_VOTE="Content - Vote" -PLG_VOTE_XML_DESCRIPTION="Add Voting functionality to Articles." \ No newline at end of file +PLG_VOTE_XML_DESCRIPTION="Add Voting functionality to Articles." diff --git a/administrator/language/en-GB/plg_extension_joomla.sys.ini b/administrator/language/en-GB/plg_extension_joomla.sys.ini index c461cdb61c03c..9c0e64f4be4f9 100644 --- a/administrator/language/en-GB/plg_extension_joomla.sys.ini +++ b/administrator/language/en-GB/plg_extension_joomla.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_EXTENSION_JOOMLA="Extension - Joomla" -PLG_EXTENSION_JOOMLA_XML_DESCRIPTION="Manage the update sites for extensions." \ No newline at end of file +PLG_EXTENSION_JOOMLA_XML_DESCRIPTION="Manage the update sites for extensions." diff --git a/administrator/language/en-GB/plg_extension_namespacemap.ini b/administrator/language/en-GB/plg_extension_namespacemap.ini index d32aa7ebe1df7..8c95b93561d55 100644 --- a/administrator/language/en-GB/plg_extension_namespacemap.ini +++ b/administrator/language/en-GB/plg_extension_namespacemap.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_EXTENSION_NAMESPACEMAP="Extension - Namespace Updater" -PLG_EXTENSION_NAMESPACEMAP_XML_DESCRIPTION="

Automatically builds and updates the administrator/cache/autoload_psr4.php file that is used to autoload extensions.

Warning! This plugin must be enabled as it runs on extension install, update and uninstall.

" \ No newline at end of file +PLG_EXTENSION_NAMESPACEMAP_XML_DESCRIPTION="

Automatically builds and updates the administrator/cache/autoload_psr4.php file that is used to autoload extensions.

Warning! This plugin must be enabled as it runs on extension install, update and uninstall.

" diff --git a/administrator/language/en-GB/plg_system_sef.sys.ini b/administrator/language/en-GB/plg_system_sef.sys.ini index db6f969889d14..a9fbc4a7ab8f4 100644 --- a/administrator/language/en-GB/plg_system_sef.sys.ini +++ b/administrator/language/en-GB/plg_system_sef.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SEF_XML_DESCRIPTION="Adds SEF support to links in the document. It operates directly on the HTML and does not require a special tag." -PLG_SYSTEM_SEF="System - SEF" \ No newline at end of file +PLG_SYSTEM_SEF="System - SEF" diff --git a/administrator/language/en-GB/plg_user_terms.sys.ini b/administrator/language/en-GB/plg_user_terms.sys.ini index 138ff07a90e5c..a5ac184576ace 100644 --- a/administrator/language/en-GB/plg_user_terms.sys.ini +++ b/administrator/language/en-GB/plg_user_terms.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_USER_TERMS="User - Terms and Conditions" -PLG_USER_TERMS_XML_DESCRIPTION="Basic plugin to request user's consent to the site's terms and conditions." \ No newline at end of file +PLG_USER_TERMS_XML_DESCRIPTION="Basic plugin to request user's consent to the site's terms and conditions." diff --git a/language/en-GB/mod_breadcrumbs.ini b/language/en-GB/mod_breadcrumbs.ini index 1d7475000a8c3..3aa6fb573efc9 100644 --- a/language/en-GB/mod_breadcrumbs.ini +++ b/language/en-GB/mod_breadcrumbs.ini @@ -11,4 +11,4 @@ MOD_BREADCRUMBS_FIELD_SHOWHOME_LABEL="Home" MOD_BREADCRUMBS_FIELD_SHOWLAST_LABEL="Last" MOD_BREADCRUMBS_HERE="You are here: " MOD_BREADCRUMBS_HOME="Home" -MOD_BREADCRUMBS_XML_DESCRIPTION="This module displays the Breadcrumbs." \ No newline at end of file +MOD_BREADCRUMBS_XML_DESCRIPTION="This module displays the Breadcrumbs." From ba0e0ec3a2270671f73f93f5a84ed29ee8a68ce8 Mon Sep 17 00:00:00 2001 From: David Jardin Date: Tue, 5 Sep 2023 12:12:16 +0200 Subject: [PATCH 04/21] allow numeric client ids in update server manifests (#41462) --- libraries/src/Updater/Adapter/ExtensionAdapter.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/src/Updater/Adapter/ExtensionAdapter.php b/libraries/src/Updater/Adapter/ExtensionAdapter.php index b2f266d664011..12f8793b92db4 100644 --- a/libraries/src/Updater/Adapter/ExtensionAdapter.php +++ b/libraries/src/Updater/Adapter/ExtensionAdapter.php @@ -300,7 +300,14 @@ public function findUpdate($options) if (isset($this->latest)) { if (isset($this->latest->client) && \strlen($this->latest->client)) { - $this->latest->client_id = ApplicationHelper::getClientInfo($this->latest->client, true)->id; + /** + * The client_id in the update XML manifest can be either an integer (backwards + * compatible with Joomla 1.6–3.10) or a string. Backwards compatibility with the + * integer key is provided as update servers with the legacy, numeric IDs cause PHP notices + * during update retrieval. The proper string key is one of 'site' or 'administrator'. + */ + $this->latest->client_id = is_numeric($this->latest->client) ? $this->latest->client + : ApplicationHelper::getClientInfo($this->latest->client, true)->id; unset($this->latest->client); } From de81247f92a2b18849b17d56d5cd51d18353e7f3 Mon Sep 17 00:00:00 2001 From: Martin Kopp Date: Tue, 5 Sep 2023 16:59:53 +0200 Subject: [PATCH 05/21] Joomla! 4.4.0 Beta 1 --- administrator/language/en-GB/install.xml | 2 +- administrator/language/en-GB/langmetadata.xml | 2 +- administrator/manifests/files/joomla.xml | 4 ++-- administrator/manifests/packages/pkg_en-GB.xml | 2 +- api/language/en-GB/install.xml | 2 +- api/language/en-GB/langmetadata.xml | 2 +- installation/language/en-GB/langmetadata.xml | 2 +- language/en-GB/install.xml | 2 +- language/en-GB/langmetadata.xml | 2 +- libraries/src/Application/ConsoleApplication.php | 4 ++-- libraries/src/Console/UpdateCoreCommand.php | 2 +- libraries/src/Version.php | 8 ++++---- 12 files changed, 17 insertions(+), 17 deletions(-) diff --git a/administrator/language/en-GB/install.xml b/administrator/language/en-GB/install.xml index f798341067548..7d5cd60a2fd41 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.4.0 - 2023-08 + 2023-09 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 1d189a9e64168..9f97275e2d064 100644 --- a/administrator/language/en-GB/langmetadata.xml +++ b/administrator/language/en-GB/langmetadata.xml @@ -2,7 +2,7 @@ English (en-GB) 4.4.0 - 2023-08 + 2023-09 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/manifests/files/joomla.xml b/administrator/manifests/files/joomla.xml index 67f8e1d9372ec..a3ce593117476 100644 --- a/administrator/manifests/files/joomla.xml +++ b/administrator/manifests/files/joomla.xml @@ -6,8 +6,8 @@ www.joomla.org (C) 2019 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt - 4.4.0-alpha5-dev - 2023-08 + 4.4.0-beta1 + 2023-09 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 e26bb5aedac04..3f062cd302eee 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.4.0.1 - 2023-08 + 2023-09 Joomla! Project admin@joomla.org www.joomla.org diff --git a/api/language/en-GB/install.xml b/api/language/en-GB/install.xml index 130a6e05576d5..c5145e46d0c1d 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.4.0 - 2023-08 + 2023-09 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 e425c7bce7b94..f2adbdea2a021 100644 --- a/api/language/en-GB/langmetadata.xml +++ b/api/language/en-GB/langmetadata.xml @@ -2,7 +2,7 @@ English (en-GB) 4.4.0 - 2023-08 + 2023-09 Joomla! Project admin@joomla.org www.joomla.org diff --git a/installation/language/en-GB/langmetadata.xml b/installation/language/en-GB/langmetadata.xml index 16cd1f991c601..34e12f0d755e9 100644 --- a/installation/language/en-GB/langmetadata.xml +++ b/installation/language/en-GB/langmetadata.xml @@ -2,7 +2,7 @@ English (United Kingdom) 4.4.0 - 2023-08 + 2023-09 Joomla! Project (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt diff --git a/language/en-GB/install.xml b/language/en-GB/install.xml index c5a3066ec1676..78b06f82c9d6c 100644 --- a/language/en-GB/install.xml +++ b/language/en-GB/install.xml @@ -3,7 +3,7 @@ English (en-GB) en-GB 4.4.0 - 2023-08 + 2023-09 Joomla! Project admin@joomla.org www.joomla.org diff --git a/language/en-GB/langmetadata.xml b/language/en-GB/langmetadata.xml index e703870127c4d..529c1d08fdf1a 100644 --- a/language/en-GB/langmetadata.xml +++ b/language/en-GB/langmetadata.xml @@ -2,7 +2,7 @@ English (en-GB) 4.4.0 - 2023-08 + 2023-09 Joomla! Project admin@joomla.org www.joomla.org diff --git a/libraries/src/Application/ConsoleApplication.php b/libraries/src/Application/ConsoleApplication.php index 5dccee049511b..585fb3c18148d 100644 --- a/libraries/src/Application/ConsoleApplication.php +++ b/libraries/src/Application/ConsoleApplication.php @@ -592,7 +592,7 @@ protected function getDefaultInputDefinition(): InputDefinition * * @return mixed The user state or null. * - * @since __DEPLOY_VERSION__ + * @since 4.4.0 */ public function getUserState($key, $default = null) { @@ -615,7 +615,7 @@ public function getUserState($key, $default = null) * * @return mixed The request user state. * - * @since __DEPLOY_VERSION__ + * @since 4.4.0 */ public function getUserStateFromRequest($key, $request, $default = null, $type = 'none') { diff --git a/libraries/src/Console/UpdateCoreCommand.php b/libraries/src/Console/UpdateCoreCommand.php index efa681d7a8929..83af0e3c415a6 100644 --- a/libraries/src/Console/UpdateCoreCommand.php +++ b/libraries/src/Console/UpdateCoreCommand.php @@ -406,7 +406,7 @@ public function copyFileTo($file, $dir): void * * @return integer the number of errors * - * @since __DEPLOY_VERSION__ + * @since 4.4.0 */ public function checkSchema(): int { diff --git a/libraries/src/Version.php b/libraries/src/Version.php index 7e0168e622690..9bcc2b86956e7 100644 --- a/libraries/src/Version.php +++ b/libraries/src/Version.php @@ -66,7 +66,7 @@ final class Version * @var string * @since 3.8.0 */ - public const EXTRA_VERSION = 'alpha5-dev'; + public const EXTRA_VERSION = 'beta1'; /** * Development status. @@ -74,7 +74,7 @@ final class Version * @var string * @since 3.5 */ - public const DEV_STATUS = 'Development'; + public const DEV_STATUS = 'Beta'; /** * Code name. @@ -90,7 +90,7 @@ final class Version * @var string * @since 3.5 */ - public const RELDATE = '22-August-2023'; + public const RELDATE = '5-September-2023'; /** * Release time. @@ -98,7 +98,7 @@ final class Version * @var string * @since 3.5 */ - public const RELTIME = '16:01'; + public const RELTIME = '16:00'; /** * Release timezone. From 7ccce2bc8be8e9e2d581d1a1da7ffdc0479679f6 Mon Sep 17 00:00:00 2001 From: Martin Kopp Date: Tue, 5 Sep 2023 18:00:33 +0200 Subject: [PATCH 06/21] Revert to dev Signed-off-by: Martin Kopp --- administrator/manifests/files/joomla.xml | 2 +- libraries/src/Version.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/administrator/manifests/files/joomla.xml b/administrator/manifests/files/joomla.xml index a3ce593117476..dd2ba3c152d3d 100644 --- a/administrator/manifests/files/joomla.xml +++ b/administrator/manifests/files/joomla.xml @@ -6,7 +6,7 @@ www.joomla.org (C) 2019 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt - 4.4.0-beta1 + 4.4.0-beta2-dev 2023-09 FILES_JOOMLA_XML_DESCRIPTION diff --git a/libraries/src/Version.php b/libraries/src/Version.php index 9bcc2b86956e7..0946b9ef13fb3 100644 --- a/libraries/src/Version.php +++ b/libraries/src/Version.php @@ -66,7 +66,7 @@ final class Version * @var string * @since 3.8.0 */ - public const EXTRA_VERSION = 'beta1'; + public const EXTRA_VERSION = 'beta2-dev'; /** * Development status. @@ -74,7 +74,7 @@ final class Version * @var string * @since 3.5 */ - public const DEV_STATUS = 'Beta'; + public const DEV_STATUS = 'Development'; /** * Code name. @@ -98,7 +98,7 @@ final class Version * @var string * @since 3.5 */ - public const RELTIME = '16:00'; + public const RELTIME = '16:01'; /** * Release timezone. From f4702648d4e0c48a50aecd9c56eb23cb31eb94b3 Mon Sep 17 00:00:00 2001 From: Martin Carl Kopp <6154099+MacJoom@users.noreply.github.com> Date: Thu, 7 Sep 2023 00:13:04 +0200 Subject: [PATCH 07/21] Enable creating group through api by removing required flag from group.xml (#41141) --- administrator/components/com_users/forms/group.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/administrator/components/com_users/forms/group.xml b/administrator/components/com_users/forms/group.xml index 5d22be594bc8c..ab07760580862 100644 --- a/administrator/components/com_users/forms/group.xml +++ b/administrator/components/com_users/forms/group.xml @@ -5,7 +5,6 @@ name="id" type="hidden" default="0" - required="true" readonly="true" /> From 5c8d6df69d75c0cbfde715a061b8a52895f397be Mon Sep 17 00:00:00 2001 From: Denitz <197527+Denitz@users.noreply.github.com> Date: Thu, 7 Sep 2023 02:35:48 +0300 Subject: [PATCH 08/21] Update CleanCacheCommand.php (#41555) --- libraries/src/Console/CleanCacheCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Console/CleanCacheCommand.php b/libraries/src/Console/CleanCacheCommand.php index 72ce0dd27b87e..d2fa6cd6b955a 100644 --- a/libraries/src/Console/CleanCacheCommand.php +++ b/libraries/src/Console/CleanCacheCommand.php @@ -52,7 +52,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output): in $symfonyStyle->title('Cleaning System Cache'); $cache = $this->getApplication()->bootComponent('com_cache')->getMVCFactory(); - /** @var Joomla\Component\Cache\Administrator\Model\CacheModel $model */ + /** @var \Joomla\Component\Cache\Administrator\Model\CacheModel $model */ $model = $cache->createModel('Cache', 'Administrator', ['ignore_request' => true]); if ($input->getArgument('expired')) { From 61ff226552ad2d30a2b90f99ceb22c0e8e424697 Mon Sep 17 00:00:00 2001 From: Brian Teeman Date: Fri, 8 Sep 2023 13:18:08 +0100 Subject: [PATCH 09/21] [4.4] set_time_limit (#41523) --- .../com_finder/src/Controller/IndexController.php | 4 +++- .../com_finder/src/Controller/IndexerController.php | 4 +++- libraries/src/Application/DaemonApplication.php | 4 +++- libraries/src/Console/FinderIndexCommand.php | 4 +++- libraries/src/Filesystem/File.php | 8 ++++++-- libraries/src/Filesystem/Folder.php | 12 +++++++++--- libraries/src/Installer/InstallerHelper.php | 4 +++- 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/administrator/components/com_finder/src/Controller/IndexController.php b/administrator/components/com_finder/src/Controller/IndexController.php index 042253c2f23bc..918f7b08b21ec 100644 --- a/administrator/components/com_finder/src/Controller/IndexController.php +++ b/administrator/components/com_finder/src/Controller/IndexController.php @@ -79,7 +79,9 @@ public function purge() $this->checkToken(); // Remove the script time limit. - @set_time_limit(0); + if (\function_exists('set_time_limit')) { + set_time_limit(0); + } /** @var \Joomla\Component\Finder\Administrator\Model\IndexModel $model */ $model = $this->getModel('Index', 'Administrator'); diff --git a/administrator/components/com_finder/src/Controller/IndexerController.php b/administrator/components/com_finder/src/Controller/IndexerController.php index e00e30c1f04d4..77ee717310810 100644 --- a/administrator/components/com_finder/src/Controller/IndexerController.php +++ b/administrator/components/com_finder/src/Controller/IndexerController.php @@ -133,7 +133,9 @@ public function batch() ob_start(); // Remove the script time limit. - @set_time_limit(0); + if (\function_exists('set_time_limit')) { + set_time_limit(0); + } // Get the indexer state. $state = Indexer::getState(); diff --git a/libraries/src/Application/DaemonApplication.php b/libraries/src/Application/DaemonApplication.php index abdedf1484ca7..825ee9deceb6f 100644 --- a/libraries/src/Application/DaemonApplication.php +++ b/libraries/src/Application/DaemonApplication.php @@ -130,7 +130,9 @@ public function __construct(Cli $input = null, Registry $config = null, Dispatch parent::__construct($input, $config, null, null, $dispatcher); // Set some system limits. - @set_time_limit($this->config->get('max_execution_time', 0)); + if (\function_exists('set_time_limit')) { + set_time_limit($this->config->get('max_execution_time', 0)); + } if ($this->config->get('max_memory_limit') !== null) { ini_set('memory_limit', $this->config->get('max_memory_limit', '256M')); diff --git a/libraries/src/Console/FinderIndexCommand.php b/libraries/src/Console/FinderIndexCommand.php index 78cd077ac762c..10ce114c81bb0 100644 --- a/libraries/src/Console/FinderIndexCommand.php +++ b/libraries/src/Console/FinderIndexCommand.php @@ -366,7 +366,9 @@ private function index() $app->triggerEvent('onStartIndex'); // Remove the script time limit. - @set_time_limit(0); + if (\function_exists('set_time_limit')) { + set_time_limit(0); + } // Get the indexer state. $state = Indexer::getState(); diff --git a/libraries/src/Filesystem/File.php b/libraries/src/Filesystem/File.php index 435ead9ba9c3a..d199d2e5cc3d6 100644 --- a/libraries/src/Filesystem/File.php +++ b/libraries/src/Filesystem/File.php @@ -407,7 +407,9 @@ public static function move($src, $dest, $path = '', $useStreams = false) */ public static function write($file, $buffer, $useStreams = false) { - @set_time_limit(ini_get('max_execution_time')); + if (\function_exists('set_time_limit')) { + set_time_limit(ini_get('max_execution_time')); + } // If the destination directory doesn't exist we need to create it if (!file_exists(\dirname($file))) { @@ -466,7 +468,9 @@ public static function write($file, $buffer, $useStreams = false) */ public static function append($file, $buffer, $useStreams = false) { - @set_time_limit(ini_get('max_execution_time')); + if (\function_exists('set_time_limit')) { + set_time_limit(ini_get('max_execution_time')); + } // If the file doesn't exist, just write instead of append if (!file_exists($file)) { diff --git a/libraries/src/Filesystem/Folder.php b/libraries/src/Filesystem/Folder.php index cef115745c236..1d2da094f9cad 100644 --- a/libraries/src/Filesystem/Folder.php +++ b/libraries/src/Filesystem/Folder.php @@ -46,7 +46,9 @@ abstract class Folder */ public static function copy($src, $dest, $path = '', $force = false, $useStreams = false) { - @set_time_limit(ini_get('max_execution_time')); + if (\function_exists('set_time_limit')) { + set_time_limit(ini_get('max_execution_time')); + } $FTPOptions = ClientHelper::getCredentials('ftp'); @@ -285,7 +287,9 @@ public static function create($path = '', $mode = 0755) */ public static function delete($path) { - @set_time_limit(ini_get('max_execution_time')); + if (\function_exists('set_time_limit')) { + set_time_limit(ini_get('max_execution_time')); + } // Sanity check if (!$path) { @@ -566,7 +570,9 @@ public static function folders( */ protected static function _items($path, $filter, $recurse, $full, $exclude, $excludeFilterString, $findFiles) { - @set_time_limit(ini_get('max_execution_time')); + if (\function_exists('set_time_limit')) { + set_time_limit(ini_get('max_execution_time')); + } $arr = []; diff --git a/libraries/src/Installer/InstallerHelper.php b/libraries/src/Installer/InstallerHelper.php index 84af3cf811515..be0348be2f827 100644 --- a/libraries/src/Installer/InstallerHelper.php +++ b/libraries/src/Installer/InstallerHelper.php @@ -128,7 +128,9 @@ public static function downloadPackage($url, $target = false) ini_set('track_errors', $track_errors); // Bump the max execution time because not using built in php zip libs are slow - @set_time_limit(ini_get('max_execution_time')); + if (\function_exists('set_time_limit')) { + set_time_limit(ini_get('max_execution_time')); + } // Return the name of the downloaded package return basename($target); From da378aa2a8ad0e03c30295fbb6b8a5cf4286bfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cyril=20Rez=C3=A9?= Date: Fri, 8 Sep 2023 18:30:04 +0200 Subject: [PATCH 10/21] Improve Calendar form field style - Issues #36933 & #33447 (#40761) * Improve Calendar form field style * Improve Calendar form field style * Improve Calendar form field style * Add files via upload * Improve Calendar form field style (add RTL) * Add files via upload * Improve Calendar form field style * Improve Calendar form field style * Improve Calendar form field style --------- Co-authored-by: Olivier Buisard --- .../system/css/fields/calendar-rtl.css | 67 ++++++++++++++++--- .../system/css/fields/calendar.css | 66 +++++++++++++++--- .../system/images/select-bg-rtl.svg | 1 + .../media_source/system/images/select-bg.svg | 1 + .../system/js/fields/calendar.es5.js | 22 +++--- 5 files changed, 131 insertions(+), 26 deletions(-) create mode 100644 build/media_source/system/images/select-bg-rtl.svg create mode 100644 build/media_source/system/images/select-bg.svg diff --git a/build/media_source/system/css/fields/calendar-rtl.css b/build/media_source/system/css/fields/calendar-rtl.css index d22f9db4d6c51..674d226738fe7 100644 --- a/build/media_source/system/css/fields/calendar-rtl.css +++ b/build/media_source/system/css/fields/calendar-rtl.css @@ -2,9 +2,11 @@ * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ - .js-calendar { + +.js-calendar { box-shadow: 0 0 15px 4px rgba(0,0,0,.15) !important; - } +} + .calendar-container { float: left; min-width: 160px; @@ -14,13 +16,23 @@ background-color: #ffffff !important; z-index: 1100 !important; } + +.calendar-container .nav { + display: table-cell; +} + .calendar-container table { table-layout: fixed; - max-width: 262px; + max-width: 268px; border-radius: 5px; background-color: #ffffff !important; z-index: 1100 !important; + margin-top: 2px; + margin-left: auto; + margin-right: auto; + padding: 3px; } + /* The main calendar widget. DIV containing a table. */ div.calendar-container table th, .calendar-container table td { box-shadow: none; @@ -100,6 +112,7 @@ div.calendar-container table td.title { /* This holds the current "month, year" width: auto; font-weight: bold; } + .calendar-container table tbody td.today:after { position: absolute; bottom: 3px; @@ -110,6 +123,7 @@ div.calendar-container table td.title { /* This holds the current "month, year" border-radius: 1.5px; background-color: #46a546; } + .calendar-container table tbody td.today.selected:after { background-color: #fff; } @@ -119,6 +133,7 @@ div.calendar-container table td.title { /* This holds the current "month, year" background: #3d8fd7; color: #fff; } + .calendar-container table tbody td.day:hover:after { background-color: #fff; } @@ -135,42 +150,78 @@ div.calendar-container table td.title { /* This holds the current "month, year" .calendar-container table tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ display: none; } + .calendar-container .calendar-head-row td { padding: 4px 0 !important; border-bottom: none; } + .calendar-container .day-name { + padding-top: 0.5rem; font-size: 0.7rem; font-weight: bold; + border-bottom: none; } + .calendar-container .time td { - padding: 8px 8px 8px 0; + padding: 15px 3px 10px 0; + border-bottom: none; +} + +.calendar-container td.time-title { + display: block; + margin-top: 20px; } + +.calendar-container .time td select { + display: block; + width: 100%; + padding: 5px 9px 3px; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #f0f4fb; + background-image: url("../../images/select-bg-rtl.svg"); + background-repeat: no-repeat; + background-position: left center; + background-size: max(100%, 58rem); + border: 1px solid #cdcdcd; + border-radius: 0.25rem; + appearance: none; +} + .buttons-wrapper { - padding: 5px 5px; - width:100%; + margin-bottom: 0 !important; + padding: 5px; + width: 100%; } + .buttons-wrapper .btn { min-width: 60px; color: #495057; border: 1px solid #495057; - margin-left: .5rem; + margin-left: 0; padding: 0 16px; line-height: 2.375rem; box-shadow: 1px 0 1px 1px rgba(0,0,0,.25); } + .buttons-wrapper .btn:hover { color: #fff; background: #1a466b; } + .buttons-wrapper .btn:last-child { margin-left: 0; } + .time .time-title { - background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg width='22' height='22' viewBox='0 0 1792 1792' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg width='24' height='24' viewBox='0 0 1792 1792' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; } + /* Fix cursor on js-btn and time select */ .calendar-container select, .calendar-container .js-btn { diff --git a/build/media_source/system/css/fields/calendar.css b/build/media_source/system/css/fields/calendar.css index 70dc7aa09bac3..038567b481fca 100644 --- a/build/media_source/system/css/fields/calendar.css +++ b/build/media_source/system/css/fields/calendar.css @@ -2,9 +2,11 @@ * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ - .js-calendar { + +.js-calendar { box-shadow: 0 0 15px 4px rgba(0,0,0,.15) !important; - } +} + .calendar-container { float: left; min-width: 160px; @@ -14,13 +16,23 @@ background-color: #ffffff !important; z-index: 1100 !important; } + +.calendar-container .nav { + display: table-cell; +} + .calendar-container table { table-layout: fixed; - max-width: 262px; + max-width: 268px; border-radius: 5px; background-color: #ffffff !important; z-index: 1100 !important; + margin-top: 2px; + margin-left: auto; + margin-right: auto; + padding: 3px; } + /* The main calendar widget. DIV containing a table. */ div.calendar-container table th, .calendar-container table td { box-shadow: none; @@ -100,6 +112,7 @@ div.calendar-container table td.title { /* This holds the current "month, year" width: auto; font-weight: bold; } + .calendar-container table tbody td.today:after { position: absolute; bottom: 3px; @@ -110,6 +123,7 @@ div.calendar-container table td.title { /* This holds the current "month, year" border-radius: 1.5px; background-color: #46a546; } + .calendar-container table tbody td.today.selected:after { background-color: #fff; } @@ -119,6 +133,7 @@ div.calendar-container table td.title { /* This holds the current "month, year" background: #3d8fd7; color: #fff; } + .calendar-container table tbody td.day:hover:after { background-color: #fff; } @@ -140,38 +155,73 @@ div.calendar-container table td.title { /* This holds the current "month, year" padding: 4px 0 !important; border-bottom: none; } + .calendar-container .day-name { + padding-top: 0.5rem; font-size: 0.7rem; font-weight: bold; + border-bottom: none; } + .calendar-container .time td { - padding: 8px 0 8px 8px; + padding: 15px 3px 10px 0; + border-bottom: none; +} + +.calendar-container td.time-title { + display: block; + margin-top: 20px; } + +.calendar-container .time td select { + display: block; + width: 100%; + padding: 5px 9px 3px; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #f0f4fb; + background-image: url("../../images/select-bg.svg"); + background-repeat: no-repeat; + background-position: right center; + background-size: max(100%, 58rem); + border: 1px solid #cdcdcd; + border-radius: 0.25rem; + appearance: none; +} + .buttons-wrapper { - padding: 5px 5px; - width:100%; + margin-bottom: 0 !important; + padding: 5px; + width: 100%; } + .buttons-wrapper .btn { min-width: 60px; color: #495057; border: 1px solid #495057; - margin-right: .5rem; + margin-right: 0; padding: 0 16px; line-height: 2.375rem; box-shadow: 1px 1px 1px 0 rgba(0,0,0,.25); } + .buttons-wrapper .btn:hover { color: #fff; background: #1a466b; } + .buttons-wrapper .btn:last-child { margin-right: 0; } + .time .time-title { - background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg width='22' height='22' viewBox='0 0 1792 1792' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z'/%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3Csvg width='24' height='24' viewBox='0 0 1792 1792' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; } + /* Fix cursor on js-btn and time select */ .calendar-container select, .calendar-container .js-btn { diff --git a/build/media_source/system/images/select-bg-rtl.svg b/build/media_source/system/images/select-bg-rtl.svg new file mode 100644 index 0000000000000..a1ae9a3e60bb1 --- /dev/null +++ b/build/media_source/system/images/select-bg-rtl.svg @@ -0,0 +1 @@ + diff --git a/build/media_source/system/images/select-bg.svg b/build/media_source/system/images/select-bg.svg new file mode 100644 index 0000000000000..e2fefccf30242 --- /dev/null +++ b/build/media_source/system/images/select-bg.svg @@ -0,0 +1 @@ + diff --git a/build/media_source/system/js/fields/calendar.es5.js b/build/media_source/system/js/fields/calendar.es5.js index 2ab7a308c9005..b4bc2721020b4 100644 --- a/build/media_source/system/js/fields/calendar.es5.js +++ b/build/media_source/system/js/fields/calendar.es5.js @@ -632,7 +632,7 @@ row.className = "calendar-head-row"; this._nav_py = hh("‹", 1, -2, '', {"text-align": "center", "font-size": "18px", "line-height": "18px"}, 'js-btn btn-prev-year'); // Previous year button this.title = hh('
', this.params.weekNumbers ? 6 : 5, 300); - this.title.className = "title"; + this.title.className = "title title-year"; this._nav_ny = hh(" ›", 1, 2, '', {"text-align": "center", "font-size": "18px", "line-height": "18px"}, 'js-btn btn-next-year'); // Next year button } @@ -640,7 +640,7 @@ row.className = "calendar-head-row"; this._nav_pm = hh("‹", 1, -1, '', {"text-align": "center", "font-size": "2em", "line-height": "1em"}, 'js-btn btn-prev-month'); // Previous month button this._nav_month = hh('
', this.params.weekNumbers ? 6 : 5, 888, 'td', {'textAlign': 'center'}); - this._nav_month.className = "title"; + this._nav_month.className = "title title-month"; this._nav_nm = hh(" ›", 1, 1, '', {"text-align": "center", "font-size": "2em", "line-height": "1em"}, 'js-btn btn-next-month'); // Next month button row = createElement("tr", thead); // day names @@ -698,7 +698,7 @@ row = createElement("tr", tbody); row.className = "time"; - cell = createElement("td", row); + var cell = createElement("td", row); cell.className = "time time-title"; cell.colSpan = 1; cell.style.verticalAlign = 'middle'; @@ -706,11 +706,11 @@ var cell1 = createElement("td", row); cell1.className = "time hours-select"; - cell1.colSpan = 2; + cell1.colSpan = self.params.time24 ? 3 : 2; var cell2 = createElement("td", row); cell2.className = "time minutes-select"; - cell2.colSpan = 2; + cell2.colSpan = self.params.time24 ? 3 : 2; (function () { function makeTimePart(className, selected, range_start, range_end, cellTml) { @@ -750,11 +750,12 @@ M = makeTimePart("time time-minutes", mins, 0, 59, cell2), AP = null; - cell = createElement("td", row); - cell.className = "time ampm-select"; - cell.colSpan = self.params.weekNumbers ? 2 : 3; if (t12) { + cell = createElement("td", row); + cell.className = "time ampm-select"; + cell.colSpan = self.params.weekNumbers ? 3 : 2; + var selAttr = true, altDate = Date.parseFieldDate(self.inputField.getAttribute('data-alt-value'), self.params.dateFormat, 'gregorian', self.strings); pm = (altDate.getHours() >= 12); @@ -772,9 +773,10 @@ event.target.parentNode.parentNode.childNodes[2].childNodes[0].value, event.target.parentNode.parentNode.childNodes[3].childNodes[0].value); }, false); - } else { + } else if (self.params.weekNumbers) { + cell = createElement("td", row); cell.innerHTML = " "; - cell.colSpan = self.params.weekNumbers ? 3 : 2; + cell.colSpan = 1; } H.addEventListener("change", function (event) { From 3ba9cff150b92f5cc8de041ed441cdbe0e092c75 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sat, 9 Sep 2023 20:15:17 +0200 Subject: [PATCH 11/21] system test com_modules webservices (#41560) * system test com_modules webservices * wrong client id * cs * moreendpoint * cs * 1file1endpoint * Delete tests/System/integration/api/com_modules/Request.cy.js * cs * cs * cs * cs * cs * cs * LF * cs * grr --- .../src/Controller/ModulesController.php | 4 +- .../api/com_modules/Administrator.cy.js | 75 +++++++++++++++++++ .../integration/api/com_modules/Site.cy.js | 75 +++++++++++++++++++ .../integration/api/com_modules/Types.cy.js | 15 ++++ 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 tests/System/integration/api/com_modules/Administrator.cy.js create mode 100644 tests/System/integration/api/com_modules/Site.cy.js create mode 100644 tests/System/integration/api/com_modules/Types.cy.js diff --git a/api/components/com_modules/src/Controller/ModulesController.php b/api/components/com_modules/src/Controller/ModulesController.php index f394794088395..31066a3ac2c30 100644 --- a/api/components/com_modules/src/Controller/ModulesController.php +++ b/api/components/com_modules/src/Controller/ModulesController.php @@ -53,7 +53,7 @@ class ModulesController extends ApiController */ public function displayItem($id = null) { - $this->modelState->set('filter.client_id', $this->getClientIdFromInput()); + $this->modelState->set('client_id', $this->getClientIdFromInput()); return parent::displayItem($id); } @@ -67,7 +67,7 @@ public function displayItem($id = null) */ public function displayList() { - $this->modelState->set('filter.client_id', $this->getClientIdFromInput()); + $this->modelState->set('client_id', $this->getClientIdFromInput()); return parent::displayList(); } diff --git a/tests/System/integration/api/com_modules/Administrator.cy.js b/tests/System/integration/api/com_modules/Administrator.cy.js new file mode 100644 index 0000000000000..82f494a18c405 --- /dev/null +++ b/tests/System/integration/api/com_modules/Administrator.cy.js @@ -0,0 +1,75 @@ +describe('Test that modules administrator API endpoint', () => { + afterEach(() => cy.task('queryDB', "DELETE FROM #__modules WHERE title = 'automated test administrator module'")); + + it('can deliver a list of administrator modules', () => { + cy.api_get('/modules/administrator') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('module') + .should('include', 'mod_sampledata')); + }); + + it('can deliver a single administrator module', () => { + cy.db_createModule({ title: 'automated test administrator module', client_id: 1 }) + .then((module) => cy.api_get(`/modules/administrator/${module}`)) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('title') + .should('include', 'automated test administrator module')); + }); + + it('can create an administrator module', () => { + cy.api_post('/modules/administrator', { + access: '1', + assigned: [ + '101', + '105', + ], + assignment: '0', + client_id: '1', + language: '0', + module: 'mod_version', + note: '', + ordering: '1', + params: { + bootstrap_size: '0', + cache: '1', + cache_time: '900', + cachemode: 'static', + count: '10', + header_class: '', + header_tag: 'h3', + layout: '_:default', + module_tag: 'div', + moduleclass_sfx: '', + style: '0', + }, + position: '', + publish_down: '', + publish_up: '', + published: '1', + showtitle: '1', + title: 'automated test administrator module', + }) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('title') + .should('include', 'automated test administrator module')); + }); + + it('can update an administrator module', () => { + cy.db_createModule({ title: 'automated test administrator module', client_id: 1 }) + .then((id) => { + const updatedModuleData = { + published: -2, + }; + return cy.api_patch(`/modules/administrator/${id}`, updatedModuleData); + }) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('published') + .should('equal', -2)); + }); + + it('can delete a administrator module', () => { + cy.db_createModule({ title: 'automated test administrator module', published: -2, client_id: 1 }) + .then((module) => cy.api_delete(`/modules/administrator/${module}`)) + .then((response) => cy.wrap(response).its('status').should('equal', 204)); + }); +}); diff --git a/tests/System/integration/api/com_modules/Site.cy.js b/tests/System/integration/api/com_modules/Site.cy.js new file mode 100644 index 0000000000000..0aee39c1ea552 --- /dev/null +++ b/tests/System/integration/api/com_modules/Site.cy.js @@ -0,0 +1,75 @@ +describe('Test that modules site API endpoint', () => { + afterEach(() => cy.task('queryDB', "DELETE FROM #__modules WHERE title = 'automated test site module'")); + + it('can deliver a list of site modules', () => { + cy.api_get('/modules/site') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('module') + .should('include', 'mod_breadcrumbs')); + }); + + it('can deliver a single site module', () => { + cy.db_createModule({ title: 'automated test site module' }) + .then((module) => cy.api_get(`/modules/site/${module}`)) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('title') + .should('include', 'automated test site module')); + }); + + it('can create a site module', () => { + cy.api_post('/modules/site', { + access: '1', + assigned: [ + '101', + '105', + ], + assignment: '0', + client_id: '0', + language: '0', + module: 'mod_articles_archive', + note: '', + ordering: '1', + params: { + bootstrap_size: '0', + cache: '1', + cache_time: '900', + cachemode: 'static', + count: '10', + header_class: '', + header_tag: 'h3', + layout: '_:default', + module_tag: 'div', + moduleclass_sfx: '', + style: '0', + }, + position: '', + publish_down: '', + publish_up: '', + published: '1', + showtitle: '1', + title: 'automated test site module', + }) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('title') + .should('include', 'automated test site module')); + }); + + it('can update a site module', () => { + cy.db_createModule({ title: 'automated test site module' }) + .then((id) => { + const updatedModuleData = { + published: -2, + }; + return cy.api_patch(`/modules/site/${id}`, updatedModuleData); + }) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('published') + .should('equal', -2)); + }); + + it('can delete a site module', () => { + cy.db_createModule({ title: 'automated test site module', published: -2 }) + .then((module) => cy.api_delete(`/modules/site/${module}`)) + .then((response) => cy.wrap(response).its('status').should('equal', 204)); + }); +}); diff --git a/tests/System/integration/api/com_modules/Types.cy.js b/tests/System/integration/api/com_modules/Types.cy.js new file mode 100644 index 0000000000000..219fb4bae8f5c --- /dev/null +++ b/tests/System/integration/api/com_modules/Types.cy.js @@ -0,0 +1,15 @@ +describe('Test that modules types API endpoint', () => { + it('can deliver a list of modules types administrator', () => { + cy.api_get('/modules/types/administrator') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('module') + .should('include', 'mod_latestactions')); + }); + + it('can deliver a list of modules types site', () => { + cy.api_get('/modules/types/site') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('module') + .should('include', 'mod_articles_archive')); + }); +}); From 8f8c2551b6d4384cd78247fc45e83b584c414642 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Sun, 10 Sep 2023 08:28:11 +0200 Subject: [PATCH 12/21] system test com_plugins webservices (#41692) * api plugin test * Rename --------- Co-authored-by: Allon Moritz --- .../integration/api/com_plugins/Plugins.cy.js | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/System/integration/api/com_plugins/Plugins.cy.js diff --git a/tests/System/integration/api/com_plugins/Plugins.cy.js b/tests/System/integration/api/com_plugins/Plugins.cy.js new file mode 100644 index 0000000000000..5e6ccaddbaf26 --- /dev/null +++ b/tests/System/integration/api/com_plugins/Plugins.cy.js @@ -0,0 +1,35 @@ +describe('Test that plugins API endpoint', () => { + it('can deliver a list of plugins', () => { + cy.api_get('/plugins') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('folder') + .should('include', 'actionlog')); + }); + + it('can deliver a single plugin', () => { + cy.api_get('/plugins') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('id')) + .then((id) => { + cy.api_get(`/plugins/${id}`) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('folder') + .should('include', 'actionlog')); + }); + }); + + it('can modify a single plugin', () => { + cy.api_get('/plugins') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('id')) + .then((id) => { + const updatedPlugin = { + enabled: 0, + }; + cy.api_patch(`/plugins/${id}`, updatedPlugin) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('enabled') + .should('equal', 0)); + }); + }); +}); From 0469fac1af6cf22e4c6ca170ba04cff1fbb76f15 Mon Sep 17 00:00:00 2001 From: Denitz <197527+Denitz@users.noreply.github.com> Date: Mon, 11 Sep 2023 09:56:29 +0300 Subject: [PATCH 13/21] [4.4] Invalid timings in debug plugin (#35655) * start * phpcs fix * docblock fix * docblocks fix * custom memory collector * cs fix * fix cs * even more cs * Update plugins/system/cache/cache.php Co-authored-by: Phil E. Taylor * Update plugins/system/debug/src/DataCollector/MemoryCollector.php Co-authored-by: Phil E. Taylor * Update plugins/system/debug/src/DataCollector/MemoryCollector.php Co-authored-by: Phil E. Taylor * Update plugins/system/debug/src/DataCollector/ProfileCollector.php Co-authored-by: Phil E. Taylor * Update plugins/system/debug/src/DataCollector/ProfileCollector.php Co-authored-by: Phil E. Taylor * cs * cs * revert ProfileCollector constructor. * fix * Remove 'afterRespond' mark * fix * Phase 1 convert BRANCH to PSR-12 * Phase 2 convert BRANCH to PSR-12 * fix * fix CS * fix * short Event, try to re-start drone --------- Co-authored-by: Denitz Co-authored-by: Phil E. Taylor Co-authored-by: Joomla! Bot --- .../src/DataCollector/MemoryCollector.php | 151 ++++++++++++++++++ .../src/DataCollector/ProfileCollector.php | 63 +++++--- plugins/system/debug/src/Extension/Debug.php | 91 ++++++----- 3 files changed, 242 insertions(+), 63 deletions(-) create mode 100644 plugins/system/debug/src/DataCollector/MemoryCollector.php diff --git a/plugins/system/debug/src/DataCollector/MemoryCollector.php b/plugins/system/debug/src/DataCollector/MemoryCollector.php new file mode 100644 index 0000000000000..6bac4d1644f63 --- /dev/null +++ b/plugins/system/debug/src/DataCollector/MemoryCollector.php @@ -0,0 +1,151 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Plugin\System\Debug\DataCollector; + +use Joomla\Plugin\System\Debug\AbstractDataCollector; +use Joomla\Registry\Registry; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Collects info about the request duration as well as providing + * a way to log duration of any operations + * + * @since __DEPLOY_VERSION__ + */ +class MemoryCollector extends AbstractDataCollector +{ + /** + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $realUsage = false; + + /** + * @var float + * @since __DEPLOY_VERSION__ + */ + protected $peakUsage = 0; + + /** + * @param Registry $params Parameters. + * @param float $peakUsage + * @param boolean $realUsage + * + * @since __DEPLOY_VERSION__ + */ + public function __construct(Registry $params, $peakUsage = null, $realUsage = null) + { + parent::__construct($params); + + if ($peakUsage !== null) { + $this->peakUsage = $peakUsage; + } + + if ($realUsage !== null) { + $this->realUsage = $realUsage; + } + } + + /** + * Returns whether total allocated memory page size is used instead of actual used memory size + * by the application. See $real_usage parameter on memory_get_peak_usage for details. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + public function getRealUsage() + { + return $this->realUsage; + } + + /** + * Sets whether total allocated memory page size is used instead of actual used memory size + * by the application. See $real_usage parameter on memory_get_peak_usage for details. + * + * @param boolean $realUsage + * + * @since __DEPLOY_VERSION__ + */ + public function setRealUsage($realUsage) + { + $this->realUsage = $realUsage; + } + + /** + * Returns the peak memory usage + * + * @return integer + * + * @since __DEPLOY_VERSION__ + */ + public function getPeakUsage() + { + return $this->peakUsage; + } + + /** + * Updates the peak memory usage value + * + * @since __DEPLOY_VERSION__ + */ + public function updatePeakUsage() + { + if ($this->peakUsage === null) { + $this->peakUsage = memory_get_peak_usage($this->realUsage); + } + } + + /** + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function collect() + { + $this->updatePeakUsage(); + + return [ + 'peak_usage' => $this->peakUsage, + 'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage, 3), + ]; + } + + /** + * @return string + * + * @since __DEPLOY_VERSION__ + */ + public function getName() + { + return 'memory'; + } + + /** + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function getWidgets() + { + return [ + 'memory' => [ + 'icon' => 'cogs', + 'tooltip' => 'Memory Usage', + 'map' => 'memory.peak_usage_str', + 'default' => "'0B'", + ], + ]; + } +} diff --git a/plugins/system/debug/src/DataCollector/ProfileCollector.php b/plugins/system/debug/src/DataCollector/ProfileCollector.php index 0c1de924b7ad4..381ae45ff2a81 100644 --- a/plugins/system/debug/src/DataCollector/ProfileCollector.php +++ b/plugins/system/debug/src/DataCollector/ProfileCollector.php @@ -84,8 +84,9 @@ public function __construct(Registry $params) * @param string|null $label Public name * @param string|null $collector The source of the collector * - * @since 4.0.0 * @return void + * + * @since 4.0.0 */ public function startMeasure($name, $label = null, $collector = null) { @@ -103,8 +104,9 @@ public function startMeasure($name, $label = null, $collector = null) * * @param string $name Group name. * - * @since 4.0.0 * @return bool + * + * @since 4.0.0 */ public function hasStartedMeasure($name): bool { @@ -117,9 +119,11 @@ public function hasStartedMeasure($name): bool * @param string $name Measurement name. * @param array $params Parameters * + * @return void + * * @since 4.0.0 + * * @throws DebugBarException - * @return void */ public function stopMeasure($name, array $params = []) { @@ -129,13 +133,7 @@ public function stopMeasure($name, array $params = []) throw new DebugBarException("Failed stopping measure '$name' because it hasn't been started"); } - $this->addMeasure( - $this->startedMeasures[$name]['label'], - $this->startedMeasures[$name]['start'], - $end, - $params, - $this->startedMeasures[$name]['collector'] - ); + $this->addMeasure($this->startedMeasures[$name]['label'], $this->startedMeasures[$name]['start'], $end, $params, $this->startedMeasures[$name]['collector']); unset($this->startedMeasures[$name]); } @@ -149,8 +147,9 @@ public function stopMeasure($name, array $params = []) * @param array $params Parameters. * @param string|null $collector A collector. * - * @since 4.0.0 * @return void + * + * @since 4.0.0 */ public function addMeasure($label, $start, $end, array $params = [], $collector = null) { @@ -174,8 +173,9 @@ public function addMeasure($label, $start, $end, array $params = [], $collector * @param \Closure $closure A closure. * @param string|null $collector A collector. * - * @since 4.0.0 * @return void + * + * @since 4.0.0 */ public function measure($label, \Closure $closure, $collector = null) { @@ -189,8 +189,9 @@ public function measure($label, \Closure $closure, $collector = null) /** * Returns an array of all measures * - * @since 4.0.0 * @return array + * + * @since 4.0.0 */ public function getMeasures(): array { @@ -200,8 +201,9 @@ public function getMeasures(): array /** * Returns the request start time * - * @since 4.0.0 * @return float + * + * @since 4.0.0 */ public function getRequestStartTime(): float { @@ -211,8 +213,9 @@ public function getRequestStartTime(): float /** * Returns the request end time * - * @since 4.0.0 * @return float + * + * @since 4.0.0 */ public function getRequestEndTime(): float { @@ -222,8 +225,9 @@ public function getRequestEndTime(): float /** * Returns the duration of a request * - * @since 4.0.0 * @return float + * + * @since 4.0.0 */ public function getRequestDuration(): float { @@ -234,15 +238,32 @@ public function getRequestDuration(): float return microtime(true) - $this->requestStartTime; } + /** + * Sets request end time. + * + * @param float $time Request end time. + * + * @return $this + * + * @since __DEPLOY_VERSION__ + */ + public function setRequestEndTime($time): self + { + $this->requestEndTime = $time; + + return $this; + } + /** * Called by the DebugBar when data needs to be collected * - * @since 4.0.0 * @return array Collected data + * + * @since 4.0.0 */ public function collect(): array { - $this->requestEndTime = microtime(true); + $this->requestEndTime = $this->requestEndTime ?? microtime(true); $start = $this->requestStartTime; @@ -284,8 +305,9 @@ function ($a, $b) { /** * Returns the unique name of the collector * - * @since 4.0.0 * @return string + * + * @since 4.0.0 */ public function getName(): string { @@ -296,8 +318,9 @@ public function getName(): string * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * - * @since 4.0.0 * @return array + * + * @since 4.0.0 */ public function getWidgets(): array { diff --git a/plugins/system/debug/src/Extension/Debug.php b/plugins/system/debug/src/Extension/Debug.php index dfc909023f76e..70ea776277e45 100644 --- a/plugins/system/debug/src/Extension/Debug.php +++ b/plugins/system/debug/src/Extension/Debug.php @@ -10,7 +10,6 @@ namespace Joomla\Plugin\System\Debug\Extension; -use DebugBar\DataCollector\MemoryCollector; use DebugBar\DataCollector\MessagesCollector; use DebugBar\DebugBar; use DebugBar\OpenHandler; @@ -28,11 +27,13 @@ use Joomla\Database\DatabaseInterface; use Joomla\Database\Event\ConnectionEvent; use Joomla\Event\DispatcherInterface; +use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\Plugin\System\Debug\DataCollector\InfoCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageErrorsCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageFilesCollector; use Joomla\Plugin\System\Debug\DataCollector\LanguageStringsCollector; +use Joomla\Plugin\System\Debug\DataCollector\MemoryCollector; use Joomla\Plugin\System\Debug\DataCollector\ProfileCollector; use Joomla\Plugin\System\Debug\DataCollector\QueryCollector; use Joomla\Plugin\System\Debug\DataCollector\RequestDataCollector; @@ -68,7 +69,7 @@ final class Debug extends CMSPlugin implements SubscriberInterface * @var boolean * @since 3.0 */ - private $debugLang = false; + private $debugLang; /** * Holds log entries handled by the plugin. @@ -78,14 +79,6 @@ final class Debug extends CMSPlugin implements SubscriberInterface */ private $logEntries = []; - /** - * Holds SHOW PROFILES of queries. - * - * @var array - * @since 3.1.2 - */ - private $sqlShowProfiles = []; - /** * Holds all SHOW PROFILE FOR QUERY n, indexed by n-1. * @@ -102,14 +95,6 @@ final class Debug extends CMSPlugin implements SubscriberInterface */ private $explains = []; - /** - * Holds total amount of executed queries. - * - * @var int - * @since 3.2 - */ - private $totalQueries = 0; - /** * @var DebugBar * @since 4.0.0 @@ -133,7 +118,7 @@ final class Debug extends CMSPlugin implements SubscriberInterface protected $isAjax = false; /** - * Whether displaing a logs is enabled + * Whether displaying a logs is enabled * * @var bool * @since 4.0.0 @@ -141,8 +126,14 @@ final class Debug extends CMSPlugin implements SubscriberInterface protected $showLogs = false; /** - * Returns an array of events this subscriber will listen to. + * The time spent in onAfterDisconnect() * + * @var float + * @since __DEPLOY_VERSION__ + */ + protected $timeInOnAfterDisconnect = 0; + + /** * @return array * * @since 4.1.3 @@ -150,12 +141,18 @@ final class Debug extends CMSPlugin implements SubscriberInterface public static function getSubscribedEvents(): array { return [ - 'onBeforeCompileHead' => 'onBeforeCompileHead', - 'onAjaxDebug' => 'onAjaxDebug', - 'onBeforeRespond' => 'onBeforeRespond', - 'onAfterRespond' => 'onAfterRespond', - ApplicationEvents::AFTER_RESPOND => 'onAfterRespond', - 'onAfterDisconnect' => 'onAfterDisconnect', + 'onBeforeCompileHead' => 'onBeforeCompileHead', + 'onAjaxDebug' => 'onAjaxDebug', + 'onBeforeRespond' => 'onBeforeRespond', + 'onAfterRespond' => [ + 'onAfterRespond', + PHP_INT_MIN, + ], + ApplicationEvents::AFTER_RESPOND => [ + 'onAfterRespond', + PHP_INT_MIN, + ], + 'onAfterDisconnect' => 'onAfterDisconnect', ]; } @@ -181,7 +178,7 @@ public function __construct(DispatcherInterface $dispatcher, $config, CMSApplica return; } - $this->getApplication()->getConfig()->set('gzip', false); + $this->getApplication()->set('gzip', false); ob_start(); ob_implicit_flush(false); @@ -269,8 +266,11 @@ public function onBeforeCompileHead() */ public function onAfterRespond() { + $endTime = microtime(true) - $this->timeInOnAfterDisconnect; + $endMemory = memory_get_peak_usage(false); + // Do not collect data if debugging or language debug is not enabled. - if (!JDEBUG && !$this->debugLang || $this->isAjax) { + if ((!JDEBUG && !$this->debugLang) || $this->isAjax) { return; } @@ -287,7 +287,7 @@ public function onAfterRespond() if (JDEBUG) { if ($this->params->get('memory', 1)) { - $this->debugBar->addCollector(new MemoryCollector()); + $this->debugBar->addCollector(new MemoryCollector($this->params, $endMemory)); } if ($this->params->get('request', 1)) { @@ -299,10 +299,13 @@ public function onAfterRespond() } if ($this->params->get('profile', 1)) { - $this->debugBar->addCollector(new ProfileCollector($this->params)); + $this->debugBar->addCollector((new ProfileCollector($this->params))->setRequestEndTime($endTime)); } if ($this->params->get('queries', 1)) { + // Close session to collect possible session-related queries. + $this->getApplication()->getSession()->close(); + // Call $db->disconnect() here to trigger the onAfterDisconnect() method here in this class! $this->getDatabase()->disconnect(); $this->debugBar->addCollector(new QueryCollector($this->params, $this->queryMonitor, $this->sqlShowProfileEach, $this->explains)); @@ -364,7 +367,7 @@ public function onAfterRespond() /** * AJAX handler * - * @param Joomla\Event\Event $event + * @param Event $event * * @return void * @@ -389,6 +392,7 @@ public function onAjaxDebug($event) $result[] = $handler->handle($this->getApplication()->getInput()->request->getArray(), false, false); $event['result'] = $result; + break; } } @@ -401,7 +405,7 @@ public function onAjaxDebug($event) */ private function isAuthorisedDisplayDebug(): bool { - static $result = null; + static $result; if ($result !== null) { return $result; @@ -440,13 +444,13 @@ public function onAfterDisconnect(ConnectionEvent $event) return; } + $startTime = microtime(true); + $db = $event->getDriver(); // Remove the monitor to avoid monitoring the following queries $db->setMonitor(null); - $this->totalQueries = $db->getCount(); - if ($this->params->get('query_profiles') && $db->getServerType() === 'mysql') { try { // Check if profiling is enabled. @@ -456,13 +460,13 @@ public function onAfterDisconnect(ConnectionEvent $event) if ($hasProfiling) { // Run a SHOW PROFILE query. $db->setQuery('SHOW PROFILES'); - $this->sqlShowProfiles = $db->loadAssocList(); + $sqlShowProfiles = $db->loadAssocList(); - if ($this->sqlShowProfiles) { - foreach ($this->sqlShowProfiles as $qn) { + if ($sqlShowProfiles) { + foreach ($sqlShowProfiles as $qn) { // Run SHOW PROFILE FOR QUERY for each query where a profile is available (max 100). $db->setQuery('SHOW PROFILE FOR QUERY ' . (int) $qn['Query_ID']); - $this->sqlShowProfileEach[(int) ($qn['Query_ID'] - 1)] = $db->loadAssocList(); + $this->sqlShowProfileEach[$qn['Query_ID'] - 1] = $db->loadAssocList(); } } } else { @@ -503,6 +507,8 @@ public function onAfterDisconnect(ConnectionEvent $event) } } } + + $this->timeInOnAfterDisconnect = microtime(true) - $startTime; } /** @@ -530,18 +536,18 @@ public function logger(LogEntry $entry) /** * Collect log messages. * - * @return $this + * @return void * * @since 4.0.0 */ - private function collectLogs(): self + private function collectLogs() { $loggerOptions = ['group' => 'default']; $logger = new InMemoryLogger($loggerOptions); $logEntries = $logger->getCollectedEntries(); if (!$this->logEntries && !$logEntries) { - return $this; + return; } if ($this->logEntries) { @@ -569,6 +575,7 @@ private function collectLogs(): self $this->debugBar[$entry->category]->addMessage($entry->message); } break; + case 'deprecated': if (!$logDeprecated && !$logDeprecatedCore) { break; @@ -643,8 +650,6 @@ private function collectLogs(): self break; } } - - return $this; } /** From 8a036ef6d08590cdffdfa4ef1f741fd2acac2120 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 11 Sep 2023 14:17:57 +0200 Subject: [PATCH 14/21] Package version bump (#41678) * Change the version in the bump script for package.json * Updated package file * cs --- build/bump.php | 9 ++ package.json | 228 ++++++++++++++++++++++++------------------------- 2 files changed, 123 insertions(+), 114 deletions(-) diff --git a/build/bump.php b/build/bump.php index 69212ec12d41f..2c0ac2997b98e 100644 --- a/build/bump.php +++ b/build/bump.php @@ -59,6 +59,8 @@ function usage($command) $antJobFile = '/build.xml'; +$packageJsonFile = '/package.json'; + $readMeFiles = [ '/README.md', '/README.txt', @@ -245,6 +247,13 @@ function usage($command) file_put_contents($rootPath . $antJobFile, $fileContents); } +// Updates the version in the package.json file. +if (file_exists($rootPath . $packageJsonFile)) { + $package = json_decode(file_get_contents($rootPath . $packageJsonFile)); + $package->version = $version['release']; + file_put_contents($rootPath . $packageJsonFile, json_encode($package, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); +} + // Updates the version in readme files. foreach ($readMeFiles as $readMeFile) { if (file_exists($rootPath . $readMeFile)) { diff --git a/package.json b/package.json index 93954585fe46b..c84c264bef639 100644 --- a/package.json +++ b/package.json @@ -1,115 +1,115 @@ { - "name": "joomla", - "version": "4.0.0", - "description": "Joomla CMS", - "license": "GPL-2.0-or-later", - "repository": { - "type": "git", - "url": "https://github.com/joomla/joomla-cms.git" - }, - "__engines_upgrades__": "Dockerfiles @ github.com/joomla-projects/docker-images need also upgrade", - "engines": { - "node": ">=16", - "npm": ">=8.5.5" - }, - "scripts": { - "build:js": "node build/build.js --compile-js", - "build:css": "node build/build.js --compile-css", - "build:bs5": "node build/build.js --compile-bs", - "build:com_media": "set NODE_ENV=PRODUCTION && node build/build.js --com-media", - "build:com_media:dev": "set NODE_ENV=DEVELOPMENT && node build/build.js --com-media", - "watch": "node build/build.js --watch", - "watch:com_media": "node build/build.js --watch-com-media", - "lint:js": "eslint --config build/.eslintrc --ignore-pattern '/media/' --ext .es6.js,.es6,.vue .", - "lint:testjs": "eslint --config build/.eslintrc --ext .js tests/System", - "lint:css": "stylelint --config build/.stylelintrc.json \"administrator/components/com_media/resources/**/*.scss\" \"administrator/templates/**/*.scss\" \"build/media_source/**/*.scss\" \"templates/**/*.scss\" \"installation/template/**/*.scss\"", - "install": "node build/build.js --prepare", - "update": "node build/build.js --copy-assets && node build/build.js --build-pages && node build/build.js --compile-js && node build/build.js --compile-css && node build/build.js --compile-bs && set NODE_ENV=PRODUCTION && node build/build.js --com-media", - "gzip": "node build/build.js --gzip", - "versioning": "node build/build.js --versioning", - "browserlist:update": "npx browserslist@latest --update-db", - "cypress:install": "cypress install", - "cypress:open": "cypress open", - "cypress:run": "cypress run" - }, - "browserslist": [ - "last 2 major version", - "not ie < 11" - ], - "dependencies": { - "@claviska/jquery-minicolors": "^2.3.6", - "@fortawesome/fontawesome-free": "^5.15.4", - "@joomla/joomla-a11y-checker": "^1.0.0", - "@popperjs/core": "^2.11.8", - "@webcomponents/webcomponentsjs": "^2.8.0", - "accessibility": "^3.0.17", - "awesomplete": "^1.1.5", - "bootstrap": "~5.3.0", - "choices.js": "^9.1.0", - "chosen-js": "^1.8.7", - "codemirror": "^5.65.15", - "cropperjs": "^1.6.0", - "diff": "^5.1.0", - "dotenv": "^16.3.1", - "dragula": "^3.7.3", - "focus-visible": "^5.2.0", - "hotkeys-js": "^3.12.0", - "joomla-ui-custom-elements": "^0.2.0", - "jquery": "^3.7.1", - "jquery-migrate": "^3.4.1", - "mark.js": "^8.11.1", - "mediaelement": "^5.1.1", - "metismenujs": "^1.4.0", - "punycode": "^2.3.0", - "qrcode-generator": "^1.4.4", - "roboto-fontface": "^0.10.0", - "shepherd.js": "^11.2.0", - "short-and-sweet": "^1.0.4", - "skipto": "^4.1.7", - "tinymce": "^5.10.7", - "vue": "3.2.45", - "vue-focus-lock": "^2.0.5", - "vuex": "^4.1.0", - "vuex-persist": "^3.1.3" - }, - "devDependencies": { - "@babel/core": "^7.22.11", - "@babel/preset-env": "^7.22.14", - "@dgrammatiko/compress": "^1.0.4", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^21.1.0", - "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^3.1.0", - "@vue/compiler-sfc": "^3.3.4", - "autoprefixer": "^10.4.15", - "chokidar": "^3.5.3", - "commander": "^8.3.0", - "core-js": "^3.32.1", - "cssnano": "^5.1.15", - "cypress": "^13.1.0", - "eslint": "^8.48.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-vue": "^8.7.1", - "fs-extra": "^10.1.0", - "ini": "^2.0.0", - "jasmine-core": "^3.99.1", - "joomla-cypress": "^0.0.16", - "mysql": "^2.18.1", - "postcss": "^8.4.29", - "postcss-scss": "^4.0.7", - "postgres": "^3.3.5", - "recursive-readdir": "^2.2.3", - "rimraf": "^3.0.2", - "rollup": "^2.79.1", - "rollup-plugin-vue": "^6.0.0", - "rtlcss": "^3.5.0", - "sass-embedded": "^1.66.1", - "smtp-tester": "^2.1.0", - "stylelint": "^14.16.1", - "stylelint-config-standard": "^24.0.0", - "stylelint-order": "^5.0.0", - "stylelint-scss": "^4.7.0", - "terser": "^5.19.3" - } -} + "name": "joomla", + "version": "4.4.0", + "description": "Joomla CMS", + "license": "GPL-2.0-or-later", + "repository": { + "type": "git", + "url": "https://github.com/joomla/joomla-cms.git" + }, + "__engines_upgrades__": "Dockerfiles @ github.com/joomla-projects/docker-images need also upgrade", + "engines": { + "node": ">=16", + "npm": ">=8.5.5" + }, + "scripts": { + "build:js": "node build/build.js --compile-js", + "build:css": "node build/build.js --compile-css", + "build:bs5": "node build/build.js --compile-bs", + "build:com_media": "set NODE_ENV=PRODUCTION && node build/build.js --com-media", + "build:com_media:dev": "set NODE_ENV=DEVELOPMENT && node build/build.js --com-media", + "watch": "node build/build.js --watch", + "watch:com_media": "node build/build.js --watch-com-media", + "lint:js": "eslint --config build/.eslintrc --ignore-pattern '/media/' --ext .es6.js,.es6,.vue .", + "lint:testjs": "eslint --config build/.eslintrc --ext .js tests/System", + "lint:css": "stylelint --config build/.stylelintrc.json \"administrator/components/com_media/resources/**/*.scss\" \"administrator/templates/**/*.scss\" \"build/media_source/**/*.scss\" \"templates/**/*.scss\" \"installation/template/**/*.scss\"", + "install": "node build/build.js --prepare", + "update": "node build/build.js --copy-assets && node build/build.js --build-pages && node build/build.js --compile-js && node build/build.js --compile-css && node build/build.js --compile-bs && set NODE_ENV=PRODUCTION && node build/build.js --com-media", + "gzip": "node build/build.js --gzip", + "versioning": "node build/build.js --versioning", + "browserlist:update": "npx browserslist@latest --update-db", + "cypress:install": "cypress install", + "cypress:open": "cypress open", + "cypress:run": "cypress run" + }, + "browserslist": [ + "last 2 major version", + "not ie < 11" + ], + "dependencies": { + "@claviska/jquery-minicolors": "^2.3.6", + "@fortawesome/fontawesome-free": "^5.15.4", + "@joomla/joomla-a11y-checker": "^1.0.0", + "@popperjs/core": "^2.11.8", + "@webcomponents/webcomponentsjs": "^2.8.0", + "accessibility": "^3.0.17", + "awesomplete": "^1.1.5", + "bootstrap": "~5.3.0", + "choices.js": "^9.1.0", + "chosen-js": "^1.8.7", + "codemirror": "^5.65.15", + "cropperjs": "^1.6.0", + "diff": "^5.1.0", + "dotenv": "^16.3.1", + "dragula": "^3.7.3", + "focus-visible": "^5.2.0", + "hotkeys-js": "^3.12.0", + "joomla-ui-custom-elements": "^0.2.0", + "jquery": "^3.7.1", + "jquery-migrate": "^3.4.1", + "mark.js": "^8.11.1", + "mediaelement": "^5.1.1", + "metismenujs": "^1.4.0", + "punycode": "^2.3.0", + "qrcode-generator": "^1.4.4", + "roboto-fontface": "^0.10.0", + "shepherd.js": "^11.2.0", + "short-and-sweet": "^1.0.4", + "skipto": "^4.1.7", + "tinymce": "^5.10.7", + "vue": "3.2.45", + "vue-focus-lock": "^2.0.5", + "vuex": "^4.1.0", + "vuex-persist": "^3.1.3" + }, + "devDependencies": { + "@babel/core": "^7.22.11", + "@babel/preset-env": "^7.22.14", + "@dgrammatiko/compress": "^1.0.4", + "@rollup/plugin-babel": "^5.3.1", + "@rollup/plugin-commonjs": "^21.1.0", + "@rollup/plugin-node-resolve": "^13.3.0", + "@rollup/plugin-replace": "^3.1.0", + "@vue/compiler-sfc": "^3.3.4", + "autoprefixer": "^10.4.15", + "chokidar": "^3.5.3", + "commander": "^8.3.0", + "core-js": "^3.32.1", + "cssnano": "^5.1.15", + "cypress": "^13.1.0", + "eslint": "^8.48.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-vue": "^8.7.1", + "fs-extra": "^10.1.0", + "ini": "^2.0.0", + "jasmine-core": "^3.99.1", + "joomla-cypress": "^0.0.16", + "mysql": "^2.18.1", + "postcss": "^8.4.29", + "postcss-scss": "^4.0.7", + "postgres": "^3.3.5", + "recursive-readdir": "^2.2.3", + "rimraf": "^3.0.2", + "rollup": "^2.79.1", + "rollup-plugin-vue": "^6.0.0", + "rtlcss": "^3.5.0", + "sass-embedded": "^1.66.1", + "smtp-tester": "^2.1.0", + "stylelint": "^14.16.1", + "stylelint-config-standard": "^24.0.0", + "stylelint-order": "^5.0.0", + "stylelint-scss": "^4.7.0", + "terser": "^5.19.3" + } +} \ No newline at end of file From b3f5c9fe0ef02354680fe333fe6cd4d2c0fc5d52 Mon Sep 17 00:00:00 2001 From: Nicola Galgano Date: Mon, 11 Sep 2023 15:50:23 +0200 Subject: [PATCH 15/21] system test com_templates webservices (#41695) * sitestyles * adminstyle --- .../src/Controller/StylesController.php | 2 +- .../api/com_templates/Administrator.cy.js | 35 +++++++++++++++++++ .../integration/api/com_templates/Site.cy.js | 35 +++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tests/System/integration/api/com_templates/Administrator.cy.js create mode 100644 tests/System/integration/api/com_templates/Site.cy.js diff --git a/api/components/com_templates/src/Controller/StylesController.php b/api/components/com_templates/src/Controller/StylesController.php index 87903695145b6..e973c2bfb50fc 100644 --- a/api/components/com_templates/src/Controller/StylesController.php +++ b/api/components/com_templates/src/Controller/StylesController.php @@ -88,7 +88,7 @@ protected function preprocessSaveData(array $data): array // If we are updating an item the template is a readonly property based on the ID if ($this->input->getMethod() === 'PATCH') { if (\array_key_exists('template', $data)) { - throw new InvalidParameterException('The template property cannot be modified for an existing style'); + unset($data['template']); } $model = $this->getModel(Inflector::singularize($this->contentType), '', ['ignore_request' => true]); diff --git a/tests/System/integration/api/com_templates/Administrator.cy.js b/tests/System/integration/api/com_templates/Administrator.cy.js new file mode 100644 index 0000000000000..6013b793cf85b --- /dev/null +++ b/tests/System/integration/api/com_templates/Administrator.cy.js @@ -0,0 +1,35 @@ +describe('Test that templates administrator styles API endpoint', () => { + it('can deliver a list of templates administrator styles', () => { + cy.api_get('/templates/styles/administrator') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('template') + .should('include', 'atum')); + }); + + it('can deliver a single templates administrator style', () => { + cy.api_get('/templates/styles/administrator') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('id')) + .then((id) => { + cy.api_get(`/templates/styles/administrator/${id}`) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('template') + .should('include', 'atum')); + }); + }); + + it('can modify a single template administrator style', () => { + cy.api_get('/templates/styles/administrator') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('id')) + .then((id) => { + const updatedStyle = { + title: 'automated test template administrator style', + }; + cy.api_patch(`/templates/styles/administrator/${id}`, updatedStyle) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('title') + .should('equal', 'automated test template administrator style')); + }); + }); +}); diff --git a/tests/System/integration/api/com_templates/Site.cy.js b/tests/System/integration/api/com_templates/Site.cy.js new file mode 100644 index 0000000000000..1b3faa73acd83 --- /dev/null +++ b/tests/System/integration/api/com_templates/Site.cy.js @@ -0,0 +1,35 @@ +describe('Test that templates API endpoint', () => { + it('can deliver a list of templates', () => { + cy.api_get('/templates/styles/site') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('template') + .should('include', 'cassiopeia')); + }); + + it('can deliver a single template', () => { + cy.api_get('/templates/styles/site') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('id')) + .then((id) => { + cy.api_get(`/templates/styles/site/${id}`) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('template') + .should('include', 'cassiopeia')); + }); + }); + + it('can modify a single template', () => { + cy.api_get('/templates/styles/site') + .then((response) => cy.wrap(response).its('body').its('data.0').its('attributes') + .its('id')) + .then((id) => { + const updatedStyle = { + title: 'automated test template site style', + }; + cy.api_patch(`/templates/styles/site/${id}`, updatedStyle) + .then((response) => cy.wrap(response).its('body').its('data').its('attributes') + .its('title') + .should('equal', 'automated test template site style')); + }); + }); +}); From afc47c6a99a9aeaf4096ecc73dfbd888d07d459d Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 11 Sep 2023 17:46:52 +0200 Subject: [PATCH 16/21] Change composer json file to two spaces (#41702) --- composer.json | 240 +++++++++++++++++++++++++------------------------- 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/composer.json b/composer.json index 858203010930e..5ae739a093300 100644 --- a/composer.json +++ b/composer.json @@ -1,124 +1,124 @@ { - "name": "joomla/joomla-cms", - "type": "project", - "description": "Joomla CMS", - "keywords": [ - "joomla", - "cms" - ], - "homepage": "https://github.com/joomla/joomla-cms", - "license": "GPL-2.0-or-later", - "config": { - "optimize-autoloader": true, - "platform": { - "php": "7.2.5" - }, - "vendor-dir": "libraries/vendor", - "github-protocols": ["https"], - "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true - } + "name": "joomla/joomla-cms", + "type": "project", + "description": "Joomla CMS", + "keywords": [ + "joomla", + "cms" + ], + "homepage": "https://github.com/joomla/joomla-cms", + "license": "GPL-2.0-or-later", + "config": { + "optimize-autoloader": true, + "platform": { + "php": "7.2.5" }, - "support": { - "issues": "https://issues.joomla.org/", - "irc": "irc://chat.freenode.net/joomla/", - "forum": "https://forum.joomla.org/", - "docs": "https://docs.joomla.org/" - }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/joomla-backports/json-api-php.git", - "no-api": true - } - ], - "autoload": { - "psr-4": { - "Joomla\\CMS\\": "libraries/src/" - } - }, - "autoload-dev": { - "psr-4": { - "Joomla\\Tests\\": "tests" - } - }, - "require": { - "php": "^7.2.5", - "joomla/application": "^2.0.4", - "joomla/archive": "^2.0.2", - "joomla/authentication": "^2.0.1", - "joomla/console": "^2.0.1", - "joomla/crypt": "^2.0.1", - "joomla/data": "^2.0.1", - "joomla/database": "^2.1.1", - "joomla/di": "^2.0.1", - "joomla/event": "^2.0.2", - "joomla/filter": "^2.0.3", - "joomla/filesystem": "^2.0.2", - "joomla/http": "^2.0.2", - "joomla/input": "^2.0.4", - "joomla/ldap": "~2.0.0", - "joomla/oauth1": "^2.0.2", - "joomla/oauth2": "^2.0.2", - "joomla/registry": "^2.0.4", - "joomla/router": "^2.0.1", - "joomla/session": "^2.0.2", - "joomla/string": "^2.0.1", - "joomla/uri": "^2.0.4", - "joomla/utilities": "^2.0.1", - "algo26-matthias/idna-convert": "^3.1.0", - "defuse/php-encryption": "^2.4.0", - "doctrine/inflector": "^1.4.4", - "fig/link-util": "^1.1.2", - "google/recaptcha": "^1.2.4", - "laminas/laminas-diactoros": "^2.4.1", - "paragonie/sodium_compat": "^1.20", - "phpmailer/phpmailer": "^6.8.1", - "psr/link": "~1.0.0", - "symfony/console": "^5.4.28", - "symfony/error-handler": "^5.4.26", - "symfony/ldap": "^5.4.27", - "symfony/options-resolver": "^5.4.21", - "symfony/polyfill-mbstring": "^1.28.0", - "symfony/polyfill-php73": "^1.28", - "symfony/polyfill-php80": "^1.28", - "symfony/polyfill-php81": "^1.28", - "symfony/web-link": "^5.4.21", - "symfony/yaml": "^5.4.23", - "typo3/phar-stream-wrapper": "^3.1.7", - "wamania/php-stemmer": "^2.2", - "maximebf/debugbar": "dev-master", - "tobscure/json-api": "dev-joomla-backports", - "willdurand/negotiation": "^3.1.0", - "ext-json": "*", - "ext-simplexml": "*", - "psr/log": "^1.1.4", - "ext-gd": "*", - "web-auth/webauthn-lib": "2.1.*", - "composer/ca-bundle": "^1.3.7", - "dragonmantank/cron-expression": "^3.3.3", - "enshrined/svg-sanitize": "^0.15.4", - "lcobucci/jwt": "^3.4.6", - "web-token/signature-pack": "^2.2.11", - "phpseclib/bcmath_compat": "^2.0.1", - "jfcherng/php-diff": "^6.10.14", - "voku/portable-utf8": "6.0.12 as 5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.33", - "friendsofphp/php-cs-fixer": "^3.4.0", - "squizlabs/php_codesniffer": "^3.7.2", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", - "joomla/mediawiki": "^1.0.0", - "joomla/test": "^2.0.2", - "phan/phan": "^5.4.2" - }, - "replace": { - "paragonie/random_compat": "9.99.99" - }, - "scripts": { - "post-install-cmd": [ - "php build/update_fido_cache.php" - ] + "vendor-dir": "libraries/vendor", + "github-protocols": ["https"], + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "support": { + "issues": "https://issues.joomla.org/", + "irc": "irc://chat.freenode.net/joomla/", + "forum": "https://forum.joomla.org/", + "docs": "https://docs.joomla.org/" + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/joomla-backports/json-api-php.git", + "no-api": true + } + ], + "autoload": { + "psr-4": { + "Joomla\\CMS\\": "libraries/src/" + } + }, + "autoload-dev": { + "psr-4": { + "Joomla\\Tests\\": "tests" } + }, + "require": { + "php": "^7.2.5", + "joomla/application": "^2.0.4", + "joomla/archive": "^2.0.2", + "joomla/authentication": "^2.0.1", + "joomla/console": "^2.0.1", + "joomla/crypt": "^2.0.1", + "joomla/data": "^2.0.1", + "joomla/database": "^2.1.1", + "joomla/di": "^2.0.1", + "joomla/event": "^2.0.2", + "joomla/filter": "^2.0.3", + "joomla/filesystem": "^2.0.2", + "joomla/http": "^2.0.2", + "joomla/input": "^2.0.4", + "joomla/ldap": "~2.0.0", + "joomla/oauth1": "^2.0.2", + "joomla/oauth2": "^2.0.2", + "joomla/registry": "^2.0.4", + "joomla/router": "^2.0.1", + "joomla/session": "^2.0.2", + "joomla/string": "^2.0.1", + "joomla/uri": "^2.0.4", + "joomla/utilities": "^2.0.1", + "algo26-matthias/idna-convert": "^3.1.0", + "defuse/php-encryption": "^2.4.0", + "doctrine/inflector": "^1.4.4", + "fig/link-util": "^1.1.2", + "google/recaptcha": "^1.2.4", + "laminas/laminas-diactoros": "^2.4.1", + "paragonie/sodium_compat": "^1.20", + "phpmailer/phpmailer": "^6.8.1", + "psr/link": "~1.0.0", + "symfony/console": "^5.4.28", + "symfony/error-handler": "^5.4.26", + "symfony/ldap": "^5.4.27", + "symfony/options-resolver": "^5.4.21", + "symfony/polyfill-mbstring": "^1.28.0", + "symfony/polyfill-php73": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/web-link": "^5.4.21", + "symfony/yaml": "^5.4.23", + "typo3/phar-stream-wrapper": "^3.1.7", + "wamania/php-stemmer": "^2.2", + "maximebf/debugbar": "dev-master", + "tobscure/json-api": "dev-joomla-backports", + "willdurand/negotiation": "^3.1.0", + "ext-json": "*", + "ext-simplexml": "*", + "psr/log": "^1.1.4", + "ext-gd": "*", + "web-auth/webauthn-lib": "2.1.*", + "composer/ca-bundle": "^1.3.7", + "dragonmantank/cron-expression": "^3.3.3", + "enshrined/svg-sanitize": "^0.15.4", + "lcobucci/jwt": "^3.4.6", + "web-token/signature-pack": "^2.2.11", + "phpseclib/bcmath_compat": "^2.0.1", + "jfcherng/php-diff": "^6.10.14", + "voku/portable-utf8": "6.0.12 as 5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.33", + "friendsofphp/php-cs-fixer": "^3.4.0", + "squizlabs/php_codesniffer": "^3.7.2", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", + "joomla/mediawiki": "^1.0.0", + "joomla/test": "^2.0.2", + "phan/phan": "^5.4.2" + }, + "replace": { + "paragonie/random_compat": "9.99.99" + }, + "scripts": { + "post-install-cmd": [ + "php build/update_fido_cache.php" + ] + } } From f19d92c96b8bf4597e1b732c8cde90083315187c Mon Sep 17 00:00:00 2001 From: Dimitris Grammatikogiannis Date: Mon, 11 Sep 2023 22:05:08 +0300 Subject: [PATCH 17/21] Bump node version (#41699) * Update package.json * Update .drone.yml * Update package-lock.json * changing signature * Update package-lock.json * Update package.json * Reset the indantation to 2 spaces --- .drone.yml | 4 +- build/bump.php | 4 +- package-lock.json | 4 +- package.json | 227 +++++++++++++++++++++++----------------------- 4 files changed, 120 insertions(+), 119 deletions(-) diff --git a/.drone.yml b/.drone.yml index cab113d139b9c..72d23ab75ba75 100644 --- a/.drone.yml +++ b/.drone.yml @@ -39,7 +39,7 @@ steps: - ./libraries/vendor/bin/phan - name: npm - image: node:16-bullseye-slim + image: node:18-bullseye-slim depends_on: [ phpcs ] volumes: - name: npm-cache @@ -462,6 +462,6 @@ trigger: --- kind: signature -hmac: 06ecea6156e9c3f4cbb17d5e5e876a8c2b256e0e98412ce6351c914b2adbda97 +hmac: c80f54f77ce8c648018d3946dc20d86bf3491484662a0e5defd8d9453f33cd92 ... diff --git a/build/bump.php b/build/bump.php index 2c0ac2997b98e..46a16c13149bf 100644 --- a/build/bump.php +++ b/build/bump.php @@ -251,7 +251,9 @@ function usage($command) if (file_exists($rootPath . $packageJsonFile)) { $package = json_decode(file_get_contents($rootPath . $packageJsonFile)); $package->version = $version['release']; - file_put_contents($rootPath . $packageJsonFile, json_encode($package, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + + // @todo use a native formatter whenever https://github.com/php/php-src/issues/8864 is resolved + file_put_contents($rootPath . $packageJsonFile, str_replace(' ', ' ', json_encode($package, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES))); } // Updates the version in readme files. diff --git a/package-lock.json b/package-lock.json index 1a614caf71272..7a400ae927282 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,8 +86,8 @@ "terser": "^5.19.3" }, "engines": { - "node": ">=16", - "npm": ">=8.5.5" + "node": ">=18", + "npm": ">=9.6.7" } }, "node_modules/@aashutoshrathi/word-wrap": { diff --git a/package.json b/package.json index c84c264bef639..595303de43a4a 100644 --- a/package.json +++ b/package.json @@ -1,115 +1,114 @@ { - "name": "joomla", - "version": "4.4.0", - "description": "Joomla CMS", - "license": "GPL-2.0-or-later", - "repository": { - "type": "git", - "url": "https://github.com/joomla/joomla-cms.git" - }, - "__engines_upgrades__": "Dockerfiles @ github.com/joomla-projects/docker-images need also upgrade", - "engines": { - "node": ">=16", - "npm": ">=8.5.5" - }, - "scripts": { - "build:js": "node build/build.js --compile-js", - "build:css": "node build/build.js --compile-css", - "build:bs5": "node build/build.js --compile-bs", - "build:com_media": "set NODE_ENV=PRODUCTION && node build/build.js --com-media", - "build:com_media:dev": "set NODE_ENV=DEVELOPMENT && node build/build.js --com-media", - "watch": "node build/build.js --watch", - "watch:com_media": "node build/build.js --watch-com-media", - "lint:js": "eslint --config build/.eslintrc --ignore-pattern '/media/' --ext .es6.js,.es6,.vue .", - "lint:testjs": "eslint --config build/.eslintrc --ext .js tests/System", - "lint:css": "stylelint --config build/.stylelintrc.json \"administrator/components/com_media/resources/**/*.scss\" \"administrator/templates/**/*.scss\" \"build/media_source/**/*.scss\" \"templates/**/*.scss\" \"installation/template/**/*.scss\"", - "install": "node build/build.js --prepare", - "update": "node build/build.js --copy-assets && node build/build.js --build-pages && node build/build.js --compile-js && node build/build.js --compile-css && node build/build.js --compile-bs && set NODE_ENV=PRODUCTION && node build/build.js --com-media", - "gzip": "node build/build.js --gzip", - "versioning": "node build/build.js --versioning", - "browserlist:update": "npx browserslist@latest --update-db", - "cypress:install": "cypress install", - "cypress:open": "cypress open", - "cypress:run": "cypress run" - }, - "browserslist": [ - "last 2 major version", - "not ie < 11" - ], - "dependencies": { - "@claviska/jquery-minicolors": "^2.3.6", - "@fortawesome/fontawesome-free": "^5.15.4", - "@joomla/joomla-a11y-checker": "^1.0.0", - "@popperjs/core": "^2.11.8", - "@webcomponents/webcomponentsjs": "^2.8.0", - "accessibility": "^3.0.17", - "awesomplete": "^1.1.5", - "bootstrap": "~5.3.0", - "choices.js": "^9.1.0", - "chosen-js": "^1.8.7", - "codemirror": "^5.65.15", - "cropperjs": "^1.6.0", - "diff": "^5.1.0", - "dotenv": "^16.3.1", - "dragula": "^3.7.3", - "focus-visible": "^5.2.0", - "hotkeys-js": "^3.12.0", - "joomla-ui-custom-elements": "^0.2.0", - "jquery": "^3.7.1", - "jquery-migrate": "^3.4.1", - "mark.js": "^8.11.1", - "mediaelement": "^5.1.1", - "metismenujs": "^1.4.0", - "punycode": "^2.3.0", - "qrcode-generator": "^1.4.4", - "roboto-fontface": "^0.10.0", - "shepherd.js": "^11.2.0", - "short-and-sweet": "^1.0.4", - "skipto": "^4.1.7", - "tinymce": "^5.10.7", - "vue": "3.2.45", - "vue-focus-lock": "^2.0.5", - "vuex": "^4.1.0", - "vuex-persist": "^3.1.3" - }, - "devDependencies": { - "@babel/core": "^7.22.11", - "@babel/preset-env": "^7.22.14", - "@dgrammatiko/compress": "^1.0.4", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^21.1.0", - "@rollup/plugin-node-resolve": "^13.3.0", - "@rollup/plugin-replace": "^3.1.0", - "@vue/compiler-sfc": "^3.3.4", - "autoprefixer": "^10.4.15", - "chokidar": "^3.5.3", - "commander": "^8.3.0", - "core-js": "^3.32.1", - "cssnano": "^5.1.15", - "cypress": "^13.1.0", - "eslint": "^8.48.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-vue": "^8.7.1", - "fs-extra": "^10.1.0", - "ini": "^2.0.0", - "jasmine-core": "^3.99.1", - "joomla-cypress": "^0.0.16", - "mysql": "^2.18.1", - "postcss": "^8.4.29", - "postcss-scss": "^4.0.7", - "postgres": "^3.3.5", - "recursive-readdir": "^2.2.3", - "rimraf": "^3.0.2", - "rollup": "^2.79.1", - "rollup-plugin-vue": "^6.0.0", - "rtlcss": "^3.5.0", - "sass-embedded": "^1.66.1", - "smtp-tester": "^2.1.0", - "stylelint": "^14.16.1", - "stylelint-config-standard": "^24.0.0", - "stylelint-order": "^5.0.0", - "stylelint-scss": "^4.7.0", - "terser": "^5.19.3" - } -} \ No newline at end of file + "name": "joomla", + "version": "4.4.0", + "description": "Joomla CMS", + "license": "GPL-2.0-or-later", + "repository": { + "type": "git", + "url": "https://github.com/joomla/joomla-cms.git" + }, + "engines": { + "node": ">=18", + "npm": ">=9.6.7" + }, + "scripts": { + "build:js": "node build/build.js --compile-js", + "build:css": "node build/build.js --compile-css", + "build:bs5": "node build/build.js --compile-bs", + "build:com_media": "set NODE_ENV=PRODUCTION && node build/build.js --com-media", + "build:com_media:dev": "set NODE_ENV=DEVELOPMENT && node build/build.js --com-media", + "watch": "node build/build.js --watch", + "watch:com_media": "node build/build.js --watch-com-media", + "lint:js": "eslint --config build/.eslintrc --ignore-pattern '/media/' --ext .es6.js,.es6,.vue .", + "lint:testjs": "eslint --config build/.eslintrc --ext .js tests/System", + "lint:css": "stylelint --config build/.stylelintrc.json \"administrator/components/com_media/resources/**/*.scss\" \"administrator/templates/**/*.scss\" \"build/media_source/**/*.scss\" \"templates/**/*.scss\" \"installation/template/**/*.scss\"", + "install": "node build/build.js --prepare", + "update": "node build/build.js --copy-assets && node build/build.js --build-pages && node build/build.js --compile-js && node build/build.js --compile-css && node build/build.js --compile-bs && set NODE_ENV=PRODUCTION && node build/build.js --com-media", + "gzip": "node build/build.js --gzip", + "versioning": "node build/build.js --versioning", + "browserlist:update": "npx browserslist@latest --update-db", + "cypress:install": "cypress install", + "cypress:open": "cypress open", + "cypress:run": "cypress run" + }, + "browserslist": [ + "last 2 major version", + "not ie < 11" + ], + "dependencies": { + "@claviska/jquery-minicolors": "^2.3.6", + "@fortawesome/fontawesome-free": "^5.15.4", + "@joomla/joomla-a11y-checker": "^1.0.0", + "@popperjs/core": "^2.11.8", + "@webcomponents/webcomponentsjs": "^2.8.0", + "accessibility": "^3.0.17", + "awesomplete": "^1.1.5", + "bootstrap": "~5.3.0", + "choices.js": "^9.1.0", + "chosen-js": "^1.8.7", + "codemirror": "^5.65.15", + "cropperjs": "^1.6.0", + "diff": "^5.1.0", + "dotenv": "^16.3.1", + "dragula": "^3.7.3", + "focus-visible": "^5.2.0", + "hotkeys-js": "^3.12.0", + "joomla-ui-custom-elements": "^0.2.0", + "jquery": "^3.7.1", + "jquery-migrate": "^3.4.1", + "mark.js": "^8.11.1", + "mediaelement": "^5.1.1", + "metismenujs": "^1.4.0", + "punycode": "^2.3.0", + "qrcode-generator": "^1.4.4", + "roboto-fontface": "^0.10.0", + "shepherd.js": "^11.2.0", + "short-and-sweet": "^1.0.4", + "skipto": "^4.1.7", + "tinymce": "^5.10.7", + "vue": "3.2.45", + "vue-focus-lock": "^2.0.5", + "vuex": "^4.1.0", + "vuex-persist": "^3.1.3" + }, + "devDependencies": { + "@babel/core": "^7.22.11", + "@babel/preset-env": "^7.22.14", + "@dgrammatiko/compress": "^1.0.4", + "@rollup/plugin-babel": "^5.3.1", + "@rollup/plugin-commonjs": "^21.1.0", + "@rollup/plugin-node-resolve": "^13.3.0", + "@rollup/plugin-replace": "^3.1.0", + "@vue/compiler-sfc": "^3.3.4", + "autoprefixer": "^10.4.15", + "chokidar": "^3.5.3", + "commander": "^8.3.0", + "core-js": "^3.32.1", + "cssnano": "^5.1.15", + "cypress": "^13.1.0", + "eslint": "^8.48.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-vue": "^8.7.1", + "fs-extra": "^10.1.0", + "ini": "^2.0.0", + "jasmine-core": "^3.99.1", + "joomla-cypress": "^0.0.16", + "mysql": "^2.18.1", + "postcss": "^8.4.29", + "postcss-scss": "^4.0.7", + "postgres": "^3.3.5", + "recursive-readdir": "^2.2.3", + "rimraf": "^3.0.2", + "rollup": "^2.79.1", + "rollup-plugin-vue": "^6.0.0", + "rtlcss": "^3.5.0", + "sass-embedded": "^1.66.1", + "smtp-tester": "^2.1.0", + "stylelint": "^14.16.1", + "stylelint-config-standard": "^24.0.0", + "stylelint-order": "^5.0.0", + "stylelint-scss": "^4.7.0", + "terser": "^5.19.3" + } +} From 2875f27a18d8921fe65ba5638d45c3a6d534a447 Mon Sep 17 00:00:00 2001 From: Denitz <197527+Denitz@users.noreply.github.com> Date: Mon, 11 Sep 2023 23:07:49 +0300 Subject: [PATCH 18/21] [4.4] Optimize scheduler running plugin (#37120) * fix * CS * CS * bind it! * Make Postgres happy * Postgressssss * CS * Update plugins/system/schedulerunner/schedulerunner.php Quy's suggestion Co-authored-by: Quy * Update plugins/system/schedulerunner/schedulerunner.php Quy's suggestion Co-authored-by: Quy * Update plugins/system/schedulerunner/schedulerunner.php Quy's suggestion Co-authored-by: Quy * fix * Use model method * Phase 1 convert BRANCH to PSR-12 * Phase 2 convert BRANCH to PSR-12 * fix CS * fix CS * Update administrator/components/com_scheduler/src/Model/TasksModel.php Co-authored-by: Allon Moritz * Update administrator/components/com_scheduler/src/Model/TasksModel.php Co-authored-by: Allon Moritz --------- Co-authored-by: Denitz Co-authored-by: Quy Co-authored-by: Joomla! Bot Co-authored-by: Allon Moritz Co-authored-by: Martin Carl Kopp <6154099+MacJoom@users.noreply.github.com> --- .../com_scheduler/src/Model/TasksModel.php | 35 +++++++++++++++++-- .../src/Extension/ScheduleRunner.php | 22 ++++-------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/administrator/components/com_scheduler/src/Model/TasksModel.php b/administrator/components/com_scheduler/src/Model/TasksModel.php index 95f3cc0170365..bac44530eff41 100644 --- a/administrator/components/com_scheduler/src/Model/TasksModel.php +++ b/administrator/components/com_scheduler/src/Model/TasksModel.php @@ -11,6 +11,7 @@ namespace Joomla\Component\Scheduler\Administrator\Model; use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Date\Date; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; @@ -366,7 +367,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0): array { // Get stuff from the model state $listOrder = $this->getState('list.ordering', 'a.title'); - $listDirectionN = strtolower($this->getState('list.direction', 'asc')) == 'desc' ? -1 : 1; + $listDirectionN = strtolower($this->getState('list.direction', 'asc')) === 'desc' ? -1 : 1; // Set limit parameters and get object list $query->setLimit($limit, $limitstart); @@ -395,7 +396,7 @@ static function (array $arr) { $this->attachTaskOptions($responseList); // If ordering by non-db fields, we need to sort here in code - if ($listOrder == 'j.type_title') { + if ($listOrder === 'j.type_title') { $responseList = ArrayHelper::sortObjects($responseList, 'safeTypeTitle', $listDirectionN, true, false); } @@ -437,4 +438,34 @@ protected function populateState($ordering = 'a.title', $direction = 'ASC'): voi // Call the parent method parent::populateState($ordering, $direction); } + + /** + * Check if we have any enabled due tasks and no locked tasks. + * + * @param Date $time The next execution time to check against + * + * @return boolean + * @since __DEPLOY_VERSION__ + */ + public function hasDueTasks(Date $time): bool + { + $db = $this->getDatabase(); + $now = $time->toSql(); + + $query = $db->getQuery(true) + // Count due tasks + ->select('SUM(CASE WHEN ' . $db->quoteName('a.next_execution') . ' <= :now THEN 1 ELSE 0 END) AS due_count') + // Count locked tasks + ->select('SUM(CASE WHEN ' . $db->quoteName('a.locked') . ' IS NULL THEN 0 ELSE 1 END) AS locked_count') + ->from($db->quoteName('#__scheduler_tasks', 'a')) + ->where($db->quoteName('a.state') . ' = 1') + ->bind(':now', $now); + + $db->setQuery($query); + + $taskDetails = $db->loadObject(); + + // False if we don't have due tasks, or we have locked tasks + return $taskDetails && $taskDetails->due_count && !$taskDetails->locked_count; + } } diff --git a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php index f4f507229f66f..7bac5df8ba957 100644 --- a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php +++ b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php @@ -19,6 +19,7 @@ use Joomla\CMS\Session\Session; use Joomla\CMS\Table\Extension; use Joomla\CMS\User\UserHelper; +use Joomla\Component\Scheduler\Administrator\Model\TasksModel; use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; use Joomla\Component\Scheduler\Administrator\Task\Task; use Joomla\Event\Event; @@ -109,22 +110,13 @@ public function injectLazyJS(EventInterface $event): void return; } - // Check if any task is due to decrease the load + /** @var TasksModel $model */ $model = $this->getApplication()->bootComponent('com_scheduler') ->getMVCFactory()->createModel('Tasks', 'Administrator', ['ignore_request' => true]); - $model->setState('filter.state', 1); - $model->setState('filter.due', 1); + $now = Factory::getDate('now', 'UTC'); - $items = $model->getItems(); - - // See if we are running currently - $model->setState('filter.locked', 1); - $model->setState('filter.due', 0); - - $items2 = $model->getItems(); - - if (empty($items) || !empty($items2)) { + if (!$model->hasDueTasks($now)) { return; } @@ -262,7 +254,7 @@ public function runTestCron(Event $event) ] ); - if (!is_null($task)) { + if ($task) { $task->run(); $event->addArgument('result', $task->getContent()); } else { @@ -286,7 +278,7 @@ public function runTestCron(Event $event) * @return ?Task * * @since 4.1.0 - * @throws RuntimeException + * @throws \RuntimeException */ private function runScheduler(int $id = 0): ?Task { @@ -301,7 +293,7 @@ private function runScheduler(int $id = 0): ?Task * @return void * * @since 4.1.0 - * @throws UnexpectedValueException|RuntimeException + * @throws \UnexpectedValueException|\RuntimeException * * @todo Move to another plugin? */ From a482eed1e1db670fdcacfe9e8897cb08f5a50299 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 12 Sep 2023 08:11:20 +0200 Subject: [PATCH 19/21] Change indentation to two spaces in composer.json --- composer.json | 103 -------------------------------------------------- 1 file changed, 103 deletions(-) diff --git a/composer.json b/composer.json index 4ceda79149fc8..a646e85f8de47 100644 --- a/composer.json +++ b/composer.json @@ -126,107 +126,4 @@ "php build/update_fido_cache.php" ] } - }, - "support": { - "issues": "https://issues.joomla.org/", - "irc": "irc://chat.freenode.net/joomla/", - "forum": "https://forum.joomla.org/", - "docs": "https://docs.joomla.org/" - }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/joomla-backports/json-api-php.git", - "no-api": true - } - ], - "autoload": { - "psr-4": { - "Joomla\\CMS\\": "libraries/src/" - } - }, - "autoload-dev": { - "psr-4": { - "Joomla\\Tests\\": "tests" - } - }, - "require": { - "php": "^7.2.5", - "joomla/application": "^2.0.4", - "joomla/archive": "^2.0.2", - "joomla/authentication": "^2.0.1", - "joomla/console": "^2.0.1", - "joomla/crypt": "^2.0.1", - "joomla/data": "^2.0.1", - "joomla/database": "^2.1.1", - "joomla/di": "^2.0.1", - "joomla/event": "^2.0.2", - "joomla/filter": "^2.0.3", - "joomla/filesystem": "^2.0.2", - "joomla/http": "^2.0.2", - "joomla/input": "^2.0.4", - "joomla/ldap": "~2.0.0", - "joomla/oauth1": "^2.0.2", - "joomla/oauth2": "^2.0.2", - "joomla/registry": "^2.0.4", - "joomla/router": "^2.0.1", - "joomla/session": "^2.0.2", - "joomla/string": "^2.0.1", - "joomla/uri": "^2.0.4", - "joomla/utilities": "^2.0.1", - "algo26-matthias/idna-convert": "^3.1.0", - "defuse/php-encryption": "^2.4.0", - "doctrine/inflector": "^1.4.4", - "fig/link-util": "^1.1.2", - "google/recaptcha": "^1.2.4", - "laminas/laminas-diactoros": "^2.4.1", - "paragonie/sodium_compat": "^1.20", - "phpmailer/phpmailer": "^6.8.1", - "psr/link": "~1.0.0", - "symfony/console": "^5.4.28", - "symfony/error-handler": "^5.4.26", - "symfony/ldap": "^5.4.27", - "symfony/options-resolver": "^5.4.21", - "symfony/polyfill-mbstring": "^1.28.0", - "symfony/polyfill-php73": "^1.28", - "symfony/polyfill-php80": "^1.28", - "symfony/polyfill-php81": "^1.28", - "symfony/web-link": "^5.4.21", - "symfony/yaml": "^5.4.23", - "typo3/phar-stream-wrapper": "^3.1.7", - "wamania/php-stemmer": "^2.2", - "maximebf/debugbar": "dev-master", - "tobscure/json-api": "dev-joomla-backports", - "willdurand/negotiation": "^3.1.0", - "ext-json": "*", - "ext-simplexml": "*", - "psr/log": "^1.1.4", - "ext-gd": "*", - "web-auth/webauthn-lib": "2.1.*", - "composer/ca-bundle": "^1.3.7", - "dragonmantank/cron-expression": "^3.3.3", - "enshrined/svg-sanitize": "^0.15.4", - "lcobucci/jwt": "^3.4.6", - "web-token/signature-pack": "^2.2.11", - "phpseclib/bcmath_compat": "^2.0.1", - "jfcherng/php-diff": "^6.10.14", - "voku/portable-utf8": "6.0.12 as 5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.33", - "friendsofphp/php-cs-fixer": "^3.4.0", - "squizlabs/php_codesniffer": "^3.7.2", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", - "joomla/mediawiki": "^1.0.0", - "joomla/test": "^2.0.2", - "phan/phan": "^5.4.2" - }, - "replace": { - "paragonie/random_compat": "9.99.99" - }, - "scripts": { - "post-install-cmd": [ - "php build/update_fido_cache.php" - ] - } } From f82d6105b4d3eca1950e5f449df9293c6bac95f8 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 12 Sep 2023 08:13:48 +0200 Subject: [PATCH 20/21] Update drone signature --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 79ea041b18740..e02b91e7420c0 100644 --- a/.drone.yml +++ b/.drone.yml @@ -372,6 +372,6 @@ trigger: --- kind: signature -hmac: 6b06b1c7f407650fe98f0851dc865911f399422116fa4f250a52d01a556397ed +hmac: 45b19b7430edc5ec922ef32c2f2dcb284c7cbf7ba55eb295ba4d877cee0fe5a4 ... From 7c21bc2498dec5a9cad16a7797f0a2e121e05964 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 12 Sep 2023 08:39:12 +0200 Subject: [PATCH 21/21] Fix merge conflict in package.json --- package.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/package.json b/package.json index 67479f51f961b..7bf093087304c 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,6 @@ { "name": "joomla", -<<<<<<< HEAD "version": "5.0.0", -======= - "version": "4.4.0", ->>>>>>> 4.4-dev "description": "Joomla CMS", "license": "GPL-2.0-or-later", "repository": {