From c6be331f146db63a8c8ae9b43071bfc4e8b89a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20Espi=C3=A9?= Date: Mon, 14 May 2018 07:41:51 +0000 Subject: [PATCH] Code cleanup SVN:trunk[5779] --- core/designdocument.class.inc.php | 82 ++-- setup/compat/domcompat.php | 48 ++ setup/modelfactory.class.inc.php | 698 +++++++++++++++++++--------- setup/modulediscovery.class.inc.php | 86 ++-- 4 files changed, 630 insertions(+), 284 deletions(-) create mode 100644 setup/compat/domcompat.php diff --git a/core/designdocument.class.inc.php b/core/designdocument.class.inc.php index 0d3cafc1b..2be363414 100644 --- a/core/designdocument.class.inc.php +++ b/core/designdocument.class.inc.php @@ -1,20 +1,23 @@ +/** + * Copyright (c) 2010-2018 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with iTop. If not, see + * + */ /** * Design document and associated nodes @@ -57,6 +60,9 @@ class DesignDocument extends DOMDocument /** * Overload of the standard API + * + * @param $filename + * @param int $options */ public function load($filename, $options = 0) { @@ -65,6 +71,11 @@ class DesignDocument extends DOMDocument /** * Overload of the standard API + * + * @param $filename + * @param int $options + * + * @return int */ public function save($filename, $options = 0) { @@ -84,18 +95,18 @@ class DesignDocument extends DOMDocument { return $sXml; } - else - { - echo "
\n";
-			echo htmlentities($sXml);
-			echo "
\n"; - } + + echo "
\n";
+		echo htmlentities($sXml);
+		echo "
\n"; + + return ''; } /** * Quote and escape strings for use within an XPath expression * Usage: DesignDocument::GetNodes('class[@id='.DesignDocument::XPathQuote($sId).']'); - * @param $sValue The value to be quoted + * @param string $sValue The value to be quoted * @return string to be used within an XPath */ public static function XPathQuote($sValue) @@ -115,7 +126,7 @@ class DesignDocument extends DOMDocument /** * Extracts some nodes from the DOM * @param string $sXPath A XPath expression - * @param DesignNode|null $oContextNode The node to start the search from + * @param DesignElement $oContextNode The node to start the search from * @return \DOMNodeList */ public function GetNodes($sXPath, $oContextNode = null) @@ -134,7 +145,7 @@ class DesignDocument extends DOMDocument /** * An alternative to getNodePath, that gives the id of nodes instead of the position within the children - * @param $oNode The node to describe + * @param DesignElement $oNode The node to describe * @return string */ public static function GetItopNodePath($oNode) @@ -166,8 +177,11 @@ class DesignElement extends \DOMElement /** * Create an HTML representation of the DOM, for debugging purposes + * * @param bool|false $bReturnRes Echoes or returns the HTML representation + * * @return mixed void or the HTML representation of the DOM + * @throws \Exception */ public function Dump($bReturnRes = false) { @@ -180,19 +194,16 @@ class DesignElement extends \DOMElement { return $sXml; } - else - { - echo "
\n";
-			echo htmlentities($sXml);
-			echo "
\n"; - } + echo "
\n";
+		echo htmlentities($sXml);
+		echo "
\n"; + return ''; } - /** * Returns the node directly under the given node * @param $sTagName * @param bool|true $bMustExist - * @return MFElement + * @return \MFElement * @throws DOMFormatException */ public function GetUniqueElement($sTagName, $bMustExist = true) @@ -216,7 +227,7 @@ class DesignElement extends \DOMElement /** * Returns the node directly under the current node, or null if missing * @param $sTagName - * @return MFElement + * @return \MFElement * @throws DOMFormatException */ public function GetOptionalElement($sTagName) @@ -252,9 +263,12 @@ class DesignElement extends \DOMElement /** * Get the TEXT value from a child node + * * @param string $sTagName * @param string|null $sDefault + * * @return string + * @throws \DOMFormatException */ public function GetChildText($sTagName, $sDefault = null) { diff --git a/setup/compat/domcompat.php b/setup/compat/domcompat.php new file mode 100644 index 000000000..7a2dd9ee1 --- /dev/null +++ b/setup/compat/domcompat.php @@ -0,0 +1,48 @@ + + * + */ + + +/** + * Allow the setup page to load and perform its checks (including the check about the required extensions) + */ +if (!class_exists('DOMDocument')) +{ + /** + * Class DOMDocument + */ + class DOMDocument { + function __construct(){throw new Exception('The dom extension is not enabled');} + } +} + + +/** + * Allow the setup page to load and perform its checks (including the check about the required extensions) + */ +if (!class_exists('DOMElement')) +{ + /** + * Class DOMElement + */ + class DOMElement { + function __construct(){throw new Exception('The dom extension is not enabled');} + } +} diff --git a/setup/modelfactory.class.inc.php b/setup/modelfactory.class.inc.php index 76a646008..0965599ba 100644 --- a/setup/modelfactory.class.inc.php +++ b/setup/modelfactory.class.inc.php @@ -1,31 +1,31 @@ +/** + * Copyright (c) 2010-2018 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with iTop. If not, see + * + */ /** * ModelFactory: in-memory manipulation of the XML MetaModel - * - * @copyright Copyright (C) 2010-2017 Combodo SARL - * @license http://opensource.org/licenses/AGPL-3.0 */ - require_once(APPROOT.'setup/moduleinstaller.class.inc.php'); require_once(APPROOT.'setup/itopdesignformat.class.inc.php'); +require_once(APPROOT.'setup/compat/domcompat.php'); require_once(APPROOT.'core/designdocument.class.inc.php'); /** @@ -46,7 +46,7 @@ class MFException extends Exception * @var string */ protected $sExtraInfo; - + const COULD_NOT_BE_ADDED = 1; const COULD_NOT_BE_DELETED = 2; const COULD_NOT_BE_MODIFIED_NOT_FOUND = 3; @@ -56,7 +56,17 @@ class MFException extends Exception const NOT_FOUND = 7; const PARENT_NOT_FOUND = 8; - + + /** + * MFException constructor. + * + * @param null $message + * @param null $code + * @param int $iSourceLineNumber + * @param string $sXPath + * @param string $sExtraInfo + * @param null $previous + */ public function __construct ($message = null, $code = null, $iSourceLineNumber = 0, $sXPath = '', $sExtraInfo = '', $previous = null) { parent::__construct($message, $code, $previous); @@ -99,16 +109,51 @@ class MFException extends Exception */ class MFModule { + /** + * @var string + */ protected $sId; + /** + * @var string + */ protected $sName; + /** + * @var string + */ protected $sVersion; + /** + * @var string + */ protected $sRootDir; + /** + * @var string + */ protected $sLabel; + /** + * @var array + */ protected $aDataModels; + /** + * @var bool + */ protected $bAutoSelect; + /** + * @var string + */ protected $sAutoSelect; + /** + * @var array + */ protected $aFilesToInclude; - + + /** + * MFModule constructor. + * + * @param $sId + * @param $sRootDir + * @param $sLabel + * @param bool $bAutoSelect + */ public function __construct($sId, $sRootDir, $sLabel, $bAutoSelect = false) { $this->sId = $sId; @@ -140,38 +185,59 @@ class MFModule closedir($hDir); } } - - + + + /** + * @return mixed + */ public function GetId() { return $this->sId; } - + + /** + * @return mixed + */ public function GetName() { return $this->sName; } + /** + * @return string + */ public function GetVersion() { return $this->sVersion; } + /** + * @return mixed + */ public function GetLabel() { return $this->sLabel; } - + + /** + * @return mixed + */ public function GetRootDir() { return $this->sRootDir; } + /** + * @return string + */ public function GetModuleDir() { return basename($this->sRootDir); } + /** + * @return array + */ public function GetDataModelFiles() { return $this->aDataModels; @@ -184,7 +250,10 @@ class MFModule { return array(); } - + + /** + * @return array + */ public function GetDictionaryFiles() { $aDictionaries = array(); @@ -202,39 +271,46 @@ class MFModule } return $aDictionaries; } - + + /** + * @return bool + */ public function IsAutoSelect() { return $this->bAutoSelect; } - + + /** + * @param $sAutoSelect + */ public function SetAutoSelect($sAutoSelect) { $this->sAutoSelect = $sAutoSelect; } + /** + * @return string + */ public function GetAutoSelect() { return $this->sAutoSelect; } - + + /** + * @param $aFiles + * @param $sCategory + */ public function SetFilesToInclude($aFiles, $sCategory) { // Now ModuleDiscovery provides us directly with relative paths... nothing to do $this->aFilesToInclude[$sCategory] = $aFiles; - - /* - $sDir = basename($this->sRootDir); - $iLen = strlen($sDir.'/'); - foreach($aFiles as $sFile) - { - $iPos = strpos($sFile, $sDir.'/'); - //$this->aFilesToInclude[$sCategory][] = substr($sFile, $iPos+$iLen); - $this->aFilesToInclude[$sCategory][] = $sFile; - } - */ } - + + /** + * @param $sCategory + * + * @return mixed + */ public function GetFilesToInclude($sCategory) { return $this->aFilesToInclude[$sCategory]; @@ -248,34 +324,47 @@ class MFModule */ class MFDeltaModule extends MFModule { + /** + * MFDeltaModule constructor. + * + * @param $sDeltaFile + */ public function __construct($sDeltaFile) { - $this->sId = 'datamodel-delta'; - + parent::__construct('datamodel-delta', '', 'Additional Delta'); $this->sName = 'delta'; $this->sVersion = '1.0'; - - $this->sRootDir = ''; - $this->sLabel = 'Additional Delta'; $this->aDataModels = array($sDeltaFile); $this->aFilesToInclude = array('addons' => array(), 'business' => array(), 'webservices' => array(),); } + /** + * @return mixed|string + */ public function GetName() { return ''; // Objects created inside this pseudo module retain their original module's name } + /** + * @return mixed|string + */ public function GetRootDir() { return ''; } + /** + * @return string + */ public function GetModuleDir() { return ''; } + /** + * @return array + */ public function GetDictionaryFiles() { return array(); @@ -288,29 +377,41 @@ class MFDeltaModule extends MFModule */ class MFCoreModule extends MFModule { + /** + * MFCoreModule constructor. + * + * @param $sName + * @param $sLabel + * @param $sDeltaFile + */ public function __construct($sName, $sLabel, $sDeltaFile) { - $this->sId = $sName; - + parent::__construct($sName, '', $sLabel); $this->sName = $sName; $this->sVersion = '1.0'; - - $this->sRootDir = ''; - $this->sLabel = $sLabel; $this->aDataModels = array($sDeltaFile); $this->aFilesToInclude = array('addons' => array(), 'business' => array(), 'webservices' => array(),); } - + + /** + * @return mixed|string + */ public function GetRootDir() { return ''; } + /** + * @return string + */ public function GetModuleDir() { return ''; } + /** + * @return array + */ public function GetDictionaryFiles() { return array(); @@ -323,29 +424,41 @@ class MFCoreModule extends MFModule */ class MFDictModule extends MFModule { + /** + * MFDictModule constructor. + * + * @param $sName + * @param $sLabel + * @param $sRootDir + */ public function __construct($sName, $sLabel, $sRootDir) { - $this->sId = $sName; - + parent::__construct($sName, $sRootDir, $sLabel); $this->sName = $sName; $this->sVersion = '1.0'; - - $this->sRootDir = $sRootDir; - $this->sLabel = $sLabel; $this->aDataModels = array(); $this->aFilesToInclude = array('addons' => array(), 'business' => array(), 'webservices' => array(),); } + /** + * @return mixed|string + */ public function GetRootDir() { return ''; } + /** + * @return string + */ public function GetModuleDir() { return ''; } - + + /** + * @return array + */ public function GetDictionaryFiles() { $aDictionaries = array(); @@ -378,16 +491,24 @@ class ModelFactory protected $oModules; protected $oClasses; protected $oMenus; + protected $oMeta; protected $oDictionaries; static protected $aLoadedClasses; static protected $aWellKnownParents = array('DBObject', 'CMDBObject','cmdbAbstractObject'); -// static protected $aWellKnownMenus = array('DataAdministration', 'Catalogs', 'ConfigManagement', 'Contact', 'ConfigManagementCI', 'ConfigManagement:Shortcuts', 'ServiceManagement'); static protected $aLoadedModules; static protected $aLoadErrors; protected $aDict; protected $aDictKeys; - - + + + /** + * ModelFactory constructor. + * + * @param $aRootDirs + * @param array $aRootNodeExtensions + * + * @throws \Exception + */ public function __construct($aRootDirs, $aRootNodeExtensions = array()) { $this->aDict = array(); @@ -425,7 +546,13 @@ class ModelFactory libxml_use_internal_errors(true); } - + + /** + * @param null $oNode + * @param bool $bReturnRes + * + * @return mixed + */ public function Dump($oNode = null, $bReturnRes = false) { if (is_null($oNode)) @@ -435,6 +562,9 @@ class ModelFactory return $oNode->Dump($bReturnRes); } + /** + * @param $sCacheFile + */ public function LoadFromFile($sCacheFile) { $this->oDOMDocument->load($sCacheFile); @@ -451,14 +581,22 @@ class ModelFactory } } + /** + * @param $sCacheFile + */ public function SaveToFile($sCacheFile) { $this->oDOMDocument->save($sCacheFile); } + /** * To progressively replace LoadModule - * @param MFElement $oSourceNode - * @param MFElement $oTargetParentNode + * + * @param $oSourceNode + * @param $oTargetParentNode + * + * @throws \MFException + * @throws \DOMFormatException */ public function LoadDelta($oSourceNode, $oTargetParentNode) { @@ -701,13 +839,14 @@ class ModelFactory $sError = implode(', ', $oFormat->GetErrors()); throw new Exception("Cannot load module $sModuleName, failed to upgrade to datamodel format of: $sXmlFile. Reason(s): $sError"); } - + $oDeltaRoot = $oDocument->childNodes->item(0); $this->LoadDelta($oDeltaRoot, $this->oDOMDocument); } $aDictionaries = $oModule->GetDictionaryFiles(); - + + $sPHPFile = 'undefined'; try { $this->ResetTempDictionary(); @@ -797,7 +936,7 @@ class ModelFactory * @param string $sLanguageCode The language code * @param string $sEnglishLanguageDesc English description of the language (unused but kept for API compatibility) * @param string $sLocalizedLanguageDesc Localized description of the language (unused but kept for API compatibility) - * @param hash $aEntries The entries to load: string_code => translation + * @param array $aEntries The entries to load: string_code => translation */ protected function AddToTempDictionary($sLanguageCode, $sEnglishLanguageDesc, $sLocalizedLanguageDesc, $aEntries) { @@ -813,7 +952,7 @@ class ModelFactory $this->aDict[$sLanguageCode]['entries'][$sKey] = $sValue; } } - + protected function ResetTempDictionary() { $this->aDict = array(); @@ -853,6 +992,11 @@ class ModelFactory return $sMessage; } + /** + * @param bool $bExcludeWorkspace + * + * @return array + */ function GetLoadedModules($bExcludeWorkspace = true) { if ($bExcludeWorkspace) @@ -872,8 +1016,13 @@ class ModelFactory } return $aModules; } - - + + + /** + * @param $sModuleName + * + * @return mixed|null + */ function GetModule($sModuleName) { foreach(self::$aLoadedModules as $oModule) @@ -882,36 +1031,30 @@ class ModelFactory } return null; } - + + /** + * @param $sTagName + * @param string $sValue + * + * @return mixed + */ public function CreateElement($sTagName, $sValue = '') { return $this->oDOMDocument->createElement($sTagName, $sValue); } - + + /** + * @param $sXPath + * @param $sId + * @param null $oContextNode + * + * @return \DOMNodeList + */ public function GetNodeById($sXPath, $sId, $oContextNode = null) { return $this->oDOMDocument->GetNodeById($sXPath, $sId, $oContextNode); } - /** - * Apply extensibility rules into the DOM - * @param array aRestrictionRules Array of array ('selectors' => array of XPaths, 'rules' => array of rules) - * @return void - */ - public function RestrictExtensibility($aRestrictionRules) - { - foreach ($aRestrictionRules as $aRestriction) - { - foreach ($aRestriction['selectors'] as $sSelector) - { - foreach($this->GetNodes($sSelector) as $oNode) - { - $oNode->RestrictExtensibility($aRestriction['rules']); - } - } - } - } - /** * Check if the class specified by the given node already exists in the loaded DOM * @param DOMNode $oClassNode The node corresponding to the class to load @@ -987,7 +1130,13 @@ class ModelFactory } } } - + + /** + * @param $sName + * @param $sIcon + * + * @return string + */ public function GetClassXMLTemplate($sName, $sIcon) { $sHeader = ''; @@ -1018,7 +1167,10 @@ EOF /** * List all constants from the DOM, for a given module + * * @param string $sModuleName + * + * @return \DOMNodeList * @throws Exception */ public function ListConstants($sModuleName) @@ -1028,7 +1180,10 @@ EOF /** * List all classes from the DOM, for a given module + * * @param string $sModuleName + * + * @return \DOMNodeList * @throws Exception */ public function ListClasses($sModuleName) @@ -1054,12 +1209,22 @@ EOF return $this->GetNodes("/itop_design/classes/class/class[class]"); } + /** + * @param $sClassName + * + * @return \DOMElement + */ public function GetClass($sClassName) { $oClassNode = $this->GetNodes("/itop_design/classes//class[@id='$sClassName']")->item(0); return $oClassNode; } - + + /** + * @param $sWellKnownParent + * + * @return mixed + */ public function AddWellKnownParent($sWellKnownParent) { $oWKClass = $this->oDOMDocument->CreateElement('class'); @@ -1067,13 +1232,25 @@ EOF $this->oClasses->AppendChild($oWKClass); return $oWKClass; } - + + /** + * @param $oClassNode + * + * @return \DOMNodeList + */ public function GetChildClasses($oClassNode) { return $this->GetNodes("class", $oClassNode); } - - + + + /** + * @param $sClassName + * @param $sAttCode + * + * @return \DOMElement|null + * @throws \Exception + */ public function GetField($sClassName, $sAttCode) { if (!$this->ClassNameExists($sClassName)) @@ -1088,41 +1265,56 @@ EOF } return $oFieldNode; } - + /** * List all classes from the DOM - * @throws Exception + * + * @param \DOMNode $oClassNode + * + * @return \DOMNodeList */ public function ListFields(DOMNode $oClassNode) { return $this->GetNodes("fields/field", $oClassNode); } - + /** * List all transitions from a given state + * * @param DOMNode $oStateNode The state + * + * @return \DOMNodeList * @throws Exception */ public function ListTransitions(DOMNode $oStateNode) { return $this->GetNodes("transitions/transition", $oStateNode); } - + /** * List all states of a given class + * * @param DOMNode $oClassNode The class + * + * @return \DOMNodeList * @throws Exception */ public function ListStates(DOMNode $oClassNode) { return $this->GetNodes("lifecycle/states/state", $oClassNode); } - + + /** + * @return mixed + */ public function ApplyChanges() { return $this->oRoot->ApplyChanges(); } - + + /** + * @return mixed + */ public function ListChanges() { return $this->oRoot->ListChanges(); @@ -1130,7 +1322,11 @@ EOF /** - * Import the node into the delta + * Import the node into the delta + * + * @param $oNodeClone + * + * @return mixed */ protected function SetDeltaFlags($oNodeClone) { @@ -1170,9 +1366,12 @@ EOF /** * Create path for the delta - * @param Array aMovedClasses The classes that have been moved in the hierarchy (deleted + created elsewhere) + * + * @param array aMovedClasses The classes that have been moved in the hierarchy (deleted + created elsewhere) * @param DOMDocument oTargetDoc Where to attach the top of the hierarchy - * @param MFElement oNode The node to import with its path + * @param MFElement oNode The node to import with its path + * + * @return \DOMElement|null */ protected function ImportNodeAndPathDelta($aMovedClasses, $oTargetDoc, $oNode) { @@ -1214,7 +1413,7 @@ EOF { if ($sAlteration == 'removed') { - // Remove that node: this specification will be overriden by the 'replaced' spec (see below) + // Remove that node: this specification will be overridden by the 'replaced' spec (see below) $oClassNode->parentNode->removeChild($oClassNode); } else @@ -1260,8 +1459,12 @@ EOF /** * Set the value for a given trace attribute - * See MFElement::SetTrace to enable/disable change traces - */ + * See MFElement::SetTrace to enable/disable change traces + * + * @param $sAttribute + * @param $sPreviousValue + * @param $sNewValue + */ public function SetTraceValue($sAttribute, $sPreviousValue, $sNewValue) { // Search into the deleted node as well! @@ -1274,7 +1477,13 @@ EOF /** * Get the document version of the delta - */ + * + * @param array $aNodesToIgnore + * @param null $aAttributes + * + * @return \MFDocument + * @throws \Exception + */ public function GetDeltaDocument($aNodesToIgnore = array(), $aAttributes = null) { $oDelta = new MFDocument(); @@ -1333,17 +1542,25 @@ EOF /** * Get the text/XML version of the delta - */ + * + * @param array $aNodesToIgnore + * @param null $aAttributes + * + * @return string + * @throws \Exception + */ public function GetDelta($aNodesToIgnore = array(), $aAttributes = null) { $oDelta = $this->GetDeltaDocument($aNodesToIgnore, $aAttributes); return $oDelta->saveXML(); } - + /** * Searches on disk in the root directories for module description files * and returns an array of MFModules + * * @return array Array of MFModules + * @throws \Exception */ public function FindModules() { @@ -1372,9 +1589,13 @@ EOF } return $aResult; } - + public function TestAlteration() { + $sDOMOriginal = 'undefined'; + $sDOMModified = 'undefined'; + $sDOMRebuilt = 'undefined'; + $sDeltaXML = 'undefined'; try { $sHeader = ''; @@ -1428,7 +1649,7 @@ EOF; $oNewC->Rename('blah'); $oNewC->Rename('foo'); $oNewC->AddChildNode($this->oDOMDocument->CreateElement('y', '(no flag)')); - $oNewC->AddChildNode($this->oDOMDocument->CreateElement('x', 'To delete programatically')); + $oNewC->AddChildNode($this->oDOMDocument->CreateElement('x', 'To delete programmatically')); $oSubNode = $oNewC->GetUniqueElement('z'); $oSubNode->Rename('abcdef'); $oSubNode = $oNewC->GetUniqueElement('x'); @@ -1447,7 +1668,7 @@ EOF; $oSubnode->setAttribute('id', 'to be changed'); $oNewA->AddChildNode($oSubnode); $oNewA->AddChildNode($this->oDOMDocument->CreateElement('f', 'Welcome to the newcomer')); - $oNewA->AddChildNode($this->oDOMDocument->CreateElement('x', 'To delete programatically')); + $oNewA->AddChildNode($this->oDOMDocument->CreateElement('x', 'To delete programmatically')); // Alter this "new a", as it is new, no flag should be set $oNewA->Rename('new_a'); @@ -1469,7 +1690,7 @@ EOF; //echo "
\n";
 			//echo htmlentities($sDeltaXML);
 			//echo "
\n"; - + // Reiterating - try to remake the DOM by applying the computed delta // $this->oDOMDocument = new MFDocument(); @@ -1527,7 +1748,11 @@ EOF; /** * Extracts some nodes from the DOM + * * @param string $sXPath A XPath expression + * @param null $oContextNode + * @param bool $bSafe + * * @return DOMNodeList */ public function GetNodes($sXPath, $oContextNode = null, $bSafe = true) @@ -1536,15 +1761,6 @@ EOF; } } - -/** - * Allow the setup page to load and perform its checks (including the check about the required extensions) - */ -if (!class_exists('DOMElement')) -{ -class DOMElement {function __construct(){throw new Exception('The dom extension is not enabled');}} -} - /** * MFElement: helper to read/change the DOM * @package ModelFactory @@ -1553,17 +1769,23 @@ class MFElement extends Combodo\iTop\DesignElement { /** * Extracts some nodes from the DOM + * * @param string $sXPath A XPath expression + * @param bool $bSafe + * * @return DOMNodeList */ public function GetNodes($sXPath, $bSafe = true) { return $this->ownerDocument->GetNodes($sXPath, $this, $bSafe); } - + /** * Extracts some nodes from the DOM (active nodes only !!!) + * * @param string $sXPath A XPath expression + * @param $sId + * * @return DOMNodeList */ public function GetNodeById($sXPath, $sId) @@ -1572,8 +1794,14 @@ class MFElement extends Combodo\iTop\DesignElement } /** - * Returns the node directly under the given node - */ + * Returns the node directly under the given node + * + * @param $sTagName + * @param bool $bMustExist + * + * @return MFElement + * @throws \DOMFormatException + */ public function GetUniqueElement($sTagName, $bMustExist = true) { $oNode = null; @@ -1591,16 +1819,21 @@ class MFElement extends Combodo\iTop\DesignElement } return $oNode; } - + /** * Assumes the current node to be either a text or * * value * value * - * where value can be the either a text or an array of items... recursively - * Returns a PHP array - */ + * where value can be the either a text or an array of items... recursively + * Returns a PHP array + * + * @param string $sElementName + * + * @return array|null|string + * @throws \DOMFormatException + */ public function GetNodeAsArrayOfItems($sElementName = 'items') { $oItems = $this->GetOptionalElement($sElementName); @@ -1647,17 +1880,11 @@ class MFElement extends Combodo\iTop\DesignElement return $res; } - public function SetNodeAsArrayOfItems($aList) - { - $oNewNode = $this->ownerDocument->CreateElement($this->tagName); - if ($this->getAttribute('id') != '') - { - $oNewNode->setAttribute('id', $this->getAttribute('id')); - } - self::AddItemToNode($this->ownerDocument, $oNewNode, $aList); - $this->parentNode->RedefineChildNode($oNewNode); - } - + /** + * @param $oXmlDoc + * @param $oXMLNode + * @param $itemValue + */ protected static function AddItemToNode($oXmlDoc, $oXMLNode, $itemValue) { if (is_array($itemValue)) @@ -1697,26 +1924,33 @@ class MFElement extends Combodo\iTop\DesignElement } $this->removeChild($this->firstChild); } - } + } /** * Find the child node matching the given node. * UNSAFE: may return nodes marked as _alteration="removed" * A method with the same signature MUST exist in MFDocument for the recursion to work fine + * * @param MFElement $oRefNode The node to search for - * @param string $sSearchId substitutes to the value of the 'id' attribute - */ + * @param string $sSearchId substitutes to the value of the 'id' attribute + * + * @return \DOMElement|null + * @throws \Exception + */ public function _FindChildNode(MFElement $oRefNode, $sSearchId = null) { return self::_FindNode($this, $oRefNode, $sSearchId); } - + /** * Find the child node matching the given node under the specified parent. * UNSAFE: may return nodes marked as _alteration="removed" + * * @param DOMNode $oParent * @param MFElement $oRefNode * @param string $sSearchId + * + * @return \DOMElement|null * @throws Exception */ public static function _FindNode(DOMNode $oParent, MFElement $oRefNode, $sSearchId = null) @@ -1789,12 +2023,12 @@ class MFElement extends Combodo\iTop\DesignElement } return false; } - + static $aTraceAttributes = null; /** * Enable/disable the trace on changed nodes * - *@param aAttributes array Array of attributes (key => value) to be added onto any changed node + *@param array aAttributes Array of attributes (key => value) to be added onto any changed node */ static public function SetTrace($aAttributes = null) { @@ -1817,8 +2051,11 @@ class MFElement extends Combodo\iTop\DesignElement /** * Add a node and set the flags that will be used to compute the delta + * * @param MFElement $oNode The node (including all subnodes) to add - */ + * + * @throws \MFException + */ public function AddChildNode(MFElement $oNode) { // First: cleanup any flag behind the new node, and eventually add trace data @@ -1850,8 +2087,12 @@ class MFElement extends Combodo\iTop\DesignElement /** * Modify a node and set the flags that will be used to compute the delta + * * @param MFElement $oNode The node (including all subnodes) to set - */ + * @param null $sSearchId + * + * @throws \MFException + */ public function RedefineChildNode(MFElement $oNode, $sSearchId = null) { // First: cleanup any flag behind the new node, and eventually add trace data @@ -1870,7 +2111,6 @@ class MFElement extends Combodo\iTop\DesignElement { $sPath = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(empty($sSearchId) ? '' : "[$sSearchId]"); $iLine = $oNode->getLineNo(); - $sSourceNode = MFDocument::GetItopNodePath($this)."/".$oNode->tagName.(is_null($sSearchId) ? '' : "[$sSearchId]").' at line '.$this->getLineNo(); throw new MFException($sPath." at line $iLine: could not be modified (marked as deleted)", MFException::COULD_NOT_BE_MODIFIED_ALREADY_DELETED, $sPath, $iLine); } $oExisting->ReplaceWith($oNode); @@ -1890,7 +2130,9 @@ class MFElement extends Combodo\iTop\DesignElement * @param MFElement $oNode The node (including all subnodes) to set * @param string $sSearchId Optional Id of the node to SearchMenuNode * @param bool $bForce Force mode to dynamically add or replace nodes - */ + * + * @throws \Exception + */ public function SetChildNode(MFElement $oNode, $sSearchId = null, $bForce = false) { // First: cleanup any flag behind the new node, and eventually add trace data @@ -1966,10 +2208,11 @@ class MFElement extends Combodo\iTop\DesignElement /** * Remove a node and set the flags that will be used to compute the delta - */ + * + * @throws \Exception + */ public function Delete() { - $oParent = $this->parentNode; switch ($this->getAttribute('_alteration')) { case 'replaced': @@ -2012,7 +2255,9 @@ class MFElement extends Combodo\iTop\DesignElement * @param string $sSearchId The id to consider (could be blank) * @param bool $bMustExist Throw an exception if the node must already be found (and not marked as deleted!) * @param bool $bIfExists Return null if the node does not exists (or is marked as deleted) + * * @return DOMNode|null + * @throws \Exception */ public function MergeInto($oContainer, $sSearchId, $bMustExist, $bIfExists = false) { @@ -2052,8 +2297,8 @@ class MFElement extends Combodo\iTop\DesignElement /** * Renames a node and set the flags that will be used to compute the delta - * @param String $sNewId The new id - */ + * @param string $sId The new id + */ public function Rename($sId) { if (($this->getAttribute('_alteration') == 'replaced') || !$this->IsInDefinition()) @@ -2074,42 +2319,6 @@ class MFElement extends Combodo\iTop\DesignElement $this->AddTrace(); } - /** - * Apply extensibility rules onto this node - * @param array aRules Array of rules (strings) - * @return void - */ - public function RestrictExtensibility($aRules) - { - $oRulesNode = $this->GetOptionalElement('rules'); - if ($oRulesNode) - { - $aCurrentRules = $oRulesNode->GetNodeAsArrayOfItems(); - $aCurrentRules = array_merge($aCurrentRules, $aRules); - $oRulesNode->SetNodeAsArrayOfItems($aCurrentRules); - } - else - { - $oNewNode = $this->ownerDocument->CreateElement('rules'); - $this->appendChild($oNewNode); - $oNewNode->SetNodeAsArrayOfItems($aRules); - } - } - - /** - * Read extensibility rules for this node - * @return Array of rules (strings) - */ - public function GetExtensibilityRules() - { - $aCurrentRules = array(); - $oRulesNode = $this->GetOptionalElement('rules'); - if ($oRulesNode) - { - $aCurrentRules = $oRulesNode->GetNodeAsArrayOfItems(); - } - return $aCurrentRules; - } /** * List changes below a given node (see also MFDocument::ListChanges) @@ -2152,21 +2361,13 @@ class MFElement extends Combodo\iTop\DesignElement } /** - * Allow the setup page to load and perform its checks (including the check about the required extensions) - */ -if (!class_exists('DOMDocument')) -{ - class DOMDocument {function __construct(){throw new Exception('The dom extension is not enabled');}} -} - -/** - * MFDocument - formating rules for XML input/output + * MFDocument - formatting rules for XML input/output * @package ModelFactory */ class MFDocument extends \Combodo\iTop\DesignDocument { /** - * Overloadable. Called prior to data loading. + * Over loadable. Called prior to data loading. */ protected function Init() { @@ -2176,6 +2377,11 @@ class MFDocument extends \Combodo\iTop\DesignDocument /** * Overload the standard API + * + * @param \DOMNode|null $node + * @param int $options + * + * @return string */ public function saveXML(DOMNode $node = null, $options = 0) { @@ -2189,12 +2395,19 @@ class MFDocument extends \Combodo\iTop\DesignDocument } return parent::saveXML($node); } - + /** * Overload createElement to make sure (via new DOMText) that the XML entities are * always properly escaped * (non-PHPdoc) + * * @see DOMDocument::createElement() + * + * @param $sName + * @param null $value + * @param null $namespaceURI + * + * @return \DOMNode */ function createElement($sName, $value = null, $namespaceURI = null) { @@ -2209,9 +2422,13 @@ class MFDocument extends \Combodo\iTop\DesignDocument /** * Find the child node matching the given node * A method with the same signature MUST exist in MFElement for the recursion to work fine + * * @param MFElement $oRefNode The node to search for - * @param string $sSearchId substitutes to the value of the 'id' attribute - */ + * @param string $sSearchId substitutes to the value of the 'id' attribute + * + * @return \DOMElement|null + * @throws \Exception + */ public function _FindChildNode(MFElement $oRefNode, $sSearchId = null) { return MFElement::_FindNode($this, $oRefNode, $sSearchId); @@ -2219,7 +2436,11 @@ class MFDocument extends \Combodo\iTop\DesignDocument /** * Extracts some nodes from the DOM + * * @param string $sXPath A XPath expression + * @param null $oContextNode + * @param bool $bSafe + * * @return DOMNodeList */ public function GetNodes($sXPath, $oContextNode = null, $bSafe = true) @@ -2240,7 +2461,14 @@ class MFDocument extends \Combodo\iTop\DesignDocument } return $oResult; } - + + /** + * @param $sXPath + * @param $sId + * @param null $oContextNode + * + * @return \DOMNodeList + */ public function GetNodeById($sXPath, $sId, $oContextNode = null) { $oXPath = new DOMXPath($this); @@ -2267,12 +2495,25 @@ class MFParameters { protected $aData = null; + /** + * MFParameters constructor. + * + * @param \DOMNode $oNode + * + * @throws \Exception + */ public function __construct(DOMNode $oNode) { $this->aData = array(); $this->LoadFromDOM($oNode); } + /** + * @param $sCode + * @param string $default + * + * @return mixed|string + */ public function Get($sCode, $default = '') { if (array_key_exists($sCode, $this->aData)) @@ -2282,11 +2523,19 @@ class MFParameters return $default; } + /** + * @return array|null + */ public function GetAll() { return $this->aData; } + /** + * @param \DOMNode $oNode + * + * @throws \Exception + */ public function LoadFromDOM(DOMNode $oNode) { $this->aData = array(); @@ -2299,8 +2548,15 @@ class MFParameters } } + /** + * @param \DOMNode $oNode + * + * @return array|bool|int + * @throws \Exception + */ protected function ReadElement(DOMNode $oNode) { + $value = null; if ($oNode instanceof DOMElement) { $sDefaultNodeType = ($this->HasChildNodes($oNode)) ? 'hash' : 'string'; @@ -2379,9 +2635,17 @@ class MFParameters { $value = $oNode->wholeText; } + return $value; } + /** + * @param $sAttName + * @param $oNode + * @param $sDefaultValue + * + * @return mixed + */ protected function GetAttribute($sAttName, $oNode, $sDefaultValue) { $sRet = $sDefaultValue; @@ -2398,7 +2662,12 @@ class MFParameters } /** - * Returns the TEXT of the current node (possibly from several subnodes) + * Returns the TEXT of the current node (possibly from several sub nodes) + * + * @param $oNode + * @param null $sDefault + * + * @return null|string */ public function GetText($oNode, $sDefault = null) { @@ -2420,8 +2689,13 @@ class MFParameters return $sText; } } + /** * Check if a node has child nodes (apart from text nodes) + * + * @param $oNode + * + * @return bool */ public function HasChildNodes($oNode) { @@ -2437,6 +2711,10 @@ class MFParameters } return false; } + + /** + * @param \XMLParameters $oTask + */ function Merge(XMLParameters $oTask) { //todo: clarify the usage of this function that CANNOT work @@ -2452,7 +2730,7 @@ class MFParameters * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value')); * => array('key' => array('org value', 'new value')); * - * array_merge_recursive_distinct does not change the datatypes of the values in the arrays. + * array_merge_recursive_distinct does not change the data types of the values in the arrays. * Matching keys' values in the second array overwrite those in the first array, as is the * case with array_merge, i.e.: * diff --git a/setup/modulediscovery.class.inc.php b/setup/modulediscovery.class.inc.php index ae8f52b66..4a92f7ad5 100644 --- a/setup/modulediscovery.class.inc.php +++ b/setup/modulediscovery.class.inc.php @@ -1,26 +1,22 @@ - /** - * ModuleDiscovery: list available modules + * Copyright (c) 2010-2018 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with iTop. If not, see * - * @copyright Copyright (C) 2010-2012 Combodo SARL - * @license http://opensource.org/licenses/AGPL-3.0 */ class MissingDependencyException extends Exception @@ -154,23 +150,28 @@ class ModuleDiscovery } /** - * Get the list of "discovered" modules, ordered based on their (inter) dependencies - * @param bool $bAbortOnMissingDependency ... - * @param hash $aModulesToLoad List of modules to search for, defaults to all if ommitted - */ + * Get the list of "discovered" modules, ordered based on their (inter) dependencies + * + * @param bool $bAbortOnMissingDependency ... + * @param array $aModulesToLoad List of modules to search for, defaults to all if omitted + * + * @return array + * @throws \MissingDependencyException + */ protected static function GetModules($bAbortOnMissingDependency = false, $aModulesToLoad = null) { // Order the modules to take into account their inter-dependencies return self::OrderModulesByDependencies(self::$m_aModules, $bAbortOnMissingDependency, $aModulesToLoad); } - + /** * Arrange an list of modules, based on their (inter) dependencies - * @param hash $aModules The list of modules to process: 'id' => $aModuleInfo - * @param bool $bAbortOnMissingDependency ... - * @param hash $aModulesToLoad List of modules to search for, defaults to all if ommitted - * @return hash - */ + * @param array $aModules The list of modules to process: 'id' => $aModuleInfo + * @param bool $bAbortOnMissingDependency ... + * @param array $aModulesToLoad List of modules to search for, defaults to all if omitted + * @return array + * @throws \MissingDependencyException +*/ public static function OrderModulesByDependencies($aModules, $bAbortOnMissingDependency = false, $aModulesToLoad = null) { // Order the modules to take into account their inter-dependencies @@ -178,7 +179,7 @@ class ModuleDiscovery $aSelectedModules = array(); foreach($aModules as $sId => $aModule) { - list($sModuleName, $sModuleVersion) = self::GetModuleName($sId); + list($sModuleName, ) = self::GetModuleName($sId); if (is_null($aModulesToLoad) || in_array($sModuleName, $aModulesToLoad)) { $aDependencies[$sId] = $aModule['dependencies']; @@ -234,8 +235,8 @@ class ModuleDiscovery /** * Remove the duplicate modules (i.e. modules with the same name but with a different version) from the supplied list of modules - * @param hash $aModules - * @return hash The ordered modules as a duplicate-free list of modules + * @param array $aModules + * @return array The ordered modules as a duplicate-free list of modules */ public static function RemoveDuplicateModules($aModules) { @@ -340,10 +341,13 @@ class ModuleDiscovery /** * Search (on the disk) for all defined iTop modules, load them and returns the list (as an array) * of the possible iTop modules to install - * @param aSearchDirs Array of directories to search (absolute paths) - * @param bool $bAbortOnMissingDependency ... - * @param hash $aModulesToLoad List of modules to search for, defaults to all if ommitted - * @return Hash A big array moduleID => ModuleData + * + * @param $aSearchDirs array of directories to search (absolute paths) + * @param bool $bAbortOnMissingDependency ... + * @param array $aModulesToLoad List of modules to search for, defaults to all if omitted + * + * @return array A big array moduleID => ModuleData + * @throws \Exception */ public static function GetAvailableModules($aSearchDirs, $bAbortOnMissingDependency = false, $aModulesToLoad = null) { @@ -404,13 +408,15 @@ class ModuleDiscovery } return array($sName, $sVersion); } - + /** * Helper function to browse a directory and get the modules + * * @param $sRelDir string Directory to start from * @param $sRootDir string The root directory path - * @return array(name, version) - */ + * + * @throws \Exception + */ protected static function ListModuleFiles($sRelDir, $sRootDir) { static $iDummyClassIndex = 0;