Reintegrated a number of fixes from trunk:

#672 and #673 Physical interfaces
#683 DB name can have numbers + hyphen
#664 Could not logon after an upgrade of 1.x
#686 Issue with default values on upgrade
#657 Quotes not allowed in synchro name/desc
#659 Error report not displayed during the setup
#660 Issue with ZendServer
#661 and #662 Issues with autocompletes
#666 Import: reconciliation of Software CIs
#668 Management IP not visible anywhere
#675 Drill-down on graph failing
#679 Setup: dependency between modules
#680 Setup: missing php-xml (module "dom")


SVN:2.0[2643]
This commit is contained in:
Romain Quetiez
2013-03-20 09:15:11 +00:00
parent d2f9458516
commit be4a2e52bc
14 changed files with 177 additions and 64 deletions

View File

@@ -546,6 +546,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
{
$sTip .= "<p>Synchronized with {$aRow['name']} - {$aRow['description']}</p>";
}
$sTip = addslashes($sTip);
$oPage->add_ready_script("$('#synchro_$sInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
}
@@ -2832,6 +2833,7 @@ EOF
{
$sTip .= "<p>Synchronized with {$aRow['name']} - {$aRow['description']}</p>";
}
$sTip = addslashes($sTip);
$oPage->add_ready_script("$('#synchro_$sInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );");
}

View File

@@ -395,7 +395,7 @@ class DisplayBlock
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy);
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy, true);
$aRes = CMDBSource::QueryToArray($sSql);
$aGroupBy = array();
@@ -893,7 +893,7 @@ EOF
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy);
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy, true);
$aRes = CMDBSource::QueryToArray($sSql);
$aGroupBy = array();
@@ -968,7 +968,7 @@ EOF
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy);
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy, true);
$aRes = CMDBSource::QueryToArray($sSql);
$aGroupBy = array();
@@ -1049,7 +1049,8 @@ EOF
$aGroupBy = array();
$aGroupBy['grouped_by_1'] = $oGroupByExp;
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy);
$sSql = MetaModel::MakeGroupByQuery($this->m_oFilter, $aQueryParams, $aGroupBy, true);
$aRes = CMDBSource::QueryToArray($sSql);
$aGroupBy = array();

View File

