From 5d3c5bd7bb846b1153dc73842af6b249d99b5282 Mon Sep 17 00:00:00 2001 From: Matt Saladna Date: Tue, 21 Nov 2023 12:16:30 -0500 Subject: [PATCH 1/2] Require Composer dependencies against PHP 7.3 to preserve commitment --- composer.lock | 191 +++++++++++++++++++++++++------------------------- 1 file changed, 94 insertions(+), 97 deletions(-) diff --git a/composer.lock b/composer.lock index 19fa791..6ec7908 100644 --- a/composer.lock +++ b/composer.lock @@ -8,27 +8,22 @@ "packages": [ { "name": "psr/container", - "version": "2.0.2", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=7.4.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -55,22 +50,22 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "source": "https://github.com/php-fig/container/tree/1.1.1" }, - "time": "2021-11-05T16:47:00+00:00" + "time": "2021-03-05T17:36:06+00:00" }, { "name": "symfony/console", - "version": "v5.4.8", + "version": "v5.4.31", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b" + "reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b", - "reference": "ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b", + "url": "https://api.github.com/repos/symfony/console/zipball/11ac5f154e0e5c4c77af83ad11ead9165280b92a", + "reference": "11ac5f154e0e5c4c77af83ad11ead9165280b92a", "shasum": "" }, "require": { @@ -135,12 +130,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.8" + "source": "https://github.com/symfony/console/tree/v5.4.31" }, "funding": [ { @@ -156,29 +151,29 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:02:29+00:00" + "time": "2023-10-31T07:58:33+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -207,7 +202,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" }, "funding": [ { @@ -223,20 +218,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -251,7 +246,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -289,7 +284,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -305,20 +300,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -330,7 +325,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -370,7 +365,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -386,20 +381,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -411,7 +406,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -454,7 +449,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -470,20 +465,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -498,7 +493,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -537,7 +532,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -553,20 +548,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", "shasum": "" }, "require": { @@ -575,7 +570,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -616,7 +611,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" }, "funding": [ { @@ -632,20 +627,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.25.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -654,7 +649,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -699,7 +694,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, "funding": [ { @@ -715,25 +710,26 @@ "type": "tidelift" } ], - "time": "2022-03-04T08:16:47+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.0.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", "shasum": "" }, "require": { - "php": ">=8.0.2", - "psr/container": "^2.0" + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -744,7 +740,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -781,7 +777,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" }, "funding": [ { @@ -797,37 +793,38 @@ "type": "tidelift" } ], - "time": "2022-03-13T20:10:05+00:00" + "time": "2022-05-30T19:17:29+00:00" }, { "name": "symfony/string", - "version": "v6.0.8", + "version": "v5.4.31", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ac0aa5c2282e0de624c175b68d13f2c8f2e2649d" + "reference": "2765096c03f39ddf54f6af532166e42aaa05b24b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ac0aa5c2282e0de624c175b68d13f2c8f2e2649d", - "reference": "ac0aa5c2282e0de624c175b68d13f2c8f2e2649d", + "url": "https://api.github.com/repos/symfony/string/zipball/2765096c03f39ddf54f6af532166e42aaa05b24b", + "reference": "2765096c03f39ddf54f6af532166e42aaa05b24b", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" }, "conflict": { - "symfony/translation-contracts": "<2.0" + "symfony/translation-contracts": ">=3.0" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -866,7 +863,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.8" + "source": "https://github.com/symfony/string/tree/v5.4.31" }, "funding": [ { @@ -882,20 +879,20 @@ "type": "tidelift" } ], - "time": "2022-04-22T08:18:02+00:00" + "time": "2023-11-09T08:19:44+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.37", + "version": "v4.4.45", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311" + "reference": "aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d7f637cc0f0cc14beb0984f2bb50da560b271311", - "reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311", + "url": "https://api.github.com/repos/symfony/yaml/zipball/aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d", + "reference": "aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d", "shasum": "" }, "require": { @@ -937,7 +934,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v4.4.37" + "source": "https://github.com/symfony/yaml/tree/v4.4.45" }, "funding": [ { @@ -953,7 +950,7 @@ "type": "tidelift" } ], - "time": "2022-01-24T20:11:01+00:00" + "time": "2022-08-02T15:47:23+00:00" } ], "packages-dev": [], From 7f4852970378939a7aa286cade5d8ce8a212e748 Mon Sep 17 00:00:00 2001 From: Matt Saladna Date: Thu, 23 Nov 2023 20:11:55 -0500 Subject: [PATCH 2/2] Replace eval() with AST parser. plugin:list-all does not extend AbstractSite, infer $target_dir from CWD Remove non-specific "type" property from site:list Verify runtime path is writeable falling back to system temp directory. --- .../Console/Command/Database/Install.php | 8 +- .../Console/Command/Plugin/ListAll.php | 4 +- .../Console/Command/Site/Listing.php | 7 +- src/Joomlatools/Console/Joomla/Util.php | 107 +++++------------- .../Console/Joomla/VersionSniffer.php | 103 +++++++++++++++++ 5 files changed, 141 insertions(+), 88 deletions(-) create mode 100644 src/Joomlatools/Console/Joomla/VersionSniffer.php diff --git a/src/Joomlatools/Console/Command/Database/Install.php b/src/Joomlatools/Console/Command/Database/Install.php index be77813..699ed89 100644 --- a/src/Joomlatools/Console/Command/Database/Install.php +++ b/src/Joomlatools/Console/Command/Database/Install.php @@ -146,7 +146,7 @@ protected function execute(InputInterface $input, OutputInterface $output) }; $executeQuery("REPLACE INTO j_schemas (extension_id, version_id) VALUES (700, '$schema');"); - $executeQuery("UPDATE j_extensions SET manifest_cache = '{\"version\": \"$version->release\"}' WHERE manifest_cache = '';"); + $executeQuery("UPDATE j_extensions SET manifest_cache = '{\"version\": \"{$version->release}\"}' WHERE manifest_cache = '';"); } } @@ -179,7 +179,7 @@ public function check(InputInterface $input, OutputInterface $output) if($version !== false && $version->release) { - if (in_array($sample_data, array('testing', 'learn')) && version_compare($version->release, '3.0.0', '<')) { + if (in_array($sample_data, array('testing', 'learn')) && $version->major < 3) { throw new \RuntimeException(sprintf('%s does not support sample data %s', $version->release, $sample_data)); } } @@ -208,7 +208,7 @@ protected function _getSQLFiles(InputInterface $input, OutputInterface $output) if ($version !== false) { $users = 'joomla3.users.sql'; - if(is_numeric(substr($version->release, 0, 1)) && version_compare($version->release, '3.0.0', '<')) { + if($version->major < 3) { $users = 'joomla2.users.sql'; } $path = Util::getTemplatePath(); @@ -261,4 +261,4 @@ protected function _getInstallFiles($sample_data = false) return $files; } -} +} \ No newline at end of file diff --git a/src/Joomlatools/Console/Command/Plugin/ListAll.php b/src/Joomlatools/Console/Command/Plugin/ListAll.php index ad2a80c..1a08811 100644 --- a/src/Joomlatools/Console/Command/Plugin/ListAll.php +++ b/src/Joomlatools/Console/Command/Plugin/ListAll.php @@ -24,10 +24,10 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { - if (Util::isJoomla4($this->target_dir)) { + if (Util::isJoomla4(getcwd() ?: dirname(__FILE__))) { $output->write("This command is not implemented for Joomla 4\n"); - return; + return 1; } $plugins = $this->getApplication()->getPlugins(); diff --git a/src/Joomlatools/Console/Command/Site/Listing.php b/src/Joomlatools/Console/Command/Site/Listing.php index 035792f..d8710e3 100644 --- a/src/Joomlatools/Console/Command/Site/Listing.php +++ b/src/Joomlatools/Console/Command/Site/Listing.php @@ -64,7 +64,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $sites[] = (object) array( 'name' => $fileinfo->getFilename(), 'docroot' => $docroot . '/' . $fileinfo->getFilename() . '/', - 'type' => $version->type == 'joomla-cms-new' ? 'joomla-cms' : $version->type, 'version' => $version->release ); } @@ -82,14 +81,14 @@ protected function execute(InputInterface $input, OutputInterface $output) $result->command = $input->getArgument('command'); $result->data = $sites; - $options = (version_compare(phpversion(),'5.4.0') >= 0 ? JSON_PRETTY_PRINT : 0); + $options = (version_compare(PHP_VERSION,'5.4.0') >= 0 ? JSON_PRETTY_PRINT : 0); $string = json_encode($result, $options); break; case 'txt': default: $lines = array(); foreach ($sites as $i => $site) { - $lines[] = sprintf("%s. %s (%s %s)", ($i+1), $site->name, $site->type, $site->version); + $lines[] = sprintf("%s. %s (%s)", ($i+1), $site->name, $site->version); } $string = implode("\n", $lines); @@ -100,4 +99,4 @@ protected function execute(InputInterface $input, OutputInterface $output) return 0; } -} +} \ No newline at end of file diff --git a/src/Joomlatools/Console/Joomla/Util.php b/src/Joomlatools/Console/Joomla/Util.php index a997a3a..571a668 100644 --- a/src/Joomlatools/Console/Joomla/Util.php +++ b/src/Joomlatools/Console/Joomla/Util.php @@ -9,6 +9,12 @@ class Util { + const VERSION_LOCATIONS = [ + '/libraries/cms/version/version.php', + '/libraries/src/Version.php', // 3.8+ + '/libraries/joomla/version.php' + ]; + protected static $_versions = array(); public static function executeCommand(string $command): string @@ -33,12 +39,12 @@ public static function executeCommand(string $command): string public static function isJoomla4($base): bool { - return (bool) \version_compare(static::getJoomlaVersion($base)->release, '4.0.0', '>='); + return static::getJoomlaVersion($base)->major >= 4; } public static function executeJ4CliCommand($base, $command): string { - return static::executeCommand("php $base/cli/joomla.php $command"); + return static::executeCommand(PHP_BINARY . " " . escapeshellarg($base . "/cli/joomla.php") . $command); } /** @@ -56,82 +62,26 @@ public static function getJoomlaVersion($base) if (!isset(self::$_versions[$key])) { - $canonical = function($version) { - if (isset($version->RELEASE)) { - return 'v' . $version->RELEASE . '.' . $version->DEV_LEVEL; - } - - // Joomla 3.5 and up uses constants instead of properties in JVersion - $className = get_class($version); - if (defined("$className::RELEASE")) { - return $version::RELEASE . '.' . $version::DEV_LEVEL; - } - - //start to provide support for Joomla 4 onwards - if (defined( "$className::MAJOR_VERSION") && in_array($version::MAJOR_VERSION, ['4', '5'])){ - return $version::MAJOR_VERSION . "." . $version::MINOR_VERSION . "." . $version::PATCH_VERSION . ($version::EXTRA_VERSION ? "." . $version::EXTRA_VERSION : ''); - } - - return 'unknown'; - }; - - $files = array( - 'joomla-cms' => '/libraries/cms/version/version.php', - 'joomla-cms-new' => '/libraries/src/Version.php', // 3.8+ - 'joomla-1.5' => '/libraries/joomla/version.php' - ); - - $code = false; - $application = false; - foreach ($files as $type => $file) + self::$_versions[$key] = false; + foreach (self::VERSION_LOCATIONS as $file) { $path = $base . $file; if (file_exists($path)) { - $code = $path; - $application = $type; + self::$_versions[$key] = VersionSniffer::fromFile($path); break; } } - - if ($code !== false) - { - if (!defined('JPATH_PLATFORM')) { - define('JPATH_PLATFORM', self::buildTargetPath('/libraries', $base)); - } - - if (!defined('_JEXEC')) { - define('_JEXEC', 1); - } - - $identifier = uniqid(); - - $source = file_get_contents($code); - $source = preg_replace('/<\?php/', '', $source, 1); - - $pattern = $application == 'joomla-cms-new' ? '/class Version/i' : '/class JVersion/i'; - $replacement = $application == 'joomla-cms-new' ? 'class Version' . $identifier : 'class JVersion' . $identifier; - - $source = preg_replace($pattern, $replacement, $source); - - eval($source); - - $class = $application == 'joomla-cms-new' ? '\\Joomla\\CMS\\Version'.$identifier : 'JVersion'.$identifier; - $version = new $class(); - - self::$_versions[$key] = (object) array('release' => $canonical($version), 'type' => $application); - } - else self::$_versions[$key] = false; } - - return self::$_versions[$key]; + + return self::$_versions[$key]; } /** * Builds the full path for a given path inside a Joomla project. - * + * * @param string $path The original relative path to the file/directory * @param string $base The root directory of the Joomla installation * @return string Target path @@ -151,20 +101,21 @@ public static function buildTargetPath($path, $base = '') return $base.$path; } - /** - * Return a writable path - * - * @return string - */ + /** + * Return a writable path + * + * @return string + */ public static function getWritablePath() { $path = \Phar::running(); - if (!empty($path)) { - return sys_get_temp_dir() . '/.joomla'; - } + $templatePath = self::getTemplatePath(); + if (!empty($path) || !is_writable($templatePath)) { + return sys_get_temp_dir() . '/.joomla'; + } - return self::getTemplatePath(); + return $templatePath; } /** @@ -176,12 +127,12 @@ public static function getTemplatePath() { $path = \Phar::running(); - if (!empty($path)) { - return $path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . '.files'; - } + if (!empty($path)) { + return $path . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . '.files'; + } - $root = dirname(dirname(dirname(dirname(__DIR__)))); + $root = dirname(dirname(dirname(dirname(__DIR__)))); - return realpath($root .DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . '.files'); + return realpath($root .DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . '.files'); } } \ No newline at end of file diff --git a/src/Joomlatools/Console/Joomla/VersionSniffer.php b/src/Joomlatools/Console/Joomla/VersionSniffer.php new file mode 100644 index 0000000..0368d8b --- /dev/null +++ b/src/Joomlatools/Console/Joomla/VersionSniffer.php @@ -0,0 +1,103 @@ +create(\PhpParser\ParserFactory::PREFER_PHP7); + + $ast = $parser->parse($code); + + $nodeFinder = new NodeFinder; + $nodes = $nodeFinder->find($ast, function (Node $node) { + return $node instanceof Node\Const_ || $node instanceof Node\Stmt\PropertyProperty; + }); + foreach ($nodes as $node) { + $value = $node instanceof Node\Stmt\PropertyProperty ? $node->default : $node->value; + switch ((string)$node->name) { + case 'RELEASE': + // v3.5 <= version < 4.0 + [$major, $minor] = explode('.', $value->value); + $this->major = (int)$major; + $this->minor = (int)$minor; + break; + case 'MAJOR_VERSION': + $this->major = (int)$value->value; + break; + case 'MINOR_VERSION': + $this->minor = (int)$value->value; + break; + case 'PATCH_VERSION': + case 'DEV_LEVEL': + $this->patch = (int)$value->value; + break; + case 'EXTRA_VERSION': + case 'BUILD': + $this->extra = $value->value; + break; + } + } + $this->release = $this->version(); + } + + public static function fromFile(string $file): self + { + if (!is_file($file)) { + throw new \RuntimeException("File {$file} not found"); + } + + return new static(file_get_contents($file)); + } + + public function version(): string + { + if (empty($this->major)) { + return 'unknown'; + } + + return rtrim( + implode('.', [$this->major, $this->minor, $this->patch]) . '-' . $this->extra, + '-' + ); + } + + public function major(): ?int + { + return $this->major; + } + + public function minor(): ?int + { + return $this->minor; + } + + public function patch(): ?int + { + return $this->patch; + } + + public function extra(): ?string + { + return $this->extra; + } + } \ No newline at end of file