309 lines
11 KiB
PHP
309 lines
11 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; under version 2
|
||
|
* of the License (non-upgradable).
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* Copyright (c) 2008-2010 (original work) Deutsche Institut für Internationale Pädagogische Forschung (under the project TAO-TRANSFER);
|
||
|
* 2009-2012 (update and modification) Public Research Centre Henri Tudor (under the project TAO-SUSTAIN & TAO-DEV);
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
use oat\oatbox\service\ConfigurableService;
|
||
|
use oat\oatbox\service\ServiceManager;
|
||
|
use oat\oatbox\extension\exception\ManifestException;
|
||
|
use oat\oatbox\extension\ComposerInfo;
|
||
|
use oat\oatbox\cache\SimpleCache;
|
||
|
|
||
|
/**
|
||
|
* The ExtensionsManager class is dedicated to Extensions Management. It provides
|
||
|
* methods to know if an extension is enabled/disabled, obtain the list of currently
|
||
|
* available/installed extensions, the models that have to be loaded to run the extensions,
|
||
|
* obtain a reference on a particular test case.
|
||
|
*
|
||
|
* @access public
|
||
|
* @authorlionel@taotesting.com
|
||
|
* @package generis
|
||
|
* @see @license GNU General Public (GPL) Version 2 http://www.opensource.org/licenses/gpl-2.0.php
|
||
|
*/
|
||
|
class common_ext_ExtensionsManager extends ConfigurableService
|
||
|
{
|
||
|
const EXTENSIONS_CONFIG_KEY = 'installation';
|
||
|
|
||
|
const SERVICE_ID = 'generis/extensionManager';
|
||
|
|
||
|
public static $RESERVED_WORDS = [
|
||
|
'config', 'data', 'vendor', 'tests'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* The extensions currently loaded. The array contains
|
||
|
* references on common_ext_Extension class instances.
|
||
|
*
|
||
|
* @access private
|
||
|
* @var array
|
||
|
*/
|
||
|
private $extensions = [];
|
||
|
|
||
|
/**
|
||
|
* @deprecated Use ServiceManager::get(\common_ext_ExtensionsManager::SERVICE_ID) instead
|
||
|
*
|
||
|
* Obtain a reference on a unique common_ext_ExtensionsManager
|
||
|
* class instance.
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @return common_ext_ExtensionsManager
|
||
|
*/
|
||
|
public static function singleton()
|
||
|
{
|
||
|
return ServiceManager::getServiceManager()->get(self::class);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get list of ids of installed extensions
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function getInstalledExtensionsIds()
|
||
|
{
|
||
|
$installData = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
return is_array($installData) ? array_keys($installData) : [];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the set of currently installed extensions. This method
|
||
|
* returns an array of common_ext_Extension.
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getInstalledExtensions()
|
||
|
{
|
||
|
$returnValue = [];
|
||
|
foreach ($this->getInstalledExtensionsIds() as $extId) {
|
||
|
$returnValue[$extId] = $this->getExtensionById($extId);
|
||
|
}
|
||
|
return $returnValue;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all extensions that have to be loaded
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
*/
|
||
|
public function loadExtensions()
|
||
|
{
|
||
|
foreach ($this->extensions as $extension) {
|
||
|
//handle dependances requirement
|
||
|
foreach ($extension->getManifest()->getDependencies() as $ext => $version) {
|
||
|
if (!array_key_exists($ext, $this->extensions) && $ext != 'generis') {
|
||
|
throw new common_ext_ExtensionException('Required Extension is Missing : ' . $ext);
|
||
|
}
|
||
|
}
|
||
|
$extension->load();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Call a service to retrieve list of extensions that may be installed.
|
||
|
* This method returns an array of common_ext_Extension.
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getAvailableExtensions()
|
||
|
{
|
||
|
$returnValue = [];
|
||
|
$dir = new DirectoryIterator(ROOT_PATH);
|
||
|
foreach ($dir as $fileinfo) {
|
||
|
if ($fileinfo->isDir() && !$fileinfo->isDot() && substr($fileinfo->getBasename(), 0, 1) != '.') {
|
||
|
$extId = $fileinfo->getBasename();
|
||
|
if (!in_array($extId, self::$RESERVED_WORDS) && !$this->isInstalled($extId)) {
|
||
|
try {
|
||
|
$ext = $this->getExtensionById($extId);
|
||
|
$returnValue[] = $ext;
|
||
|
} catch (common_ext_ExtensionException $exception) {
|
||
|
common_Logger::d(sprintf('%s is not an extension (%s)', $extId, $exception->getMessage()));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $returnValue;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Short description of method getModelsToLoad
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getModelsToLoad()
|
||
|
{
|
||
|
$returnValue = [];
|
||
|
|
||
|
foreach ($this->getEnabledExtensions() as $ext) {
|
||
|
$returnValue = array_merge($returnValue, $ext->getManifest()->getModels());
|
||
|
}
|
||
|
$returnValue = array_unique($returnValue);
|
||
|
|
||
|
return (array) $returnValue;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get an extension by Id. If the extension is not yet loaded, it will be
|
||
|
* loaded using common_ext_Extension::load.
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @param string $id The id of the extension.
|
||
|
* @return common_ext_Extension A common_ext_Extension instance or null if it does not exist.
|
||
|
* @throws common_ext_ExtensionException If the provided id is empty.
|
||
|
*/
|
||
|
public function getExtensionById($id)
|
||
|
{
|
||
|
if (! is_string($id) || strlen($id) == 0) {
|
||
|
throw new common_ext_ExtensionException('No id specified for getExtensionById()');
|
||
|
}
|
||
|
if (! isset($this->extensions[$id])) {
|
||
|
$extension = new common_ext_Extension($id);
|
||
|
$this->propagate($extension);
|
||
|
|
||
|
// loads the extension if it hasn't been loaded yet
|
||
|
$extension->load();
|
||
|
// if successfully loaded add to list
|
||
|
$this->extensions[$id] = $extension;
|
||
|
}
|
||
|
|
||
|
return $this->extensions[$id];
|
||
|
}
|
||
|
|
||
|
public function isEnabled($extensionId)
|
||
|
{
|
||
|
$exts = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
return isset($exts[$extensionId]['enabled']) ? $exts[$extensionId]['enabled'] : false;
|
||
|
}
|
||
|
|
||
|
public function isInstalled($extensionId)
|
||
|
{
|
||
|
$exts = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
return isset($exts[$extensionId]);
|
||
|
}
|
||
|
|
||
|
public function getInstalledVersion($extensionId)
|
||
|
{
|
||
|
$exts = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
return isset($exts[$extensionId]) ? $exts[$extensionId]['installed'] : null;
|
||
|
}
|
||
|
|
||
|
public function setEnabled($extensionId, $enabled = true)
|
||
|
{
|
||
|
$exts = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
if (!isset($exts[$extensionId])) {
|
||
|
throw new common_exception_Error('Extension ' . $extensionId . ' unkown, cannot enable/disable');
|
||
|
}
|
||
|
$exts[$extensionId]['enabled'] = (bool) $enabled;
|
||
|
return $this->getExtensionById('generis')->setConfig(self::EXTENSIONS_CONFIG_KEY, $exts);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the set of currently enabled extensions. This method
|
||
|
* returns an array of common_ext_Extension.
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getEnabledExtensions()
|
||
|
{
|
||
|
$returnValue = [];
|
||
|
|
||
|
$enabled = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
foreach ($this->getInstalledExtensions() as $ext) {
|
||
|
if (isset($enabled[$ext->getId()]) && $enabled[$ext->getId()]['enabled']) {
|
||
|
$returnValue[$ext->getId()] = $ext;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (array) $returnValue;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add the end of an installation register the new extension
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @param common_ext_Extension $extension
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function registerExtension(common_ext_Extension $extension)
|
||
|
{
|
||
|
$entry = [
|
||
|
'installed' => $extension->getManifest()->getVersion(),
|
||
|
'enabled' => false
|
||
|
];
|
||
|
$extensions = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
$extensions[$extension->getId()] = $entry;
|
||
|
return $this->getExtensionById('generis')->setConfig(self::EXTENSIONS_CONFIG_KEY, $extensions);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add the end of an uninstallation unregister the extension
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Joel Bout, <joel@taotesting.com>
|
||
|
* @param common_ext_Extension $extension
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function unregisterExtension(common_ext_Extension $extension)
|
||
|
{
|
||
|
$extensions = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
unset($extensions[$extension->getId()]);
|
||
|
$this->getExtensionById('generis')->setConfig(self::EXTENSIONS_CONFIG_KEY, $extensions);
|
||
|
}
|
||
|
|
||
|
public function updateVersion(common_ext_Extension $extension, $version)
|
||
|
{
|
||
|
$extensions = $this->getExtensionById('generis')->getConfig(self::EXTENSIONS_CONFIG_KEY);
|
||
|
$extensions[$extension->getId()]['installed'] = $version;
|
||
|
$this->getExtensionById('generis')->setConfig(self::EXTENSIONS_CONFIG_KEY, $extensions);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Call a service to retrieve a map array of all available extensions
|
||
|
* with extension package id as a key and extension id as a value
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getAvailablePackages()
|
||
|
{
|
||
|
$composer = new ComposerInfo();
|
||
|
//During installation list of packages is needed but cache service is not installed yet.
|
||
|
if (!$this->getServiceManager()->has(SimpleCache::SERVICE_ID)) {
|
||
|
return $composer->getAvailableTaoExtensions();
|
||
|
}
|
||
|
/** @var SimpleCache $cache */
|
||
|
$cache = $this->getServiceManager()->get(SimpleCache::SERVICE_ID);
|
||
|
$key = static::class.'_'.__METHOD__;
|
||
|
if (!$cache->has($key)) {
|
||
|
$cache->set($key, $composer->getAvailableTaoExtensions());
|
||
|
}
|
||
|
|
||
|
return (array) $cache->get($key);
|
||
|
}
|
||
|
}
|