mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°8760: revert dry removal audit and use real file deletion again
code formatting
This commit is contained in:
@@ -462,7 +462,6 @@ abstract class MetaModel
|
||||
return call_user_func([$sClass, 'GetClassDescription'], $sClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
*
|
||||
|
||||
@@ -26,23 +26,12 @@ use Composer\Semver\VersionParser;
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
||||
* @internal
|
||||
*/
|
||||
private static $selfDir = null;
|
||||
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $installedIsLocalDir;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
@@ -320,24 +309,6 @@ class InstalledVersions
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
|
||||
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
|
||||
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
|
||||
// so we have to assume it does not, and that may result in duplicate data being returned when listing
|
||||
// all installed packages for example
|
||||
self::$installedIsLocalDir = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private static function getSelfDir()
|
||||
{
|
||||
if (self::$selfDir === null) {
|
||||
self::$selfDir = strtr(__DIR__, '\\', '/');
|
||||
}
|
||||
|
||||
return self::$selfDir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -354,9 +325,7 @@ class InstalledVersions
|
||||
$copiedLocalDir = false;
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
$selfDir = self::getSelfDir();
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
@@ -364,14 +333,11 @@ class InstalledVersions
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
self::$installedByVendor[$vendorDir] = $required;
|
||||
$installed[] = $required;
|
||||
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
|
||||
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $required;
|
||||
self::$installedIsLocalDir = true;
|
||||
$copiedLocalDir = true;
|
||||
}
|
||||
}
|
||||
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
|
||||
$copiedLocalDir = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '19d062aa830b6d6c7d17ac4046fc9ee2c5e3fab1',
|
||||
'reference' => '469afdb2f9aea1b6e078a2a5bb12f09a969d60e0',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -22,7 +22,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '19d062aa830b6d6c7d17ac4046fc9ee2c5e3fab1',
|
||||
'reference' => '469afdb2f9aea1b6e078a2a5bb12f09a969d60e0',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Combodo\iTop\Setup\FeatureRemoval;
|
||||
|
||||
use iTopExtensionsMap;
|
||||
use MetaModel;
|
||||
use RunTimeEnvironment;
|
||||
use SetupUtils;
|
||||
|
||||
class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
||||
{
|
||||
const DRY_REMOVAL_AUDIT_ENV = "extension-removal";
|
||||
public const DRY_REMOVAL_AUDIT_ENV = "extension-removal";
|
||||
|
||||
protected array $aExtensionsByCode;
|
||||
private bool $bExtensionMapModified = false;
|
||||
@@ -37,18 +37,49 @@ class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
||||
|
||||
$sEnv = $this->sFinalEnv;
|
||||
$this->aExtensionsByCode = $aExtensionCodesToRemove;
|
||||
SetupUtils::rrmdir(APPROOT."/data/$sEnv-modules");
|
||||
SetupUtils::copydir(APPROOT."/data/$sSourceEnv-modules", APPROOT."/data/".$this->sFinalEnv."-modules");
|
||||
//SetupUtils::rrmdir(APPROOT."/data/$sEnv-modules");
|
||||
$this->Cleanup();
|
||||
SetupUtils::copydir(APPROOT."/data/$sSourceEnv-modules", APPROOT."/data/$sEnv-modules");
|
||||
|
||||
/*$oDryRemovalConfig = clone(MetaModel::GetConfig());
|
||||
if (count($aExtensionCodesToRemove) > 0) {
|
||||
$this->RemoveExtensionsLocally($aExtensionCodesToRemove);
|
||||
}
|
||||
$oDryRemovalConfig = clone(MetaModel::GetConfig());
|
||||
$oDryRemovalConfig->ChangeModulesPath($sSourceEnv, $this->sFinalEnv);
|
||||
$this->WriteConfigFileSafe($oDryRemovalConfig);*/
|
||||
$this->WriteConfigFileSafe($oDryRemovalConfig);
|
||||
}
|
||||
|
||||
private function RemoveExtensionsLocally(array $aExtensionCodes): void
|
||||
{
|
||||
$oExtensionsMap = new \iTopExtensionsMap($this->sFinalEnv);
|
||||
|
||||
foreach ($aExtensionCodes as $sCode) {
|
||||
/** @var \iTopExtension $oExtension */
|
||||
$oExtension = $oExtensionsMap->Get($sCode);
|
||||
if (!is_null($oExtension)) {
|
||||
$sDir = $oExtension->sSourceDir;
|
||||
\IssueLog::Info(__METHOD__.": remove extension locally", null, [$oExtension->sCode => $sDir]);
|
||||
SetupUtils::rrmdir($sDir);
|
||||
} else {
|
||||
\IssueLog::Warning(__METHOD__." cannot find extensions", null, ['env' => $this->sFinalEnv, 'code' => $sCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function Cleanup()
|
||||
{
|
||||
$sEnv = $this->sFinalEnv;
|
||||
SetupUtils::rrmdir(APPROOT."/data/$sEnv-modules");
|
||||
SetupUtils::rrmdir(APPROOT."/data/cache-$sEnv");
|
||||
SetupUtils::rrmdir(APPROOT."/env-$sEnv");
|
||||
SetupUtils::rrmdir(APPROOT."/conf/$sEnv");
|
||||
@unlink(APPROOT."/data/datamodel-$sEnv.xml");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \iTopExtensionsMap|null
|
||||
*/
|
||||
protected function GetExtensionMap(): ?iTopExtensionsMap
|
||||
/*protected function GetExtensionMap(): ?iTopExtensionsMap
|
||||
{
|
||||
if (is_null(parent::GetExtensionMap())) {
|
||||
return null;
|
||||
@@ -62,5 +93,5 @@ class DryRemovalRuntimeEnvironment extends RunTimeEnvironment
|
||||
}
|
||||
|
||||
return parent::GetExtensionMap();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class ModelReflectionSerializer
|
||||
$iRes = 0;
|
||||
exec(sprintf("$sPHPExec %s/get_model_reflection.php --env='%s'", __DIR__, $sEnv), $sOutput, $iRes);
|
||||
if ($iRes != 0) {
|
||||
\IssueLog::Error("Cannot get classes", null, ['code' => $iRes, "output" => $sOutput]);
|
||||
\IssueLog::Error("Cannot get classes", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]);
|
||||
throw new CoreException("Cannot get classes");
|
||||
}
|
||||
|
||||
@@ -52,4 +52,4 @@ class ModelReflectionSerializer
|
||||
|
||||
return $aClasses;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ require_once APPROOT.'setup/feature_removal/ModelReflectionSerializer.php';
|
||||
class SetupAudit
|
||||
{
|
||||
//file used when present to trigger audit exception when testing specific setups
|
||||
const GETISSUE_ERROR_MSG_FILE_FORTESTONLY = '.setup_audit_error_msg.txt';
|
||||
public const GETISSUE_ERROR_MSG_FILE_FORTESTONLY = '.setup_audit_error_msg.txt';
|
||||
|
||||
private string $sEnvBeforeExtensionRemoval;
|
||||
private string $sEnvAfterExtensionRemoval;
|
||||
@@ -123,4 +123,4 @@ class SetupAudit
|
||||
|
||||
return $oSet->Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
require_once(dirname(__DIR__, 2).'/approot.inc.php');
|
||||
require_once(APPROOT.'application/application.inc.php');
|
||||
|
||||
$sEnv = null;
|
||||
|
||||
if (isset($argv)) {
|
||||
foreach ($argv as $iArg => $sArg) {
|
||||
if (preg_match('/^--env=(.*)$/', $sArg, $aMatches)) {
|
||||
@@ -22,11 +20,12 @@ $sConfFile = utils::GetConfigFilePath($sEnv);
|
||||
|
||||
try {
|
||||
MetaModel::Startup($sConfFile, false /* $bModelOnly */, true /* $bAllowCache */, false /* $bTraceSourceFiles */, $sEnv);
|
||||
}
|
||||
catch (\Throwable $e) {
|
||||
} catch (\Throwable $e) {
|
||||
echo $e->getMessage();
|
||||
echo $e->getTraceAsString();
|
||||
\SetupLog::Error("Cannot read model from provided environment", null,
|
||||
\SetupLog::Error(
|
||||
"Cannot read model from provided environment",
|
||||
null,
|
||||
[
|
||||
'env' => $sEnv,
|
||||
'error' => $e->getMessage(),
|
||||
@@ -39,4 +38,4 @@ catch (\Throwable $e) {
|
||||
|
||||
$aClasses = MetaModel::GetClasses();
|
||||
|
||||
echo json_encode($aClasses);
|
||||
echo json_encode($aClasses);
|
||||
|
||||
@@ -2173,4 +2173,4 @@ class SetupInfo
|
||||
{
|
||||
return (array_key_exists($sModuleId, self::$aSelectedModules));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,4 +681,4 @@ class Step3 extends WizardStep
|
||||
}
|
||||
}
|
||||
|
||||
End of the example */
|
||||
End of the example */
|
||||
|
||||
@@ -2127,9 +2127,7 @@ class WizStepSummary extends WizardStep
|
||||
//$oSetupAudit->AuditExtensionsCleanupRules(true);
|
||||
//}
|
||||
*/
|
||||
}
|
||||
catch(MissingDependencyException $e)
|
||||
{
|
||||
} catch (MissingDependencyException $e) {
|
||||
$this->bDependencyCheck = false;
|
||||
$this->sDependencyIssue = $e->getHtmlDesc();
|
||||
}
|
||||
@@ -2596,4 +2594,4 @@ class WizStepDone extends WizardStep
|
||||
$oPage->add(file_get_contents($sBackupFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
static::LoadRequiredItopFiles();
|
||||
static::LoadRequiredItopFiles();
|
||||
if (is_null($this->oEnvironment)) {
|
||||
$this->oEnvironment = new UnitTestRunTimeEnvironment($this->GetTestEnvironment());
|
||||
}
|
||||
@@ -133,7 +133,6 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
// Note: To improve performances, we compile all XML deltas from test cases derived from this class and make a single environment where everything will be ran at once.
|
||||
// This requires XML deltas to be compatible, but it is a known and accepted trade-off. See PR #457
|
||||
if (false === $this->IsEnvironmentReady()) {
|
||||
|
||||
$this->debug("Preparing custom environment '$sTestEnv' with the following datamodel files:");
|
||||
foreach ($this->oEnvironment->GetCustomDatamodelFiles() as $sCustomDatamodelFile) {
|
||||
$this->debug(" - $sCustomDatamodelFile");
|
||||
@@ -190,8 +189,10 @@ abstract class ItopCustomDatamodelTestCase extends ItopDataTestCase
|
||||
CMDBSource::Query("CREATE TABLE $sNewDB.priv_module_install SELECT * FROM $sPreviousDB.priv_module_install");
|
||||
|
||||
$this->debug("Custom environment '$sTestEnv' is ready!");
|
||||
} else {
|
||||
$this->debug("Custom environment '$sTestEnv' READY BUILT:");
|
||||
}
|
||||
|
||||
parent::PrepareEnvironment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,6 @@ class UnitTestRunTimeEnvironment extends RunTimeEnvironment
|
||||
*/
|
||||
protected $aAdditionExtensionFoldersByCode = null;
|
||||
|
||||
public function GetEnvironment(): string
|
||||
{
|
||||
return $this->sFinalEnv;
|
||||
}
|
||||
|
||||
public function CompileFrom($sSourceEnv, $bUseSymLinks = null)
|
||||
{
|
||||
$sDestModulesDir = APPROOT.'data/'.$this->sTargetEnv.'-modules/';
|
||||
|
||||
@@ -26,4 +26,4 @@ class ModelSerializationTest extends ItopDataTestCase
|
||||
$this->expectExceptionMessage("Cannot get classes");
|
||||
ModelReflectionSerializer::GetInstance()->GetModelFromEnvironment('gabuzomeu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use Exception;
|
||||
|
||||
class SetupAuditTest extends ItopCustomDatamodelTestCase
|
||||
{
|
||||
const ENVT = 'php-unit-extensionremoval-tests';
|
||||
public const ENVT = 'php-unit-extensionremoval-tests';
|
||||
|
||||
public function GetDatamodelDeltaAbsPath(): string
|
||||
{
|
||||
@@ -115,4 +115,4 @@ class SetupAuditTest extends ItopCustomDatamodelTestCase
|
||||
$this->expectExceptionMessage('FinalClassFeature1Module1MyFinalClassFromLocation');
|
||||
$oSetupAudit->GetIssues(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
//// PHP Data Model definition file
|
||||
//
|
||||
//// WARNING - WARNING - WARNING
|
||||
@@ -12,4 +13,4 @@
|
||||
//// The recommended way to define new classes (for iTop 2.0) is via the XML definition.
|
||||
//// This file remains in the module's template only for the cases where there is:
|
||||
//// - either no new class or menu defined in the XML file
|
||||
//// - or no XML file at all supplied by the module
|
||||
//// - or no XML file at all supplied by the module
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -11,7 +12,7 @@
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'finalclass_ext1_module1/6.6.6',
|
||||
array(
|
||||
[
|
||||
// Identification
|
||||
//
|
||||
'label' => 'Ext For Test',
|
||||
@@ -19,32 +20,32 @@ SetupWebPage::AddModule(
|
||||
|
||||
// Setup
|
||||
//
|
||||
'dependencies' => array(
|
||||
'itop-structure/3.2.0',
|
||||
),
|
||||
'dependencies' => [
|
||||
'itop-structure/3.2.0',
|
||||
],
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
'installer' => '',
|
||||
|
||||
// Components
|
||||
//
|
||||
'datamodel' => array(
|
||||
'datamodel' => [
|
||||
'model.finalclass_ext1_module1.php',
|
||||
),
|
||||
'webservice' => array(),
|
||||
'data.struct' => array(// add your 'structure' definition XML files here,
|
||||
),
|
||||
'data.sample' => array(// add your sample data XML files here,
|
||||
),
|
||||
],
|
||||
'webservice' => [],
|
||||
'data.struct' => [// add your 'structure' definition XML files here,
|
||||
],
|
||||
'data.sample' => [// add your sample data XML files here,
|
||||
],
|
||||
|
||||
// Documentation
|
||||
//
|
||||
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
|
||||
// Default settings
|
||||
//
|
||||
'settings' => array(// Module specific settings go here, if any
|
||||
),
|
||||
)
|
||||
);
|
||||
'settings' => [// Module specific settings go here, if any
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
//// PHP Data Model definition file
|
||||
//
|
||||
//// WARNING - WARNING - WARNING
|
||||
@@ -12,4 +13,4 @@
|
||||
//// The recommended way to define new classes (for iTop 2.0) is via the XML definition.
|
||||
//// This file remains in the module's template only for the cases where there is:
|
||||
//// - either no new class or menu defined in the XML file
|
||||
//// - or no XML file at all supplied by the module
|
||||
//// - or no XML file at all supplied by the module
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -11,7 +12,7 @@
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'finalclass_ext2_module1/6.6.6',
|
||||
array(
|
||||
[
|
||||
// Identification
|
||||
//
|
||||
'label' => 'Ext For Test',
|
||||
@@ -19,32 +20,32 @@ SetupWebPage::AddModule(
|
||||
|
||||
// Setup
|
||||
//
|
||||
'dependencies' => array(
|
||||
'itop-structure/3.2.0',
|
||||
),
|
||||
'dependencies' => [
|
||||
'itop-structure/3.2.0',
|
||||
],
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
'installer' => '',
|
||||
|
||||
// Components
|
||||
//
|
||||
'datamodel' => array(
|
||||
'datamodel' => [
|
||||
'model.finalclass_ext2_module1.php',
|
||||
),
|
||||
'webservice' => array(),
|
||||
'data.struct' => array(// add your 'structure' definition XML files here,
|
||||
),
|
||||
'data.sample' => array(// add your sample data XML files here,
|
||||
),
|
||||
],
|
||||
'webservice' => [],
|
||||
'data.struct' => [// add your 'structure' definition XML files here,
|
||||
],
|
||||
'data.sample' => [// add your sample data XML files here,
|
||||
],
|
||||
|
||||
// Documentation
|
||||
//
|
||||
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
|
||||
// Default settings
|
||||
//
|
||||
'settings' => array(// Module specific settings go here, if any
|
||||
),
|
||||
)
|
||||
);
|
||||
'settings' => [// Module specific settings go here, if any
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
//// PHP Data Model definition file
|
||||
//
|
||||
//// WARNING - WARNING - WARNING
|
||||
@@ -12,4 +13,4 @@
|
||||
//// The recommended way to define new classes (for iTop 2.0) is via the XML definition.
|
||||
//// This file remains in the module's template only for the cases where there is:
|
||||
//// - either no new class or menu defined in the XML file
|
||||
//// - or no XML file at all supplied by the module
|
||||
//// - or no XML file at all supplied by the module
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
@@ -11,7 +12,7 @@
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'nominal_ext1_module1/6.6.6',
|
||||
array(
|
||||
[
|
||||
// Identification
|
||||
//
|
||||
'label' => 'Ext For Test',
|
||||
@@ -19,32 +20,32 @@ SetupWebPage::AddModule(
|
||||
|
||||
// Setup
|
||||
//
|
||||
'dependencies' => array(
|
||||
'itop-structure/3.2.0',
|
||||
),
|
||||
'dependencies' => [
|
||||
'itop-structure/3.2.0',
|
||||
],
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
'installer' => '',
|
||||
|
||||
// Components
|
||||
//
|
||||
'datamodel' => array(
|
||||
'datamodel' => [
|
||||
'model.nominal_ext1_module1.php',
|
||||
),
|
||||
'webservice' => array(),
|
||||
'data.struct' => array(// add your 'structure' definition XML files here,
|
||||
),
|
||||
'data.sample' => array(// add your sample data XML files here,
|
||||
),
|
||||
],
|
||||
'webservice' => [],
|
||||
'data.struct' => [// add your 'structure' definition XML files here,
|
||||
],
|
||||
'data.sample' => [// add your sample data XML files here,
|
||||
],
|
||||
|
||||
// Documentation
|
||||
//
|
||||
'doc.manual_setup' => '', // hyperlink to manual setup documentation, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
'doc.more_information' => '', // hyperlink to more information, if any
|
||||
|
||||
// Default settings
|
||||
//
|
||||
'settings' => array(// Module specific settings go here, if any
|
||||
),
|
||||
)
|
||||
);
|
||||
'settings' => [// Module specific settings go here, if any
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user