159 lines
3.4 KiB
PHP
159 lines
3.4 KiB
PHP
<?php
|
|
/**
|
|
* @package FOF
|
|
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
|
|
* @license GNU General Public License version 3, or later
|
|
*/
|
|
|
|
namespace FOF40\JoomlaAbstraction;
|
|
|
|
defined('_JEXEC') || die;
|
|
|
|
use Exception;
|
|
use Joomla\CMS\Factory as JoomlaFactory;
|
|
use SimpleXMLElement;
|
|
|
|
/**
|
|
* Retrieve the version of a component from the cached XML manifest or, if it's not present, the version recorded in the
|
|
* database.
|
|
*/
|
|
abstract class ComponentVersion
|
|
{
|
|
/**
|
|
* A cache with the version numbers of components
|
|
*
|
|
* @var array
|
|
*
|
|
* @since 3.1.5
|
|
*/
|
|
private static $version = array();
|
|
|
|
/**
|
|
* Get a component's version. The XML manifest on disk will be tried first. If it's not there or does not have a
|
|
* version string the manifest cache in the database is tried. If that fails a fake version number will be returned.
|
|
*
|
|
* @param string $component The name of the component, e.g. com_foobar
|
|
*
|
|
* @return string The version string
|
|
*
|
|
* @since 3.1.5
|
|
*/
|
|
public static function getFor(string $component): string
|
|
{
|
|
if (!isset(self::$version[$component]))
|
|
{
|
|
self::$version[$component] = null;
|
|
}
|
|
|
|
if (is_null(self::$version[$component]))
|
|
{
|
|
self::$version[$component] = self::getVersionFromManifest($component);
|
|
}
|
|
|
|
if (is_null(self::$version[$component]))
|
|
{
|
|
self::$version[$component] = self::getVersionFromDatabase($component);
|
|
}
|
|
|
|
if (is_null(self::$version[$component]))
|
|
{
|
|
self::$version[$component] = 'dev-' . str_replace(' ', '_', microtime(false));
|
|
}
|
|
|
|
return self::$version[$component];
|
|
}
|
|
|
|
/**
|
|
* Get a component's version from the manifest cache in the database
|
|
*
|
|
* @param string $component The component's bname
|
|
*
|
|
* @return string|null The component version or null if none is defined
|
|
*
|
|
* @since 3.1.5
|
|
*/
|
|
private static function getVersionFromDatabase(string $component): ?string
|
|
{
|
|
$db = JoomlaFactory::getDbo();
|
|
$query = $db->getQuery(true)
|
|
->select($db->qn('manifest_cache'))
|
|
->from($db->qn('#__extensions'))
|
|
->where($db->qn('element') . ' = ' . $db->q($component))
|
|
->where($db->qn('type') . ' = ' . $db->q('component'));
|
|
|
|
try
|
|
{
|
|
$json = $db->setQuery($query)->loadResult();
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (empty($json))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$options = json_decode($json, true);
|
|
|
|
if (empty($options))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (!isset($options['version']))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return $options['version'];
|
|
}
|
|
|
|
/**
|
|
* Get a component's version from the manifest file on disk. IMPORTANT! The manifest for com_something must be named
|
|
* something.xml.
|
|
*
|
|
* @param string $component The component's bname
|
|
*
|
|
* @return string The component version or null if none is defined
|
|
*
|
|
* @since 1.2.0
|
|
*/
|
|
private static function getVersionFromManifest(string $component): ?string
|
|
{
|
|
$bareComponent = str_replace('com_', '', $component);
|
|
$file = JPATH_ADMINISTRATOR . '/components/' . $component . '/' . $bareComponent . '.xml';
|
|
|
|
if (!is_file($file) || !is_readable($file))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$data = @file_get_contents($file);
|
|
|
|
if (empty($data))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
$xml = new SimpleXMLElement($data, LIBXML_COMPACT | LIBXML_NONET | LIBXML_ERR_NONE);
|
|
}
|
|
catch (Exception $e)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$versionNode = $xml->xpath('/extension/version');
|
|
|
|
if (empty($versionNode))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return (string)($versionNode[0]);
|
|
}
|
|
}
|