327 lines
9.9 KiB
PHP
327 lines
9.9 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) 2020 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
|
*
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace oat\oatbox\extension;
|
|
|
|
use oat\generis\model\DependencyInjection\ContainerServiceProviderInterface;
|
|
use oat\oatbox\extension\exception\ManifestException;
|
|
use oat\oatbox\extension\exception\ManifestNotFoundException;
|
|
use oat\oatbox\service\exception\InvalidServiceManagerException;
|
|
use Zend\ServiceManager\ServiceLocatorAwareTrait;
|
|
use Zend\ServiceManager\ServiceLocatorAwareInterface;
|
|
use Composer\InstalledVersions;
|
|
|
|
/**
|
|
* Class Manifest
|
|
* @author Jerome Bogaerts <jerome@taotesting.com>
|
|
* @package oat\oatbox\extension
|
|
*/
|
|
class Manifest implements ServiceLocatorAwareInterface
|
|
{
|
|
use ServiceLocatorAwareTrait;
|
|
|
|
/**
|
|
* The path to the file where the manifest is described.
|
|
* @var string
|
|
*/
|
|
private $filePath = '';
|
|
|
|
/**
|
|
* The version of the Extension the manifest describes.
|
|
* @var string
|
|
*/
|
|
private $version = null;
|
|
|
|
/**
|
|
* The dependencies of the Extension the manifest describes.
|
|
* @var array
|
|
*/
|
|
private $dependencies = [];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $manifest = [];
|
|
|
|
/**
|
|
* @var ComposerInfo
|
|
*/
|
|
private $composerInfo = null;
|
|
|
|
/**
|
|
* Creates a new instance of Manifest.
|
|
*
|
|
* @access public
|
|
* @param string $filePath The path to the manifest.php file to parse.
|
|
* @param ComposerInfo|null $composerInfo
|
|
* @throws ManifestNotFoundException
|
|
* @throws exception\MalformedManifestException
|
|
*/
|
|
public function __construct($filePath, ComposerInfo $composerInfo = null)
|
|
{
|
|
// the file exists, we can refer to the $filePath.
|
|
if (!is_readable($filePath)) {
|
|
throw new ManifestNotFoundException("The Extension Manifest file located at '${filePath}' could not be read.");
|
|
}
|
|
$this->manifest = require($filePath);
|
|
// mandatory
|
|
if (empty($this->manifest['name'])) {
|
|
throw new exception\MalformedManifestException("The 'name' component is mandatory in manifest located at '{$this->filePath}'.");
|
|
}
|
|
$this->composerInfo = $composerInfo;
|
|
$this->filePath = $filePath;
|
|
}
|
|
|
|
/**
|
|
* Get the name of the Extension the manifest describes.
|
|
* @return string
|
|
*/
|
|
public function getName(): string
|
|
{
|
|
return isset($this->manifest['name']) ? $this->manifest['name'] : '';
|
|
}
|
|
|
|
/**
|
|
* Get the description of the Extension the manifest describes.
|
|
* @return string
|
|
*/
|
|
public function getDescription(): string
|
|
{
|
|
return isset($this->manifest['description']) ? $this->manifest['description'] : '';
|
|
}
|
|
|
|
/**
|
|
* Get the author of the Extension the manifest describes.
|
|
* @return string
|
|
*/
|
|
public function getAuthor(): string
|
|
{
|
|
return isset($this->manifest['author']) ? $this->manifest['author'] : '';
|
|
}
|
|
|
|
/**
|
|
* Get the human readable label of the Extension the manifest describes.
|
|
* @return string
|
|
*/
|
|
public function getLabel(): string
|
|
{
|
|
return isset($this->manifest['label']) ? $this->manifest['label'] : '';
|
|
}
|
|
|
|
/**
|
|
* Returns the Access Control Layer table
|
|
* @return array
|
|
*/
|
|
public function getAclTable(): array
|
|
{
|
|
return isset($this->manifest['acl']) ? $this->manifest['acl'] : [];
|
|
}
|
|
|
|
/**
|
|
* Get the version of the Extension the manifest describes.
|
|
* @return string
|
|
* @throws ManifestException
|
|
*/
|
|
public function getVersion():string
|
|
{
|
|
if ($this->version === null) {
|
|
$packageId = $this->getComposerInfo()->getPackageId();
|
|
$this->version = InstalledVersions::getVersion($packageId);
|
|
}
|
|
return (string) $this->version;
|
|
}
|
|
|
|
/**
|
|
* Get the dependencies of the Extension the manifest describes.
|
|
* The content of the array are extensionIDs, represented as strings.
|
|
* @return array
|
|
* @throws ManifestException
|
|
* @throws InvalidServiceManagerException
|
|
*/
|
|
public function getDependencies(): array
|
|
{
|
|
if (empty($this->dependencies)) {
|
|
$this->dependencies = $this->getComposerInfo()->extractExtensionDependencies();
|
|
//backward compatibility with old requirements declaration
|
|
//todo: remove after dependencies of all Tao extensions be moved from manifest to composer.json
|
|
if (isset($this->manifest['requires'])) {
|
|
$this->dependencies = array_merge($this->dependencies, $this->manifest['requires']);
|
|
}
|
|
}
|
|
return $this->dependencies;
|
|
}
|
|
|
|
/**
|
|
* returns an array of RDF files to import during install.
|
|
* The returned array contains paths to the files to be imported.
|
|
* @return array
|
|
*/
|
|
public function getInstallModelFiles(): array
|
|
{
|
|
if (!isset($this->manifest['install']['rdf'])) {
|
|
return [];
|
|
}
|
|
$files = is_array($this->manifest['install']['rdf']) ?
|
|
$this->manifest['install']['rdf'] :
|
|
[$this->manifest['install']['rdf']];
|
|
$files = array_filter($files);
|
|
return (array) $files;
|
|
}
|
|
|
|
/**
|
|
* Get a list of PHP files to be executed at installation time.
|
|
* The returned array contains absolute paths to the files to execute.
|
|
* @return array
|
|
*/
|
|
public function getInstallPHPFiles(): array
|
|
{
|
|
$result = [];
|
|
if (isset($this->manifest['install']['php'])) {
|
|
$result = is_array($this->manifest['install']['php']) ? $this->manifest['install']['php'] : [$this->manifest['install']['php']];
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Return the uninstall data as an array if present, or null if not
|
|
* @return mixed
|
|
*/
|
|
public function getUninstallData()
|
|
{
|
|
return isset($this->manifest['uninstall']) ? $this->manifest['uninstall'] : null;
|
|
}
|
|
|
|
/**
|
|
* Return the className of the updateHandler
|
|
* @return string
|
|
*/
|
|
public function getUpdateHandler()
|
|
{
|
|
return isset($this->manifest['update']) ? $this->manifest['update'] : null;
|
|
}
|
|
|
|
/**
|
|
* PHP scripts to execute in order to add some sample data to an install
|
|
* @return array
|
|
*/
|
|
public function getLocalData()
|
|
{
|
|
return isset($this->manifest['local']) ? $this->manifest['local'] : [];
|
|
}
|
|
|
|
/**
|
|
* Gets the controller routes of this extension.
|
|
* @return array
|
|
*/
|
|
public function getRoutes()
|
|
{
|
|
return isset($this->manifest['routes']) ? $this->manifest['routes'] : [];
|
|
}
|
|
|
|
/**
|
|
* Get an array of constants to be defined where array keys are constant names
|
|
* and values are the values of these constants.
|
|
* @return array
|
|
*/
|
|
public function getConstants(): array
|
|
{
|
|
return isset($this->manifest['constants']) && is_array($this->manifest['constants'])
|
|
? $this->manifest['constants'] : [];
|
|
}
|
|
|
|
/**
|
|
* Get the array with unformatted extra data
|
|
* @return array
|
|
*/
|
|
public function getExtra()
|
|
{
|
|
return isset($this->manifest['extra']) ? $this->manifest['extra'] : [];
|
|
}
|
|
|
|
/**
|
|
* @return ContainerServiceProviderInterface[]
|
|
*/
|
|
public function getContainerServiceProvider(): array
|
|
{
|
|
return $this->manifest['containerServiceProviders'] ?? [];
|
|
}
|
|
|
|
/**
|
|
* Extract dependencies for extensions
|
|
* @param string $file
|
|
* @return array
|
|
* @throws \common_ext_ExtensionException
|
|
*/
|
|
public static function extractDependencies(string $file)
|
|
{
|
|
$file = realpath($file);
|
|
$composer = new ComposerInfo(dirname($file));
|
|
return array_keys($composer->extractExtensionDependencies());
|
|
}
|
|
|
|
/**
|
|
* Extract checks from a given manifest file.
|
|
* @param $file string The path to a manifest.php file.
|
|
* @return \common_configuration_ComponentCollection
|
|
* @throws ManifestNotFoundException
|
|
*/
|
|
public static function extractChecks(string $file)
|
|
{
|
|
// the file exists, we can refer to the $filePath.
|
|
if (!is_readable($file)) {
|
|
throw new ManifestNotFoundException(sprintf('The Extension Manifest file located at %s could not be read.', $file));
|
|
}
|
|
|
|
$manifest = require($file);
|
|
$returnValue = $manifest['install']['checks'] ?? [];
|
|
foreach ($returnValue as &$component) {
|
|
if (strpos($component['type'], 'FileSystemComponent') !== false) {
|
|
$root = realpath(dirname(__FILE__) . '/../../../../');
|
|
$component['value']['location'] = $root . '/' . $component['value']['location'];
|
|
}
|
|
}
|
|
|
|
return $returnValue;
|
|
}
|
|
|
|
/**
|
|
* Get the Role dedicated to manage this extension. Returns null if there is
|
|
* @return string
|
|
*/
|
|
public function getManagementRoleUri()
|
|
{
|
|
return isset($this->manifest['managementRole']) ? $this->manifest['managementRole'] : '';
|
|
}
|
|
|
|
/**
|
|
* @return ComposerInfo
|
|
* @throws \common_ext_ExtensionException
|
|
*/
|
|
private function getComposerInfo()
|
|
{
|
|
if ($this->composerInfo === null) {
|
|
$this->composerInfo = new ComposerInfo(dirname($this->filePath));
|
|
}
|
|
return $this->composerInfo;
|
|
}
|
|
}
|