@@ -2076,10 +2076,27 @@ abstract class MetaModel
return $aScalarArgs;
}
public static function MakeGroupByQuery(DBObjectSearch $oFilter, $aArgs, $aGroupByExpr)
public static function MakeGroupByQuery(DBObjectSearch $oFilter, $aArgs, $aGroupByExpr, $bExcludeNullValues = false)
{
$aAttToLoad = array();
$oSelect = self::MakeSelectStructure($oFilter, array(), $aArgs, $aAttToLoad, null, 0, 0, false, $aGroupByExpr);
if ($bExcludeNullValues)
{
// Null values are not handled (though external keys set to 0 are allowed)
$oQueryFilter = $oFilter->DeepClone();
foreach ($aGroupByExpr as $oGroupByExp)
{
$oNull = new FunctionExpression('ISNULL', array($oGroupByExp));
$oNotNull = new BinaryExpression($oNull, '!=', new TrueExpression());
$oQueryFilter->AddConditionExpression($oNotNull);
}
}
else
{
$oQueryFilter = $oFilter;
}
$oSelect = self::MakeSelectStructure($oQueryFilter, array(), $aArgs, $aAttToLoad, null, 0, 0, false, $aGroupByExpr);
$aScalarArgs = array_merge(self::PrepareQueryArguments($aArgs), $oFilter->GetInternalParams());
try
@@ -5148,7 +5165,7 @@ abstract class MetaModel
}
$aEntries = array();
$aCacheUserData = @apc_cache_info('user');
if (is_array($aCacheUserData))
if (is_array($aCacheUserData) && isset($aCacheUserData['cache_list']))
{
$sPrefix = 'itop-'.$sEnvironment.'-';

View File

@@ -2327,6 +2327,9 @@
<item id="iosversion_id">
<rank>40</rank>
</item>
<item id="managementip">
<rank>45</rank>
</item>
<item id="ram">
<rank>50</rank>
</item>
@@ -2395,6 +2398,9 @@
<item id="location_id">
<rank>50</rank>
</item>
<item id="managementip">
<rank>55</rank>
</item>
<item id="brand_id">
<rank>60</rank>
</item>
@@ -2647,6 +2653,9 @@
<item id="osversion_id">
<rank>40</rank>
</item>
<item id="managementip">
<rank>45</rank>
</item>
<item id="oslicence_id">
<rank>50</rank>
</item>
@@ -2721,6 +2730,9 @@
<item id="location_id">
<rank>50</rank>
</item>
<item id="managementip">
<rank>55</rank>
</item>
<item id="brand_id">
<rank>60</rank>
</item>
@@ -4409,6 +4421,8 @@
<reconciliation>
<attributes>
<attribute id="name"/>
<attribute id="version"/>
<attribute id="vendor"/>
</attributes>
</reconciliation>
</properties>

View File

@@ -127,6 +127,9 @@
<item id="model_id">
<rank>20</rank>
</item>
<item id="managementip">
<rank>25</rank>
</item>
<item id="nb_u">
<rank>30</rank>
</item>
@@ -198,6 +201,9 @@
<item id="model_id">
<rank>70</rank>
</item>
<item id="managementip">
<rank>75</rank>
</item>
<item id="serialnumber">
<rank>80</rank>
</item>
@@ -373,6 +379,9 @@
<item id="model_id">
<rank>20</rank>
</item>
<item id="managementip">
<rank>35</rank>
</item>
<item id="nb_u">
<rank>30</rank>
</item>
@@ -444,6 +453,9 @@
<item id="model_id">
<rank>70</rank>
</item>
<item id="managementip">
<rank>75</rank>
</item>
<item id="serialnumber">
<rank>80</rank>
</item>
@@ -618,6 +630,9 @@
<item id="model_id">
<rank>20</rank>
</item>
<item id="managementip">
<rank>25</rank>
</item>
<item id="nb_u">
<rank>30</rank>
</item>
@@ -689,6 +704,9 @@
<item id="model_id">
<rank>70</rank>
</item>
<item id="managementip">
<rank>75</rank>
</item>
<item id="serialnumber">
<rank>80</rank>
</item>
@@ -863,6 +881,9 @@
<item id="model_id">
<rank>20</rank>
</item>
<item id="managementip">
<rank>25</rank>
</item>
<item id="nb_u">
<rank>30</rank>
</item>
@@ -934,6 +955,9 @@
<item id="model_id">
<rank>70</rank>
</item>
<item id="managementip">
<rank>75</rank>
</item>
<item id="serialnumber">
<rank>80</rank>
</item>

View File

@@ -877,6 +877,9 @@
<presentation>
<details>
<items>
<item id="name">
<rank>5</rank>
</item>
<item id="ipaddress">
<rank>10</rank>
</item>
@@ -902,6 +905,9 @@
</details>
<search>
<items>
<item id="name">
<rank>5</rank>
</item>
<item id="ipaddress">
<rank>10</rank>
</item>

View File

@@ -361,6 +361,7 @@ $.Autocompleter = function(input, options) {
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
type: "POST",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,

View File

@@ -134,6 +134,9 @@ function WizardHelper(sClass, sFormPrefix, sState)
//console.log(sFieldCode);
this.UpdateCurrentValue(sCleanFieldCode);
}
// Remove unnecessary stuff
this.m_oData.m_oDefaultValue = {};
this.m_oData.m_oAllowedValues = {};
}
this.UpdateWizardToJSON = function ()

View File

