D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
psa
/
admin
/
plib
/
vendor
/
plesk
/
wappspector
/
src
/
Matchers
/
Filename :
Joomla.php
back
Copy
<?php namespace Plesk\Wappspector\Matchers; use League\Flysystem\Filesystem; use League\Flysystem\FilesystemException; use Plesk\Wappspector\MatchResult\EmptyMatchResult; use Plesk\Wappspector\MatchResult\Joomla as MatchResult; use Plesk\Wappspector\MatchResult\MatchResultInterface; class Joomla implements MatcherInterface { private const CONFIG_FILE = 'configuration.php'; /** * Joomla has changed the way how the version number is stored multiple times, so we need this comprehensive array */ private const VERSION = [ "files" => [ "/includes/version.php", "/libraries/joomla/version.php", "/libraries/cms/version/version.php", "/libraries/src/Version.php", ], "regex_release" => "/\\\$?RELEASE\s*=\s*'([\d.]+)';/", "regex_devlevel" => "/\\\$?DEV_LEVEL\s*=\s*'([^']+)';/", "regex_major" => "/\\\$?MAJOR_VERSION\s*=\s*([\d.]+);/", "regex_minor" => "/\\\$?MINOR_VERSION\s*=\s*([\d.]+);/", "regex_patch" => "/\\\$?PATCH_VERSION\s*=\s*([\d.]+);/", ]; /** * @throws FilesystemException */ private function isJoomla(Filesystem $fs, string $path): bool { $configFile = rtrim($path, '/') . '/' . self::CONFIG_FILE; if (!$fs->fileExists($configFile)) { return false; } $configContents = $fs->read($configFile); if ( stripos($configContents, 'JConfig') === false && stripos($configContents, 'mosConfig') === false ) { return false; } // False positive "Akeeba Backup Installer" if (stripos($configContents, 'class ABIConfiguration') !== false) { return false; } // False positive mock file in unit test folder if (stripos($configContents, 'Joomla.UnitTest') !== false) { return false; } // False positive mock file in unit test folder return stripos($configContents, "Joomla\Framework\Test") === false; } /** * @throws FilesystemException */ private function detectVersion(Filesystem $fs, string $path): ?string { // Iterate through version files foreach (self::VERSION['files'] as $file) { $versionFile = rtrim($path, '/') . '/' . $file; if (!$fs->fileExists($versionFile)) { continue; } $fileContents = $fs->read($versionFile); preg_match(self::VERSION['regex_major'], $fileContents, $major); preg_match(self::VERSION['regex_minor'], $fileContents, $minor); preg_match(self::VERSION['regex_patch'], $fileContents, $patch); if (count($major) && count($minor) && count($patch)) { return $major[1] . '.' . $minor[1] . '.' . $patch[1]; } if (count($major) && count($minor)) { return $major[1] . '.' . $minor[1] . 'x'; } if ($major !== []) { return $major[1] . '.x.x'; } // Legacy handling for all version < 3.8.0 preg_match(self::VERSION['regex_release'], $fileContents, $release); preg_match(self::VERSION['regex_devlevel'], $fileContents, $devlevel); if (count($release) && count($devlevel)) { return $release[1] . '.' . $devlevel[1]; } if ($release !== []) { return $release[1] . '.x'; } } return null; } /** * @throws FilesystemException */ public function match(Filesystem $fs, string $path): MatchResultInterface { if (!$this->isJoomla($fs, $path)) { return new EmptyMatchResult(); } return new MatchResult($path, $this->detectVersion($fs, $path)); } }