99
1010class Util
1111{
12+ const VERSION_LOCATIONS = [
13+ '/libraries/cms/version/version.php ' ,
14+ '/libraries/src/Version.php ' , // 3.8+
15+ '/libraries/joomla/version.php '
16+ ];
17+
1218 protected static $ _versions = array ();
1319
1420 public static function executeCommand (string $ command ): string
@@ -33,12 +39,12 @@ public static function executeCommand(string $command): string
3339
3440 public static function isJoomla4 ($ base ): bool
3541 {
36- return ( bool ) \version_compare ( static ::getJoomlaVersion ($ base )->release , ' 4.0.0 ' , ' >= ' ) ;
42+ return static ::getJoomlaVersion ($ base )->major >= 4 ;
3743 }
3844
3945 public static function executeJ4CliCommand ($ base , $ command ): string
4046 {
41- return static ::executeCommand (" php $ base/cli/joomla.php $ command" );
47+ return static ::executeCommand (PHP_BINARY . " " . escapeshellarg ( $ base . " /cli/joomla.php " ) . $ command );
4248 }
4349
4450 /**
@@ -56,82 +62,26 @@ public static function getJoomlaVersion($base)
5662
5763 if (!isset (self ::$ _versions [$ key ]))
5864 {
59- $ canonical = function ($ version ) {
60- if (isset ($ version ->RELEASE )) {
61- return 'v ' . $ version ->RELEASE . '. ' . $ version ->DEV_LEVEL ;
62- }
63-
64- // Joomla 3.5 and up uses constants instead of properties in JVersion
65- $ className = get_class ($ version );
66- if (defined ("$ className::RELEASE " )) {
67- return $ version ::RELEASE . '. ' . $ version ::DEV_LEVEL ;
68- }
69-
70- //start to provide support for Joomla 4 onwards
71- if (defined ( "$ className::MAJOR_VERSION " ) && in_array ($ version ::MAJOR_VERSION , ['4 ' , '5 ' ])){
72- return $ version ::MAJOR_VERSION . ". " . $ version ::MINOR_VERSION . ". " . $ version ::PATCH_VERSION . ($ version ::EXTRA_VERSION ? ". " . $ version ::EXTRA_VERSION : '' );
73- }
74-
75- return 'unknown ' ;
76- };
77-
78- $ files = array (
79- 'joomla-cms ' => '/libraries/cms/version/version.php ' ,
80- 'joomla-cms-new ' => '/libraries/src/Version.php ' , // 3.8+
81- 'joomla-1.5 ' => '/libraries/joomla/version.php '
82- );
83-
84- $ code = false ;
85- $ application = false ;
86- foreach ($ files as $ type => $ file )
65+ self ::$ _versions [$ key ] = false ;
66+ foreach (self ::VERSION_LOCATIONS as $ file )
8767 {
8868 $ path = $ base . $ file ;
8969
9070 if (file_exists ($ path ))
9171 {
92- $ code = $ path ;
93- $ application = $ type ;
72+ self ::$ _versions [$ key ] = VersionSniffer::fromFile ($ path );
9473
9574 break ;
9675 }
9776 }
9877
99- if ($ code !== false )
100- {
101- if (!defined ('JPATH_PLATFORM ' )) {
102- define ('JPATH_PLATFORM ' , self ::buildTargetPath ('/libraries ' , $ base ));
103- }
104-
105- if (!defined ('_JEXEC ' )) {
106- define ('_JEXEC ' , 1 );
107- }
108-
109- $ identifier = uniqid ();
110-
111- $ source = file_get_contents ($ code );
112- $ source = preg_replace ('/<\?php/ ' , '' , $ source , 1 );
113-
114- $ pattern = $ application == 'joomla-cms-new ' ? '/class Version/i ' : '/class JVersion/i ' ;
115- $ replacement = $ application == 'joomla-cms-new ' ? 'class Version ' . $ identifier : 'class JVersion ' . $ identifier ;
116-
117- $ source = preg_replace ($ pattern , $ replacement , $ source );
118-
119- eval ($ source );
120-
121- $ class = $ application == 'joomla-cms-new ' ? '\\Joomla \\CMS \\Version ' .$ identifier : 'JVersion ' .$ identifier ;
122- $ version = new $ class ();
123-
124- self ::$ _versions [$ key ] = (object ) array ('release ' => $ canonical ($ version ), 'type ' => $ application );
125- }
126- else self ::$ _versions [$ key ] = false ;
78+ return self ::$ _versions [$ key ];
12779 }
128-
129- return self ::$ _versions [$ key ];
13080 }
13181
13282 /**
13383 * Builds the full path for a given path inside a Joomla project.
134- *
84+ *
13585 * @param string $path The original relative path to the file/directory
13686 * @param string $base The root directory of the Joomla installation
13787 * @return string Target path
@@ -151,20 +101,21 @@ public static function buildTargetPath($path, $base = '')
151101 return $ base .$ path ;
152102 }
153103
154- /**
155- * Return a writable path
156- *
157- * @return string
158- */
104+ /**
105+ * Return a writable path
106+ *
107+ * @return string
108+ */
159109 public static function getWritablePath ()
160110 {
161111 $ path = \Phar::running ();
162112
163- if (!empty ($ path )) {
164- return sys_get_temp_dir () . '/.joomla ' ;
165- }
113+ $ templatePath = self ::getTemplatePath ();
114+ if (!empty ($ path ) || !is_writable ($ templatePath )) {
115+ return sys_get_temp_dir () . '/.joomla ' ;
116+ }
166117
167- return self :: getTemplatePath () ;
118+ return $ templatePath ;
168119 }
169120
170121 /**
@@ -176,12 +127,12 @@ public static function getTemplatePath()
176127 {
177128 $ path = \Phar::running ();
178129
179- if (!empty ($ path )) {
180- return $ path . DIRECTORY_SEPARATOR . 'bin ' . DIRECTORY_SEPARATOR . '.files ' ;
181- }
130+ if (!empty ($ path )) {
131+ return $ path . DIRECTORY_SEPARATOR . 'bin ' . DIRECTORY_SEPARATOR . '.files ' ;
132+ }
182133
183- $ root = dirname (dirname (dirname (dirname (__DIR__ ))));
134+ $ root = dirname (dirname (dirname (dirname (__DIR__ ))));
184135
185- return realpath ($ root .DIRECTORY_SEPARATOR . 'bin ' . DIRECTORY_SEPARATOR . '.files ' );
136+ return realpath ($ root .DIRECTORY_SEPARATOR . 'bin ' . DIRECTORY_SEPARATOR . '.files ' );
186137 }
187138}
0 commit comments