@@ -79,6 +79,7 @@ function FatalErrorCatcher($sOutput)
if ( preg_match('|<phpfatalerror>.*</phpfatalerror>|s', $sOutput, $aMatches) )
{
header("HTTP/1.0 500 Internal server error.");
$errors = '';
foreach ($aMatches as $sMatch)
{
$errors .= strip_tags($sMatch)."\n";

View File

@@ -375,11 +375,17 @@ class ApplicationInstaller
SetupPage::log_error('An exception occurred: '.$e->getMessage().' at line '.$e->getLine().' in file '.$e->getFile());
$idx = 0;
// Log the call stack, but log the parameters since they may contain passwords or other sensitive data
// Log the call stack, but not the parameters since they may contain passwords or other sensitive data
SetupPage::log("Call stack:");
foreach($e->getTrace() as $aTrace)
{
SetupPage::log("#$idx {$aTrace['file']}({$aTrace['line']}): {$aTrace['function']}(...)");
$sLine = empty($aTrace['line']) ? "" : $aTrace['line'];
$sFile = empty($aTrace['file']) ? "" : $aTrace['file'];
$sClass = empty($aTrace['class']) ? "" : $aTrace['class'];
$sType = empty($aTrace['type']) ? "" : $aTrace['type'];
$sFunction = empty($aTrace['function']) ? "" : $aTrace['function'];
$sVerb = empty($sClass) ? $sFunction : "$sClass{$sType}$sFunction";
SetupPage::log("#$idx $sFile($sLine): $sVerb(...)");
$idx++;
}
}
@@ -548,18 +554,18 @@ class ApplicationInstaller
// Starting 2.0, all table names must be lowercase
if ($sMode != 'install')
{
SetupPage::log_info("Renaming 'priv_internalUser' into 'priv_internaluser' (lowercase)");
SetupPage::log_info("Renaming '{$sDBPrefix}priv_internalUser' into '{$sDBPrefix}priv_internaluser' (lowercase)");
// This command will have no effect under Windows...
// and it has been written in two steps so as to make it work under windows!
CMDBSource::SelectDB($sDBName);
try
{
$sRepair = "RENAME TABLE `priv_internalUser` TO `priv_internaluser_other`, `priv_internaluser_other` TO `priv_internaluser`";
$sRepair = "RENAME TABLE `{$sDBPrefix}priv_internalUser` TO `{$sDBPrefix}priv_internaluser_other`, `{$sDBPrefix}priv_internaluser_other` TO `{$sDBPrefix}priv_internaluser`";
CMDBSource::Query($sRepair);
}
catch (Exception $e)
{
SetupPage::log_info("Renaming 'priv_internalUser' failed (already done in a previous upgrade?)");
SetupPage::log_info("Renaming '{$sDBPrefix}priv_internalUser' failed (already done in a previous upgrade?)");
}
}

View File

@@ -213,7 +213,7 @@ class ModelFactory
{
echo "Dumping target doc - looking for '$sParentId'<br/>\n";
$this->oDOMDocument->firstChild->Dump();
throw new Exception("XML datamodel loader: could not find parent node for $oSourceNode->tagName / ".$oSourceNode->getAttribute('id')." with parent id $sParentId");
throw new Exception("could not find parent node for $oSourceNode->tagName(id:".$oSourceNode->getAttribute('id').") with parent id $sParentId");
}
}
else
@@ -223,7 +223,7 @@ class ModelFactory
{
echo "Dumping target doc - looking for '".$oSourceNode->getAttribute('id')."'<br/>\n";
$this->oDOMDocument->firstChild->Dump();
throw new Exception("XML datamodel loader: could not find node for $oSourceNode->tagName/".$oSourceNode->getAttribute('id'));
throw new Exception("could not find node for $oSourceNode->tagName(id:".$oSourceNode->getAttribute('id').")");
}
else
{
@@ -297,59 +297,71 @@ class ModelFactory
*/
public function LoadModule(MFModule $oModule)
{
$aDataModels = $oModule->GetDataModelFiles();
$sModuleName = $oModule->GetName();
$aClasses = array();
self::$aLoadedModules[] = $oModule;
// For persistence in the cache
$oModuleNode = $this->oDOMDocument->CreateElement('module');
$oModuleNode->setAttribute('id', $oModule->GetId());
$oModuleNode->AppendChild($this->oDOMDocument->CreateElement('root_dir', $oModule->GetRootDir()));
$oModuleNode->AppendChild($this->oDOMDocument->CreateElement('label', $oModule->GetLabel()));
$this->oModules->AppendChild($oModuleNode);
foreach($aDataModels as $sXmlFile)
try
{
$oDocument = new MFDocument();
libxml_clear_errors();
$oDocument->load($sXmlFile);
//$bValidated = $oDocument->schemaValidate(APPROOT.'setup/itop_design.xsd');
$aErrors = libxml_get_errors();
if (count($aErrors) > 0)
$aDataModels = $oModule->GetDataModelFiles();
$sModuleName = $oModule->GetName();
$aClasses = array();
self::$aLoadedModules[] = $oModule;
// For persistence in the cache
$oModuleNode = $this->oDOMDocument->CreateElement('module');
$oModuleNode->setAttribute('id', $oModule->GetId());
$oModuleNode->AppendChild($this->oDOMDocument->CreateElement('root_dir', $oModule->GetRootDir()));
$oModuleNode->AppendChild($this->oDOMDocument->CreateElement('label', $oModule->GetLabel()));
$this->oModules->AppendChild($oModuleNode);
foreach($aDataModels as $sXmlFile)
{
self::$aLoadErrors[$sModuleName] = $aErrors;
return;
}
$oXPath = new DOMXPath($oDocument);
$oNodeList = $oXPath->query('/itop_design/classes//class');
foreach($oNodeList as $oNode)
{
if ($oNode->getAttribute('_created_in') == '')
$oDocument = new MFDocument();
libxml_clear_errors();
$oDocument->load($sXmlFile);
//$bValidated = $oDocument->schemaValidate(APPROOT.'setup/itop_design.xsd');
$aErrors = libxml_get_errors();
if (count($aErrors) > 0)
{
$oNode->SetAttribute('_created_in', $sModuleName);
self::$aLoadErrors[$sModuleName] = $aErrors;
return;
}
}
$oNodeList = $oXPath->query('/itop_design/menus/menu');
foreach($oNodeList as $oNode)
{
if ($oNode->getAttribute('_created_in') == '')
$oXPath = new DOMXPath($oDocument);
$oNodeList = $oXPath->query('/itop_design/classes//class');
foreach($oNodeList as $oNode)
{
$oNode->SetAttribute('_created_in', $sModuleName);
if ($oNode->getAttribute('_created_in') == '')
{
$oNode->SetAttribute('_created_in', $sModuleName);
}
}
}
$oUserRightsNode = $oXPath->query('/itop_design/user_rights')->item(0);
if ($oUserRightsNode)
{
if ($oUserRightsNode->getAttribute('_created_in') == '')
$oNodeList = $oXPath->query('/itop_design/menus/menu');
foreach($oNodeList as $oNode)
{
$oUserRightsNode->SetAttribute('_created_in', $sModuleName);
if ($oNode->getAttribute('_created_in') == '')
{
$oNode->SetAttribute('_created_in', $sModuleName);
}
}
$oUserRightsNode = $oXPath->query('/itop_design/user_rights')->item(0);
if ($oUserRightsNode)
{
if ($oUserRightsNode->getAttribute('_created_in') == '')
{
$oUserRightsNode->SetAttribute('_created_in', $sModuleName);
}
}
$oDeltaRoot = $oDocument->childNodes->item(0);
$this->LoadDelta($oDocument, $oDeltaRoot, $this->oDOMDocument);
}
$oDeltaRoot = $oDocument->childNodes->item(0);
$this->LoadDelta($oDocument, $oDeltaRoot, $this->oDOMDocument);
}
catch(Exception $e)
{
$aLoadedModuleNames = array();
foreach (self::$aLoadedModules as $oModule)
{
$aLoadedModuleNames[] = $oModule->GetName();
}
throw new Exception('Error loading module "'.$oModule->GetName().'": '.$e->getMessage().' - Loaded modules: '.implode(',', $aLoadedModuleNames));
}
}
@@ -1282,6 +1294,14 @@ 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
@@ -1684,7 +1704,7 @@ class MFElement extends DOMElement
{
if ($bMustExist)
{
throw new Exception("XML datamodel loader: found mandatory node $this->tagName/$sSearchId marked as deleted in $oContainer->tagName");
throw new Exception("found mandatory node $this->tagName(id:$sSearchId) marked as deleted in ".$oContainer->getNodePath());
}
// Beware: ImportNode(xxx, false) DOES NOT copy the node's attribute on *some* PHP versions (<5.2.17)
// So use this workaround to import a node and its attributes on *any* PHP version
@@ -1698,7 +1718,7 @@ class MFElement extends DOMElement
{
echo "Dumping parent node<br/>\n";
$oContainer->Dump();
throw new Exception("XML datamodel loader: could not find $this->tagName/$sSearchId in $oContainer->tagName");
throw new Exception("could not find $this->tagName(id:$sSearchId) in ".$oContainer->getNodePath());
}
// Beware: ImportNode(xxx, false) DOES NOT copy the node's attribute on *some* PHP versions (<5.2.17)
// So use this workaround to import a node and its attributes on *any* PHP version
@@ -1767,6 +1787,14 @@ class MFElement extends DOMElement
}
}
/**
* 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
* @package ModelFactory

View File

@@ -114,6 +114,7 @@ class ModuleDiscovery
{
$aDependencies[$sId] = $aModule['dependencies'];
}
ksort($aDependencies);
$aOrderedModules = array();
$iLoopCount = 1;
while(($iLoopCount < count(self::$m_aModules)) && (count($aDependencies) > 0) )

View File

@@ -535,6 +535,10 @@ class SetupUtils
{
if (function_exists('symlink'))
{
if (file_exists($sDest.'/'.$sFile))
{
unlink($sDest.'/'.$sFile);
}
symlink($sSource.'/'.$sFile, $sDest.'/'.$sFile);
}
else
@@ -544,6 +548,10 @@ class SetupUtils
}
else
{
if (is_link($sDest.'/'.$sFile))
{
unlink($sDest.'/'.$sFile);
}
copy($sSource.'/'.$sFile, $sDest.'/'.$sFile);
}
}
@@ -738,7 +746,7 @@ function ValidateField(sFieldId, bUsed)
{
if (sValue != "")
{
if (sValue.match(/^[A-Za-z][A-Za-z0-9_]*$/))
if (sValue.match(/^[A-Za-z0-9_]*$/))
{
var bCollision = false;
if (sFieldId == 'db_new_name')

View File

@@ -480,7 +480,7 @@ EOF
{
// Special case for upgrading some development versions (temporary)
$sCompatibleDMDir = SetupUtils::GetLatestDataModelDir();
$sInstalledDataModelVersion = SetupUtils::GetDataModelVersion($sLatestDMDir);
$sInstalledDataModelVersion = SetupUtils::GetDataModelVersion($sCompatibleDMDir);
}
else
{
@@ -1209,6 +1209,7 @@ EOF
foreach($aOptions as $index => $aChoice)
{
$sChoiceId = $sParentId.self::$SEP.$index;
$aScores[$sChoiceId] = 0;
if (!$this->bUpgrade && isset($aChoice['default']) && $aChoice['default'])
{
$aDefaults[$sChoiceId] = $sChoiceId;
@@ -1272,7 +1273,6 @@ EOF
{
$sChoiceName = $sChoiceId;
}
$aScores[$sChoiceId] = 0;
if (array_key_exists('modules', $aChoice))
{
foreach($aChoice['modules'] as $sModuleId)
@@ -1286,7 +1286,8 @@ EOF
$iScore = 99; // The whole parent choice is selected
}
}
}
}
$iMaxScore = max($iMaxScore, isset($aScores[$sChoiceId]) ? $aScores[$sChoiceId] : 0);
}
}
if ($iMaxScore > 0)