Compare commits

..

3 Commits

Author SHA1 Message Date
odain
f9d9fcc440 N°7398-log level with invalid json 2025-05-07 11:03:13 +02:00
odain
a4a05a2579 N°7398 - be able to add custom data in session files generated by SessionHandler 2025-05-07 11:03:05 +02:00
Benjamin Dalsass
f44468b7a1 N°8245 - External key not saved in n-n link in edition (#703)
* N°8245 - External key not saved in n-n link in edition

* Remove the listener from the input element itself, put it on the body with a selector that matches our input

* Revert "N°8245 - External key not saved in n-n link in edition"

This reverts commit a756f9b159.

---------

Co-authored-by: Stephen Abello <stephen.abello@combodo.com>
2025-03-24 14:05:30 +01:00
113 changed files with 298 additions and 777 deletions

View File

@@ -93,12 +93,6 @@ gitGraph
checkout support/3.2
commit id: "2024-06-25" tag: "3.2.0-beta1" type: REVERSE
commit id: "2024-08-07" tag: "3.2.0"
checkout support/2.7
commit id: "2025-02-25" tag: "2.7.12"
checkout support/3.1
commit id: "2025-02-25 " tag: "3.1.3"
checkout support/3.2
commit id: "2025-02-25 " tag: "3.2.1"
```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

View File

@@ -1,9 +1,5 @@
<p align="center"><a href="https://www.combodo.com/itop-193" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="/images/logos/logo-itop-baseline-light.svg">
<source media="(prefers-color-scheme: light)" srcset="/images/logos/logo-itop-baseline-dark.svg">
<img src="/images/logos/logo-itop-baseline-light.svg" width="350" alt="Logo iTop with baseline" />
</picture>
<img src="https://www.combodo.com/logos/logo-itop-baseline.svg" width=350>
</a></p>
@@ -110,7 +106,6 @@ We would like to give a special thank you 🤗 to the people from the community
- Raenker, Martin
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
- Rosenke, Stephan
- Rossi, Tommaso (a.k.a [@tomrss](https://www.github.com/tomrss))
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
- Seki, Shoji
@@ -120,7 +115,6 @@ We would like to give a special thank you 🤗 to the people from the community
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
- Tulio, Marco
- Turrubiates, Miguel
- Vlk, Karel (a.k.a [@vlk-charles](https://www.github.com/vlk-charles))
### Aliases

View File

@@ -195,31 +195,16 @@ class ApplicationContext
/**
* Returns the context as string with the format name1=value1&name2=value2....
* @return string The context as a string to be appended to an href property
*
*/
public function GetForLink(bool $bWithLeadingAmpersand = false)
public function GetForLink()
{
// If there are no parameters, return an empty string
if(empty($this->aValues)){
return '';
}
// Build the query string with ampersand separated parameters
$aParams = array();
foreach($this->aValues as $sName => $sValue)
{
$aParams[] = "c[$sName]".'='.urlencode($sValue);
}
$sReturnValue = implode('&', $aParams);
// add the leading ampersand if requested
if($bWithLeadingAmpersand){
$sReturnValue = '&' . $sReturnValue;
}
return $sReturnValue;
return implode("&", $aParams);
}
/**
* @since 3.0.0 N°2534 - dashboard: bug with autorefresh that deactivates filtering on organisation
* Returns the params as c[menu]:..., c[org_id]:....
@@ -397,7 +382,7 @@ class ApplicationContext
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
if (utils::StrLen($sUrl) > 0) {
if ($bWithNavigationContext) {
return $sUrl.$oAppContext->GetForLink(true);
return $sUrl."&".$oAppContext->GetForLink();
} else {
return $sUrl;
}

View File

@@ -311,7 +311,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
{
$sParams .= $sName.'='.urlencode($value).'&'; // Always add a trailing &
}
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/'.$oObj->GetUIPage().'?'.$sParams.'class='.get_class($oObj).'&id='.$oObj->getKey().$oAppContext->GetForLink(true).'&a=1';
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/'.$oObj->GetUIPage().'?'.$sParams.'class='.get_class($oObj).'&id='.$oObj->getKey().'&'.$oAppContext->GetForLink().'&a=1';
$oPage->add_early_script(<<<JS
if (!sessionStorage.getItem('$sSessionStorageKey'))
{
@@ -1337,7 +1337,7 @@ HTML
}
}
}
$aHeader['friendlyname'] = ['label' => MetaModel::GetName($sClassName)];
foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) {
$sColLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx) : $sAttCodeEx;
@@ -1358,7 +1358,6 @@ HTML
$aRow = [];
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
$oObj = $aObjects[$sAlias];
$aRow["friendlyname"] = $oObj->Get('friendlyname');
foreach ($aList[$sAlias] as $sAttCodeEx => $oAttDef) {
if (is_null($oObj)) {
$aRow[$oAttDef->GetCode()] = '';
@@ -3072,7 +3071,7 @@ JS
$oPage->add($oAppContext->GetForForm());
// Hook the cancel button via jQuery so that it can be unhooked easily as well if needed
$sDefaultUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_form&class='.$sClass.$oAppContext->GetForLink(true);
$sDefaultUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_form&class='.$sClass.'&'.$oAppContext->GetForLink();
$sCancelButtonOnClickScript = "let fOnClick{$this->m_iFormId}CancelButton = ";
if(isset($aExtraParams['js_handlers']['cancel_button_on_click'])){
@@ -3080,7 +3079,7 @@ JS
} else {
$sCancelButtonOnClickScript .= "function() { BackToDetails('$sClass', $iKey, '$sDefaultUrl', $sJSToken)};";
}
$sCancelButtonOnClickScript .= "$('#form_{$this->m_iFormId} button.cancel').on('click.navigation.itop', fOnClick{$this->m_iFormId}CancelButton);";
$sCancelButtonOnClickScript .= "$('#form_{$this->m_iFormId} button.cancel').on('click', fOnClick{$this->m_iFormId}CancelButton);";
$oPage->add_ready_script($sCancelButtonOnClickScript);
$iFieldsCount = count($aFieldsMap);

View File

@@ -524,7 +524,9 @@ EOF
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
{
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
if (!array_key_exists('dashboard_div_id', $aExtraParams)) {
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
}
/** @var \DashboardLayoutMultiCol $oLayout */
$oLayout = new $this->sLayoutClass();
@@ -1050,7 +1052,7 @@ EOF
$sSelectorHtml .= '</div>';
$sFile = addslashes($this->GetDefinitionFile());
$sReloadURL = json_encode($this->GetReloadURL());
$sReloadURL = $this->GetReloadURL();
$bFromDashboardPage = isset($aAjaxParams['from_dashboard_page']) ? isset($aAjaxParams['from_dashboard_page']) : false;
if ($bFromDashboardPage) {
@@ -1139,6 +1141,7 @@ JS
->AddCSSClass('ibo-action-button');
$oToolbar->AddSubBlock($oActionButton);
$aActions = array();
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
$sJSExtraParams = json_encode($aExtraParams);
@@ -1163,7 +1166,7 @@ JS
$oToolbar->AddSubBlock($oActionButton)
->AddSubBlock($oActionsMenu);
$sReloadURL = json_encode($this->GetReloadURL());
$sReloadURL = $this->GetReloadURL();
$oPage->add_script(
<<<EOF
function EditDashboard(sId, sDashboardFile, aExtraParams)
@@ -1270,7 +1273,7 @@ EOF
$sTitle = json_encode($this->sTitle);
$sFile = json_encode($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = json_encode($this->GetReloadURL());
$sReloadURL = $this->GetReloadURL();
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));

View File

@@ -2138,7 +2138,7 @@ class DashletHeaderDynamic extends Dashlet
$oSet = new DBObjectSet($oFilter);
$iCount = $oSet->Count();
$oAppContext = new ApplicationContext();
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($oFilter->serialize());
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($oFilter->serialize());
$oSubTitle->AddHtml('<a class="summary" href="'.$sHyperlink.'">'.Dict::Format(str_replace('_', ':', $sSubtitle), $iCount).'</a>');
return $oPanel;

View File

@@ -1124,7 +1124,7 @@ JS
$oSingleGroupByValueFilter->SetShowObsoleteData($this->m_bShowObsoleteData);
}
$sHyperlink = utils::GetAbsoluteUrlAppRoot()
.'pages/UI.php?operation=search'.$oAppContext->GetForLink(true)
.'pages/UI.php?operation=search&'.$oAppContext->GetForLink()
.'&filter='.rawurlencode($oSingleGroupByValueFilter->serialize());
$aCounts[$sStateValue] = ['link' => $sHyperlink, 'label' => $aCounts[$sStateValue]];
}
@@ -1232,7 +1232,7 @@ JS
$iCount = $this->m_oSet->Count();
$sClassLabel = MetaModel::GetName($sClass);
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize());
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize());
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
$aRefreshParams = [
@@ -1241,7 +1241,7 @@ JS
];
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.'&'.$oAppContext->GetForLink();
$sCreateActionLabel = Dict::Format('UI:Button:Create');
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, $sCreateActionUrl,
$sCreateActionLabel, $aRefreshParams);
@@ -1289,7 +1289,7 @@ JS
$aData = array();
$oAppContext = new ApplicationContext();
$sParams = $oAppContext->GetForLink(true);
$sParams = $oAppContext->GetForLink();
foreach ($aGroupBy as $iRow => $iCount) {
// Build the search for this subset
$oSubsetSearch = $this->m_oFilter->DeepClone();
@@ -1304,7 +1304,7 @@ JS
$aData[] = array(
'group' => $aLabels[$iRow],
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>"
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1&$sParams&filter=$sFilter\">$iCount</a>"
); // TO DO: add the context information
}
$aAttribs = array(
@@ -1636,7 +1636,7 @@ JS
$sGroupByExpr = isset($aExtraParams['group_by_expr']) ? '&params[group_by_expr]='.$aExtraParams['group_by_expr'] : '';
$sFilter = $this->m_oFilter->serialize(false, $aQueryParams);
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink(true);
$sContextParam = $oContext->GetForLink();
$sAggregationFunction = isset($aExtraParams['aggregation_function']) ? $aExtraParams['aggregation_function'] : '';
$sAggregationAttr = isset($aExtraParams['aggregation_attribute']) ? $aExtraParams['aggregation_attribute'] : '';
$sLimit = isset($aExtraParams['limit']) ? $aExtraParams['limit'] : '';
@@ -1644,7 +1644,7 @@ JS
$sOrderDirection = isset($aExtraParams['order_direction']) ? $aExtraParams['order_direction'] : '';
if (isset($aExtraParams['group_by_label'])) {
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[group_by_label]={$aExtraParams['group_by_label']}&params[chart_type]=$sChartType&params[currentId]=$sChartId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).$sContextParam;
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[group_by_label]={$aExtraParams['group_by_label']}&params[chart_type]=$sChartType&params[currentId]=$sChartId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
} else {
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$sGroupBy{$sGroupByExpr}&params[chart_type]=$sChartType&params[currentId]=$sChartId{$iChartCounter}&params[order_direction]=$sOrderDirection&params[order_by]=$sOrderBy&params[limit]=$sLimit&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
}
@@ -1681,14 +1681,11 @@ JS
$oBlock = null;
$sJSURLs = '';
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink(true);
if (isset($aExtraParams['group_by'])) {
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
$aRes = CMDBSource::QueryToArray($sSql);
$oContext = new ApplicationContext();
$sContextParam = $oContext->GetForLink();
$iTotalCount = 0;
$aURLs = array();
@@ -1708,14 +1705,14 @@ JS
$oSubsetSearch = $this->m_oFilter->DeepClone();
$oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($sValue));
$oSubsetSearch->AddConditionExpression($oCondition);
$aURLs[] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".rawurlencode($oSubsetSearch->serialize()).$sContextParam;
$aURLs[] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".rawurlencode($oSubsetSearch->serialize()).'&'.$sContextParam;
}
$sJSURLs = json_encode($aURLs);
}
if (isset($aExtraParams['group_by_label'])) {
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$aExtraParams[group_by]&params[group_by_label]={$aExtraParams['group_by_label']}&params[chart_type]=$sChartType&params[currentId]=$aExtraParams[currentId]&params[order_direction]=$aExtraParams[order_direction]&params[order_by]=$aExtraParams[order_by]&params[limit]=$aExtraParams[limit]&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).$sContextParam;
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$aExtraParams[group_by]&params[group_by_label]={$aExtraParams['group_by_label']}&params[chart_type]=$sChartType&params[currentId]=$aExtraParams[currentId]&params[order_direction]=$aExtraParams[order_direction]&params[order_by]=$aExtraParams[order_by]&params[limit]=$aExtraParams[limit]&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).'&'.$sContextParam;
} else {
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$aExtraParams[group_by]&params[chart_type]=$sChartType&params[currentId]=$aExtraParams[currentId]&params[order_direction]=$aExtraParams[order_direction]&params[order_by]=$aExtraParams[order_by]&params[limit]=$aExtraParams[limit]&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).$sContextParam;
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart&params[group_by]=$aExtraParams[group_by]&params[chart_type]=$sChartType&params[currentId]=$aExtraParams[currentId]&params[order_direction]=$aExtraParams[order_direction]&params[order_by]=$aExtraParams[order_by]&params[limit]=$aExtraParams[limit]&params[aggregation_function]=$sAggregationFunction&params[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).'&'.$sContextParam;
}
switch ($sChartType) {
@@ -1788,7 +1785,7 @@ JS
$oBlock->sCsvFile = strtolower($this->m_oFilter->GetClass()).'.csv';
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
// Pass the parameters via POST, since expression may be very long
$aParamsToPost = array(
'expression' => $this->m_oFilter->ToOQL(true),
@@ -1888,7 +1885,10 @@ class MenuBlock extends DisplayBlock
&& (!isset($aExtraParams['menu']) || $aExtraParams['menu'] === "1" || $aExtraParams['menu'] === true)
) {
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink(true);
$sContext = $oAppContext->GetForLink();
if (utils::IsNotNullOrEmptyString($sContext)) {
$sContext = '&'.$sContext;
}
$sFilter = $this->GetFilter()->serialize();
@@ -2578,8 +2578,11 @@ class MenuBlock extends DisplayBlock
$sUrl = "{$sRootUrl}pages/{$sUIPage}?{$sUrlParams}";
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink(true);
$sContext = $oAppContext->GetForLink();
if (utils::IsNotNullOrEmptyString($sContext)) {
$sUrl .= '&'.$sContext;
}
return $sUrl . $sContext;
return $sUrl;
}
}

View File

@@ -63,14 +63,14 @@ class CoreCannotSaveObjectException extends CoreException
public function getTextMessage()
{
$sTitle = Dict::S('UI:Error:SaveFailed');
$sContent = $sTitle;
$sContent = utils::HtmlEntities($sTitle);
if (count($this->aIssues) == 1) {
$sIssue = reset($this->aIssues);
$sContent .= $sIssue;
$sContent .= utils::HtmlEntities($sIssue);
} else {
foreach ($this->aIssues as $sError) {
$sContent .= " " . $sError . ", ";
$sContent .= " ".utils::HtmlEntities($sError).", ";
}
}

View File

@@ -67,7 +67,7 @@ class CoreException extends Exception
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
{
return utils::EscapeHtml($this->getMessage());
return $this->getMessage();
}
/**

View File

@@ -250,7 +250,7 @@ class UIExtKeyWidget
foreach ($aAdditionalField as $sAdditionalField) {
array_push($aArguments, $oObj->Get($sAdditionalField));
}
$aOption['additional_field'] = utils::HtmlEntities(utils::VSprintf($sFormatAdditionalField, $aArguments));
$aOption['additional_field'] = utils::HtmlEntities(vsprintf($sFormatAdditionalField, $aArguments));
}
if (!empty($sObjectImageAttCode)) {
// Try to retrieve image for contact

View File

@@ -521,8 +521,8 @@ class utils
// For URL
case static::ENUM_SANITIZATION_FILTER_URL:
$retValue = filter_var($value, FILTER_SANITIZE_URL);
$retValue = filter_var($retValue, FILTER_VALIDATE_URL);
// N°6350 - returns only valid URLs
$retValue = filter_var($value, FILTER_VALIDATE_URL);
break;
default:
@@ -1516,12 +1516,12 @@ class utils
case iPopupMenuExtension::MENU_OBJLIST_TOOLKIT:
/** @var \DBObjectSet $param */
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink(true);
$sContext = $oAppContext->GetForLink();
$sDataTableId = is_null($sDataTableId) ? '' : $sDataTableId;
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($param->GetFilter()->GetClass());
$sOQL = addslashes($param->GetFilter()->ToOQL(true));
$sFilter = urlencode($param->GetFilter()->serialize());
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/$sUIPage?operation=search&filter=".$sFilter.$sContext;
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/$sUIPage?operation=search&filter=".$sFilter."&{$sContext}";
$oContainerBlock->AddJsFileRelPath('js/tabularfieldsselector.js');
$oContainerBlock->AddJsFileRelPath('js/jquery.dragtable.js');
$oContainerBlock->AddCssFileRelPath('css/dragtable.css');
@@ -1555,10 +1555,6 @@ class utils
}
$aResult[] = new JSPopupMenuItem('UI:Menu:AddToDashboard', Dict::S('UI:Menu:AddToDashboard'), "DashletCreationDlg('$sOQL', '$sContext')");
$aResult[] = new JSPopupMenuItem('UI:Menu:ShortcutList', Dict::S('UI:Menu:ShortcutList'), "ShortcutListDlg('$sOQL', '$sDataTableId', '$sContext')");
if (ApplicationMenu::IsMenuIdEnabled('RunQueriesMenu')) {
$oMenuItemPlay = new JSPopupMenuItem('UI:Menu:OpenOQL', Dict::S('UI:Menu:OpenOQL'), "OpenOql('$sOQL')");
$aResult[] = $oMenuItemPlay;
}
break;
@@ -1695,8 +1691,8 @@ class utils
$oAppContext = new ApplicationContext();
$sUrl = $sAppRootUrl
.'pages/UI.php?operation=search'
.$oAppContext->GetForLink(true)
.'pages/UI.php?operation=search&'
.$oAppContext->GetForLink()
.'&filter='.rawurlencode($oDataTableSearchFilter->serialize());
$sUrl .= '&aParams='.rawurlencode($sParams); // Not working... yet, cause not handled by UI.php
@@ -2079,127 +2075,6 @@ SQL;
);
}
/**
* Format a string using vsprintf with safety checks to avoid ValueError
*
* This method fills missing arguments with their original format specifiers,
* then calls vsprintf with the complete array.
*
* @param string $sFormat The format string
* @param array $aArgs The arguments to format
* @param bool $bLogErrors Whether to log errors (defaults to true)
*
* @return string The formatted string
* @since 3.2.2
*/
public static function VSprintf(string $sFormat, array $aArgs, bool $bLogErrors = true): string
{
// Extract all format specifiers
$sPattern = '/%(?:(?:[1-9][0-9]*)\$)?[-+\'0# ]*(?:[0-9]*|\*)?(?:\.(?:[0-9]*|\*))?(?:[hlL])?[diouxXeEfFgGcrs%]/';
preg_match_all($sPattern, $sFormat, $aMatches, PREG_OFFSET_CAPTURE);
// Process matches, keeping track of their positions and excluding escaped percent signs (%%)
$aSpecifierMatches = [];
foreach ($aMatches[0] as $sMatch) {
if ($sMatch[0] !== '%%') {
$aSpecifierMatches[] = $sMatch;
}
}
// Check for positional specifiers and build position map
$bHasPositional = false;
$iMaxPosition = 0;
$aPositions = [];
$aUniquePositions = [];
foreach ($aSpecifierMatches as $index => $match) {
$sSpec = $match[0];
if (preg_match('/^%([1-9][0-9]*)\$/', $sSpec, $posMatch)) {
$bHasPositional = true;
$iPosition = (int)$posMatch[1] - 1; // Convert to 0-based
$aPositions[$index] = $iPosition;
$aUniquePositions[$iPosition] = true;
$iMaxPosition = max($iMaxPosition, $iPosition + 1);
} else {
$aPositions[$index] = $index;
$aUniquePositions[$index] = true;
$iMaxPosition = max($iMaxPosition, $index + 1);
}
}
// Count unique positions, this tells us how many arguments we actually need
$iExpectedCount = count($aUniquePositions);
$iActualCount = count($aArgs);
// If we have enough arguments, just use vsprintf
if ($iActualCount >= $iExpectedCount) {
return vsprintf($sFormat, $aArgs);
}
// else log the error if needed
if ($bLogErrors) {
IssueLog::Warning("Format string requires $iExpectedCount arguments, but only $iActualCount provided. Format: '$sFormat'" );
}
// Create a replacement map
if ($bHasPositional) {
// For positional, we need to handle the exact positions
$aReplacements = array_fill(0, $iMaxPosition, null);
// Fill in the real arguments first
foreach ($aArgs as $index => $sValue) {
if ($index < $iMaxPosition) {
$aReplacements[$index] = $sValue;
}
}
// For null values in the replacement map, use the original specifier
foreach ($aSpecifierMatches as $index => $sMatch) {
$iPosition = $aPositions[$index];
if ($aReplacements[$iPosition] === null) {
// Use the original format specifier when we don't have an argument
$aReplacements[$iPosition] = $sMatch[0];
}
}
// Remove any remaining nulls (for positions that weren't referenced)
$aReplacements = array_filter($aReplacements, static function($val) { return $val !== null; });
} else {
// For non-positional, we need to map each position
$aReplacements = [];
$iUsed = 0;
// Create a map of what values to use for each position
$aPositionValues = [];
for ($i = 0; $i < $iMaxPosition; $i++) {
if (isset($aUniquePositions[$i])) {
if ($iUsed < $iActualCount) {
// We have an actual argument for this position
$aPositionValues[$i] = $aArgs[$iUsed++];
} else {
// Mark this position to use the original specifier
$aPositionValues[$i] = null;
}
}
}
// Build the replacements array preserving the original order
foreach ($aSpecifierMatches as $index => $sMatch) {
$iPosition = $aPositions[$index];
if (isset($aPositionValues[$iPosition])) {
$aReplacements[] = $aPositionValues[$iPosition];
} else {
// Use the original format specifier when we don't have an argument
$aReplacements[] = $sMatch[0];
// Mark this position as used, so if it appears again, it gets the same replacement
$aPositionValues[$iPosition] = $sMatch[0];
}
}
}
// Process the format string with our filled-in arguments
return vsprintf($sFormat, $aReplacements);
}
/**
* Convert a string containing some (valid) HTML markup to plain text
*

View File

@@ -4995,7 +4995,7 @@ class AttributeCaseLog extends AttributeLongText
}
else
{
if (utils::StrLen($proposedValue) > 0)
if (strlen($proposedValue) > 0)
{
//N°5135 - add impersonation information in caselog
if (UserRights::IsImpersonated()){
@@ -10954,12 +10954,12 @@ abstract class AttributeSet extends AttributeDBFieldVoid
$sDescription = utils::EscapeHtml($this->GetValueDescription($sValue));
$oFilter = DBSearch::FromOQL("SELECT $sClass WHERE $sAttCode MATCHES '$sValue'");
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink(true);
$sContext = $oAppContext->GetForLink();
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($oFilter->GetClass());
$sFilter = rawurlencode($oFilter->serialize());
$sLink = '';
if ($bWithLink && $this->bDisplayLink) {
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/$sUIPage?operation=search&filter=".$sFilter.$sContext;
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/$sUIPage?operation=search&filter=".$sFilter."&{$sContext}";
$sLink = ' href="'.$sUrl.'"';
}
@@ -12276,13 +12276,13 @@ class AttributeTagSet extends AttributeSet
$sTagDescription = $oTag->Get('description');
$oFilter = DBSearch::FromOQL("SELECT $sClass WHERE $sAttCode MATCHES '$sTagCode'");
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink(true);
$sContext = $oAppContext->GetForLink();
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($oFilter->GetClass());
$sFilter = rawurlencode($oFilter->serialize());
$sLink = '';
if ($bWithLink && $this->bDisplayLink) {
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/$sUIPage?operation=search&filter=".$sFilter.$sContext;
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/$sUIPage?operation=search&filter=".$sFilter."&{$sContext}";
$sLink = ' href="'.$sUrl.'"';
}

View File

@@ -1406,7 +1406,7 @@ class BulkChange
$aDetails = array();
while ($oChange = $oBulkChanges->Fetch())
{
$sDate = '<a href="csvimport.php?step=10&changeid='.$oChange->GetKey().$oAppContext->GetForLink(true).'">'.$oChange->Get('date').'</a>';
$sDate = '<a href="csvimport.php?step=10&changeid='.$oChange->GetKey().'&'.$oAppContext->GetForLink().'">'.$oChange->Get('date').'</a>';
$sUser = $oChange->GetUserName();
if (preg_match('/^(.*)\\(CSV\\)$/i', $oChange->Get('userinfo'), $aMatches))
{
@@ -1488,7 +1488,7 @@ EOF
function OnTruncatedHistoryToggle(bShowAll)
{
$('#csv_history_reload').html('<img src="' + GetAbsoluteUrlAppRoot() + 'images/indicator.gif"/>');
$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?$sAppContext', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sAppContext}', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
{
$('#$sAjaxDivId').html(data);
}

View File

@@ -25,7 +25,7 @@ define('EXPORTER_DEFAULT_CHUNK_SIZE', 1000);
class BulkExportException extends Exception
{
protected $sLocalizedMessage;
public function __construct($message, $sLocalizedMessage, $code = 0, $previous = null)
public function __construct($message, $sLocalizedMessage, $code = null, $previous = null)
{
parent::__construct($message, $code, $previous);
$this->sLocalizedMessage = $sLocalizedMessage;

View File

@@ -206,7 +206,7 @@ class Dict
}
try{
return utils::VSprintf($sLocalizedFormat, $aArguments);
return vsprintf($sLocalizedFormat, $aArguments);
} catch(\Throwable $e){
\IssueLog::Error("Cannot format dict key", null, ["sFormatCode" => $sFormatCode, "sLangCode" => $sLangCode, 'exception_msg' => $e->getMessage() ]);
return $sFormatCode.' - '.implode(', ', $aArguments);

View File

@@ -1470,8 +1470,8 @@ class DisplayableGraph extends SimpleGraph
try {
$this->InitFromGraphviz();
$sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_pdf&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
$sContext = $oAppContext->GetForLink(true);
$sDrillDownURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class=%1$s&id=%2$s'.$sContext;
$sContext = $oAppContext->GetForLink();
$sDrillDownURL = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class=%1$s&id=%2$s&'.$sContext;
$sExportAsDocumentURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_attachment&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
$sLoadFromURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_json&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
$sAttachmentExportTitle = '';

View File

@@ -469,8 +469,7 @@ class ExecutionKPI
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
//$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$sExtension = '';
$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_STATS,
$sOperation,

View File

@@ -7081,7 +7081,7 @@ abstract class MetaModel
* @param array $aParams
* @param bool $bAllowAllData
*
* @return \DBObject|null
* @return \DBObject
* @throws \OQLException
*/
public static function GetObjectFromOQL($sQuery, $aParams = null, $bAllowAllData = false)

View File

@@ -77,7 +77,7 @@ abstract class ModelReflection
return $sFormatCode.' - '.implode(', ', $aArguments);
}
return utils::VSprintf($sLocalizedFormat, $aArguments);
return vsprintf($sLocalizedFormat, $aArguments);
}
/**

View File

@@ -76,52 +76,6 @@ class ObjectResult
$this->fields = array();
}
/**
* Creates an ObjectResult from a DBObject.
*
* @param DBObject $oObj The object.
* @param array|null $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported.
* @param boolean $bExtendedOutput Output all of the link set attributes ?
* @param integer $iCode An error code (RestResult::OK is no issue has been found)
* @param string $sMessage Description of the error if any, an empty string otherwise
*
* @return ObjectResult
*/
public static function FromDBObject(DBObject $oObj, ?array $aFieldSpec = null, $bExtendedOutput = false, $iCode = 0, $sMessage = '') : ObjectResult {
$oObjRes = new ObjectResult($oObj::class, $oObj->GetKey());
$oObjRes->code = $iCode;
$oObjRes->message = $sMessage;
$aFields = null;
if (!is_null($aFieldSpec))
{
// Enum all classes in the hierarchy, starting with the current one
foreach (MetaModel::EnumParentClasses($oObj::class, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass)
{
if (array_key_exists($sRefClass, $aFieldSpec))
{
$aFields = $aFieldSpec[$sRefClass];
break;
}
}
}
if (is_null($aFields))
{
// No fieldspec given, or not found...
$aFields = array('id', 'friendlyname');
}
foreach ($aFields as $sAttCode)
{
$oObjRes->AddField($oObj, $sAttCode, $bExtendedOutput);
}
return $oObjRes;
}
/**
* Helper to make an output value for a given attribute
*
@@ -250,7 +204,34 @@ class RestResultWithObjects extends RestResult
*/
public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false)
{
$oObjRes = ObjectResult::FromDBObject($oObject, $aFieldSpec, $bExtendedOutput, $iCode, $sMessage);
$sClass = get_class($oObject);
$oObjRes = new ObjectResult($sClass, $oObject->GetKey());
$oObjRes->code = $iCode;
$oObjRes->message = $sMessage;
$aFields = null;
if (!is_null($aFieldSpec))
{
// Enum all classes in the hierarchy, starting with the current one
foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass)
{
if (array_key_exists($sRefClass, $aFieldSpec))
{
$aFields = $aFieldSpec[$sRefClass];
break;
}
}
}
if (is_null($aFields))
{
// No fieldspec given, or not found...
$aFields = array('id', 'friendlyname');
}
foreach ($aFields as $sAttCode)
{
$oObjRes->AddField($oObject, $sAttCode, $bExtendedOutput);
}
$sObjKey = get_class($oObject).'::'.$oObject->GetKey();
$this->objects[$sObjKey] = $oObjRes;

View File

@@ -1962,15 +1962,6 @@ class UserRights
return self::$m_aCacheUsers[$sAuthentication][$sLogin];
}
/**
* Reset the cache of users
* @return void
*/
public static function ResetCacheUsers()
{
self::$m_aCacheUsers = [ 'internal' => [], 'external' => [] ];
}
/**
* @param string$sClass
* @param array $aAllowedOrgs
@@ -2129,8 +2120,6 @@ class StimulusChecker extends ActionChecker
{
var $sState = null;
public mixed $iState = null;
public function __construct(DBSearch $oFilter, $sState, $iStimulusCode)
{
parent::__construct($oFilter, $iStimulusCode);

View File

@@ -435,7 +435,7 @@ class ValueSetObjects extends ValueSetDefinition
foreach ($aAdditionalField as $sAdditionalField) {
array_push($aArguments, $oObject->Get($sAdditionalField));
}
$aData['additional_field'] = utils::VSprintf($sFormatAdditionalField, $aArguments);
$aData['additional_field'] = vsprintf($sFormatAdditionalField, $aArguments);
} else {
$aData['additional_field'] = '';
}

View File

@@ -21,10 +21,12 @@
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<format>%1$s</format>
<attributes>
<attribute id="login"/>
</attributes>
</naming>
<display_template/>
<style>
<icon/>
</style>

View File

@@ -201,7 +201,7 @@ SQL;
}
SetupLog::Info("Initializing attachment/item_org_id - $iUpdated records have been adjusted");
if (MetaModel::GetAttributeDef('Attachment', 'contact_id') instanceof AttributeExternalKey && version_compare($sPreviousVersion, '3.2.0', '<')) {
if (MetaModel::GetAttributeDef('Attachment', 'contact_id') instanceof AttributeExternalKey) {
SetupLog::Info("Upgrading itop-attachment from '$sPreviousVersion' to '$sCurrentVersion'. Starting with 3.2.0, contact_id will be added into the DB...");
$sUserTableName = MetaModel::DBGetTable('User');
$sUserFieldContactId = MetaModel::GetAttributeDef('User', 'contactid')->Get('sql');

View File

@@ -53,7 +53,14 @@ class DBRestore extends DBBackup
$sUser = self::EscapeShellArg($this->sDBUser);
$sPwd = self::EscapeShellArg($this->sDBPwd);
$sDBName = self::EscapeShellArg($this->sDBName);
$sMySQLExe = DBBackup::MakeSafeMySQLCommand($this->sMySQLBinDir, 'mysql');
if (empty($this->sMySQLBinDir))
{
$sMySQLExe = 'mysql';
}
else
{
$sMySQLExe = '"'.$this->sMySQLBinDir.'/mysql"';
}
if (is_null($this->iDBPort))
{
$sPortOption = '';

View File

@@ -95,7 +95,12 @@ try {
//
$sMySQLBinDir = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', '');
$sMySQLBinDir = utils::ReadParam('mysql_bindir', $sMySQLBinDir, true);
$sMySQLDump = DBBackup::MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump');
if (empty($sMySQLBinDir)) {
$sMySQLDump = 'mysqldump';
} else {
//echo 'Info - Found mysql_bindir: '.$sMySQLBinDir;
$sMySQLDump = '"'.$sMySQLBinDir.'/mysqldump"';
}
$sCommand = "$sMySQLDump -V 2>&1";
$aOutput = array();

View File

@@ -46,12 +46,12 @@
<field id="status" xsi:type="AttributeEnum">
<sort_type>rank</sort_type>
<values>
<value id="approved">
<value id="approved">approved
<code>approved</code>
<rank>60</rank>
<style><main_color>$ibo-lifecycle-success-state-primary-color</main_color><complementary_color>$ibo-lifecycle-success-state-secondary-color</complementary_color><decoration_classes>fas fa-user-check</decoration_classes></style>
</value>
<value id="assigned">
<value id="assigned">assigned
<code>assigned</code>
<rank>40</rank>
<style><main_color>$ibo-lifecycle-neutral-state-primary-color</main_color><complementary_color>$ibo-lifecycle-neutral-state-secondary-color</complementary_color><decoration_classes/></style>

View File

@@ -151,7 +151,7 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:Change/Stimulus:ev_approve+' => '',
'Class:Change/Stimulus:ev_replan' => 'Replan',
'Class:Change/Stimulus:ev_replan+' => '',
'Class:Change/Stimulus:ev_notapprove' => 'Reject approval',
'Class:Change/Stimulus:ev_notapprove' => 'Reject',
'Class:Change/Stimulus:ev_notapprove+' => '',
'Class:Change/Stimulus:ev_implement' => 'Implement',
'Class:Change/Stimulus:ev_implement+' => '',

View File

@@ -151,7 +151,7 @@ Dict::Add('EN GB', 'British English', 'British English', array(
'Class:Change/Stimulus:ev_approve+' => '',
'Class:Change/Stimulus:ev_replan' => 'Replan',
'Class:Change/Stimulus:ev_replan+' => '',
'Class:Change/Stimulus:ev_notapprove' => 'Reject approval',
'Class:Change/Stimulus:ev_notapprove' => 'Reject',
'Class:Change/Stimulus:ev_notapprove+' => '',
'Class:Change/Stimulus:ev_implement' => 'Implement',
'Class:Change/Stimulus:ev_implement+' => '',

View File

@@ -139,7 +139,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
'Class:Change/Stimulus:ev_approve+' => '~~',
'Class:Change/Stimulus:ev_replan' => 'Replan~~',
'Class:Change/Stimulus:ev_replan+' => '~~',
'Class:Change/Stimulus:ev_notapprove' => 'Reject approval~~',
'Class:Change/Stimulus:ev_notapprove' => 'Reject~~',
'Class:Change/Stimulus:ev_notapprove+' => '~~',
'Class:Change/Stimulus:ev_implement' => 'Implement~~',
'Class:Change/Stimulus:ev_implement+' => '~~',

View File

@@ -380,6 +380,7 @@
</attribute>
<attribute id="private_log">
<read_only/>
<read_only/>
</attribute>
<attribute id="caller_id">
<read_only/>

View File

@@ -4351,6 +4351,7 @@
</item>
<item id="document_id">
<rank>20</rank>
<rank>20</rank>
</item>
</items>
</list>
@@ -5735,7 +5736,8 @@
<duplicates/>
</field>
</fields>
<methods/>
<methods>
</methods>
<presentation>
<details>
<items>
@@ -7228,12 +7230,7 @@
</class>
<class id="DocumentFile" _delta="must_exist">
<presentation>
<details>
<items>
<item id="cis_list" _delta="define">
<rank>70</rank>
</item>
</items>
<details><items><item id="cis_list" _delta="define"><rank>70</rank></item></items>&gt;
</details>
</presentation>
</class>

View File

@@ -323,8 +323,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:NetworkDevice/Attribute:networkdevicetype_id+' => '',
'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Nom Type',
'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '',
'Class:NetworkDevice/Attribute:connectablecis_list' => 'Matériel connecté',
'Class:NetworkDevice/Attribute:connectablecis_list+' => 'Tous les équipements connectés à cet appareil réseau',
'Class:NetworkDevice/Attribute:connectablecis_list' => 'Matériel connectés',
'Class:NetworkDevice/Attribute:connectablecis_list+' => 'Tous les matériels connectés à cet appareil réseau',
'Class:NetworkDevice/Attribute:iosversion_id' => 'Version IOS',
'Class:NetworkDevice/Attribute:iosversion_id+' => '',
'Class:NetworkDevice/Attribute:iosversion_name' => 'Nom Version IOS',
@@ -1597,7 +1597,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkConnectableCIToNetworkDevice/Attribute:network_port+' => '',
'Class:lnkConnectableCIToNetworkDevice/Attribute:device_port' => 'Port matériel',
'Class:lnkConnectableCIToNetworkDevice/Attribute:device_port+' => '',
'Class:lnkConnectableCIToNetworkDevice/Attribute:connection_type' => 'Type de connexion',
'Class:lnkConnectableCIToNetworkDevice/Attribute:connection_type' => 'Type de connection',
'Class:lnkConnectableCIToNetworkDevice/Attribute:connection_type+' => '',
'Class:lnkConnectableCIToNetworkDevice/Attribute:connection_type/Value:downlink' => 'lien descendant',
'Class:lnkConnectableCIToNetworkDevice/Attribute:connection_type/Value:downlink+' => 'lien descendant',

View File

@@ -797,6 +797,7 @@
<is_null_allowed>true</is_null_allowed>
<on_target_delete>DEL_MANUAL</on_target_delete>
<allow_target_creation>false</allow_target_creation>
<allow_target_creation>false</allow_target_creation>
</field>
<field id="powerstart_name" xsi:type="AttributeExternalField">
<extkey_attcode>powerstart_id</extkey_attcode>

View File

@@ -247,10 +247,8 @@
<db_key_field>link_id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="error_name"/>
<attribute id="functionalci_name"/>
</attributes>
<attributes id="error_name"/>
<attributes id="functionalci_name"/>
</naming>
<style>
<icon/>

View File

@@ -53,21 +53,13 @@ $(document).ready(function()
}, 1000);
// Hide tooltips when a modal is opening, otherwise it might be overlapping it
oBodyElem.on('show.bs.modal', '.modal', function ()
oBodyElem.on('show.bs.modal', function ()
{
$(this).find('.tooltip.in').tooltip('hide');
// Set the z-index of the modal and its backdrop in case we have several modals opened
let zIndex = 1050 + (10 * $('.modal:visible').length);
$(this).css('z-index', zIndex);
// Set the z-index of the backdrop later because it is created after the modal
setTimeout(function() {
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
}, 10);
});
/*
* Display an error message on modal if the content could not be loaded.
* Display a error message on modal if the content could not be loaded.
*
* Note : As of now, we can't display a more detailed message based on the response because Bootstrap doesn't pass response data with the loaded event.
*/

View File

@@ -168,13 +168,6 @@ CombodoModal._InstantiateModal = function(oModalElem, oOptions) {
// Show modal
if (oOptions.auto_open) {
// Append modal to body if not already in DOM, this is also done when the modal is shown, but it happens after show.bs.modal event is triggered
// As we put this event listener on the body, it is not triggered when the modal is not in the DOM yet
if (oModalElem.parent().length === 0) {
$('body').append(oModalElem);
}
oModalElem.modal('show');
}

View File

@@ -631,7 +631,7 @@ abstract class AbstractBrick implements TemplatesProviderInterface
// Checking mandatory elements
if (!$oMDElement->hasAttribute('id'))
{
throw new DOMFormatException('Brick node must have both id and xsi:type attributes defined', 0, null, $oMDElement);
throw new DOMFormatException('Brick node must have both id and xsi:type attributes defined', null, null, $oMDElement);
}
$this->SetId($oMDElement->getAttribute('id'));

View File

@@ -93,7 +93,7 @@ class AggregatePageBrick extends PortalBrick
{
if (!$oAggregatePageBrickNode->hasAttribute('id'))
{
throw new DOMFormatException('AggregatePageBrick : must have an id attribute', 0,
throw new DOMFormatException('AggregatePageBrick : must have an id attribute', null,
null, $oAggregatePageBrickNode);
}
$sBrickName = $oAggregatePageBrickNode->getAttribute('id');

View File

@@ -375,7 +375,7 @@ class BrowseBrick extends PortalBrick
{
if (!$oModeNode->hasAttribute('id'))
{
throw new DOMFormatException('BrowseBrick: Browse mode must have a unique ID attribute', 0,
throw new DOMFormatException('BrowseBrick: Browse mode must have a unique ID attribute', null,
null, $oModeNode);
}
@@ -416,7 +416,7 @@ class BrowseBrick extends PortalBrick
// Checking that the brick has at least a browse mode
if (count($this->GetAvailablesBrowseModes()) === 0)
{
throw new DOMFormatException('BrowseBrick : Must have at least one browse mode', 0, null, $oMDElement);
throw new DOMFormatException('BrowseBrick : Must have at least one browse mode', null, null, $oMDElement);
}
// Checking that default browse mode in among the available
if (!in_array($this->sDefaultBrowseMode, array_keys($this->aAvailablesBrowseModes)))
@@ -427,7 +427,7 @@ class BrowseBrick extends PortalBrick
// Checking that the brick has at least a level
if (count($this->GetLevels()) === 0)
{
throw new DOMFormatException('BrowseBrick : Must have at least one level', 0, null, $oMDElement);
throw new DOMFormatException('BrowseBrick : Must have at least one level', null, null, $oMDElement);
}
return $this;

View File

@@ -21,8 +21,6 @@
namespace Combodo\iTop\Portal\Brick;
use Combodo\iTop\DesignElement;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplateDefinitionDto;
use Combodo\iTop\Portal\Service\TemplatesProvider\TemplatesRegister;
use DOMFormatException;
/**
@@ -48,17 +46,6 @@ class CreateBrick extends PortalBrick
/** @var array $aRules */
protected $aRules;
const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig';
/** @inheritdoc */
public static function RegisterTemplates(TemplatesRegister $oTemplatesRegister): void
{
parent::RegisterTemplates($oTemplatesRegister);
$oTemplatesRegister->RegisterTemplates(self::class,
TemplateDefinitionDto::Create('page', static::TEMPLATES_BASE_PATH . 'create/modal.html.twig')
);
}
/**
* Constructor
*/

View File

@@ -252,7 +252,7 @@ class FilterBrick extends PortalBrick
// Checking that the brick has at least a target brick id
if (($this->GetTargetBrickId() === null) || ($this->GetTargetBrickId() === ''))
{
throw new DOMFormatException('FilterBrick : Must have a target brick id', 0, null, $oMDElement);
throw new DOMFormatException('FilterBrick : Must have a target brick id', null, null, $oMDElement);
}
return $this;

View File

@@ -893,7 +893,7 @@ class ManageBrick extends PortalBrick
if (!$oModeNode->hasAttribute('id'))
{
throw new DOMFormatException('ManageBrick: Display mode must have a unique ID attribute',
0, null, $oModeNode);
null, null, $oModeNode);
}
$sModeId = $oModeNode->getAttribute('id');
@@ -930,7 +930,7 @@ class ManageBrick extends PortalBrick
{
if (!$oFieldNode->hasAttribute('id'))
{
throw new DOMFormatException('ManageBrick : Field must have a unique ID attribute', 0,
throw new DOMFormatException('ManageBrick : Field must have a unique ID attribute', null,
null, $oFieldNode);
}
$this->AddField($oFieldNode->getAttribute('id'));
@@ -950,7 +950,7 @@ class ManageBrick extends PortalBrick
if (!$oFieldNode->hasAttribute('id'))
{
throw new DOMFormatException('ManageBrick : Field must have a unique ID attribute',
0,
null,
null, $oFieldNode);
}
$this->AddExportField($oFieldNode->getAttribute('id'));
@@ -1012,7 +1012,7 @@ class ManageBrick extends PortalBrick
if (!$oGroupNode->hasAttribute('id'))
{
throw new DOMFormatException('ManageBrick : Group must have a unique ID attribute',
0, null, $oGroupNode);
null, null, $oGroupNode);
}
$sGroupId = $oGroupNode->getAttribute('id');
@@ -1038,12 +1038,12 @@ class ManageBrick extends PortalBrick
if (!isset($aGroup['title']) || $aGroup['title'] === '')
{
throw new DOMFormatException('ManageBrick : Group must have a title tag and it must not be empty',
0, null, $oGroupNode);
null, null, $oGroupNode);
}
if (!isset($aGroup['condition']) || $aGroup['condition'] === '')
{
throw new DOMFormatException('ManageBrick : Group must have a condition tag and it must not be empty',
0, null, $oGroupNode);
null, null, $oGroupNode);
}
$aGroups[] = $aGroup;
}

View File

@@ -211,7 +211,7 @@ class UserProfileBrick extends PortalBrick
$this->aForm['fields'][$sFieldId] = $aField;
} else {
throw new DOMFormatException('Field tag must have an id attribute', 0, null, $oFieldNode);
throw new DOMFormatException('Field tag must have an id attribute', null, null, $oFieldNode);
}
}
}

View File

@@ -53,13 +53,13 @@ class Forms extends AbstractConfiguration
$sFormId = $oFormNode->getAttribute('id');
if ($oFormNode->getAttribute('id') === '')
{
throw new DOMFormatException('form tag must have an id attribute', 0, null, $oFormNode);
throw new DOMFormatException('form tag must have an id attribute', null, null, $oFormNode);
}
// Parsing form object class
if ($oFormNode->GetUniqueElement('class')->GetText() === null)
{
throw new DOMFormatException('Class tag must be defined', 0, null, $oFormNode);
throw new DOMFormatException('Class tag must be defined', null, null, $oFormNode);
}
// Parsing class
@@ -149,7 +149,7 @@ class Forms extends AbstractConfiguration
$sModeId = $oModeNode->getAttribute('id');
if ($sModeId === '')
{
throw new DOMFormatException('mode tag must have an id attribute', 0, null,
throw new DOMFormatException('mode tag must have an id attribute', null, null,
$oFormNode);
}
$aModes[] = $sModeId;
@@ -225,7 +225,7 @@ class Forms extends AbstractConfiguration
}
else
{
throw new DOMFormatException('Field tag must have an id attribute', 0, null,
throw new DOMFormatException('Field tag must have an id attribute', null, null,
$oFormNode);
}
}

View File

@@ -50,7 +50,7 @@ class Lists extends AbstractConfiguration
$sClassId = $oClassNode->getAttribute('id');
if ($sClassId === null)
{
throw new DOMFormatException('Class tag must have an id attribute', 0, null, $oClassNode);
throw new DOMFormatException('Class tag must have an id attribute', null, null, $oClassNode);
}
// - Each lists

View File

@@ -359,8 +359,7 @@ class ObjectFormManager extends FormManager
foreach ($this->aFieldsAtts as $sAttCode => $iFieldFlags)
{
// handle plugins fields
if($this->sMode !== 'apply_stimulus'
&& array_key_exists($sAttCode, $this->aExtraData)
if(array_key_exists($sAttCode, $this->aExtraData)
&& array_key_exists('plugin', $this->aExtraData[$sAttCode])){
$sPluginName = $this->aExtraData[$sAttCode]['plugin'];
switch($sPluginName){
@@ -714,8 +713,7 @@ class ObjectFormManager extends FormManager
// fallback Checking if the instance has attachments
// (in case attachment is not explicitly declared in layout)
if ($this->sMode !== 'apply_stimulus'
&& class_exists('Attachment') && class_exists('AttachmentPlugIn')
if (class_exists('Attachment') && class_exists('AttachmentPlugIn')
&& !$this->IsPluginInitialized(AttachmentPlugIn::class)
&& AttachmentPlugIn::IsAttachmentAllowedForObject($this->oObject)){
$this->AddAttachmentField($this->oForm, 'attachments_plugin', $this->aExtraData);

View File

@@ -335,7 +335,7 @@ class BrowseBrickHelper
$aRow[$key] = array(
'level_alias' => $key,
'id' => $sCurrentObjectId,
'name' => utils::EscapeHtml($value->Get($sNameAttCode)),
'name' => $value->Get($sNameAttCode),
'class' => $sCurrentObjectClass,
'action_rules_token' => $this->PrepareActionRulesForItems($aItems, $key, $aLevelsProperties),
'metadata' => array(
@@ -513,7 +513,7 @@ class BrowseBrickHelper
$aItems[$sCurrentIndex] = array(
'level_alias' => $aCurrentRowKeys[0],
'id' => $aCurrentRowValues[0]->GetKey(),
'name' => utils::EscapeHtml($aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]]['name_att'])),
'name' => $aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]]['name_att']),
'class' => get_class($aCurrentRowValues[0]),
'subitems' => array(),
'filter_data' => $this->GetFilterData($aLevelsProperties[$aCurrentRowKeys[0]], $aCurrentRowKeys[0], $aCurrentRowValues[0]),

View File

@@ -490,7 +490,7 @@ EOF;
{
throw new DOMFormatException(
'Scope tag in class must have a not empty oql_view tag',
0,
null,
null,
$oScopeNode
);

View File

@@ -10,7 +10,7 @@
{% if aTilesRendering[brick.GetId] is defined %}
{{ aTilesRendering[brick.GetId]|raw }}
{% else %}
{% include '' ~ brick.GetTileTemplatePath with {brick: brick} only %}
{% include '' ~ brick.GetTileTemplatePath with {brick: brick} %}
{% endif %}
{% endfor %}
</section>

View File

@@ -1,44 +0,0 @@
{# itop-portal-base/portal/templates/bricks/create/layout.html.twig #}
{# Create brick base layout #}
{% extends 'itop-portal-base/portal/templates/modal/layout.html.twig' %}
{% block pModalTitle %}
{{ sPageTitle|dict_s }}
{% endblock %}
{% block pModalBody %}
<p>{{ 'Brick:Portal:Create:ChooseType'|dict_s }}</p>
<ul id="{{ sLeafClassesListId }}">
{% for aLeafClass in aLeafClasses %}
<li><a href="#" data-target-class="{{ aLeafClass.id }}">{{ aLeafClass.name }}</a></li>
{% endfor %}
</ul>
<script type="text/javascript">
$(document).ready(function(){
$('#{{ sLeafClassesListId }} a').off('click').on('click', function(oEvent){
oEvent.preventDefault();
// Preparing target class url
var sUrl = '{{ app['url_generator'].generate('p_object_create', {sObjectClass : '-sObjectClass-'})|raw }}';
sUrl = sUrl.replace(/-sObjectClass-/, $(this).attr('data-target-class') );
sUrl = CombodoGlobalToolbox.AddParameterToUrl(sUrl, 'ar_token', '{{ ar_token }}');
// Creating a new modal
CombodoModal.OpenModal({
base_modal: {
usage: 'replace',
selector: $(this).closest('.modal'),
},
content: {
endpoint: sUrl,
},
});
});
});
</script>
{% endblock %}
{% block pModalFooter %}
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'Portal:Button:Cancel'|dict_s }}</button>
{% endblock %}

View File

@@ -156,17 +156,8 @@
return row.attributes[attribute_code].sort_value;
},
filter: function (attribute_code, type, row) {
// Check if the attribute and value_html exist
if (!row.attributes[attribute_code] || !row.attributes[attribute_code]['value_html']) {
return '';
}
// Create a temporary div outside the DOM to filter out XSS
const tempDiv = document.createElement('div');
tempDiv.textContent = row.attributes[attribute_code]['value_html'];
return tempDiv.textContent;
},
return $.text($.parseHTML(row.attributes[attribute_code]['value_html']));
},
},
});
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design version="3.2">
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<classes/>
<user_rights>
<groups>
@@ -199,7 +199,7 @@
<profiles>
<profile id="117" _delta="define">
<name>SuperUser</name>
<description>This profile allows all actions which are not Administrator restricted.</description>
<description>This profil allows all actions which are not Administrator restricted.</description>
<groups>
<group id="AdminTools">
<actions>
@@ -268,11 +268,6 @@
<action id="stimulus:ev_plan">allow</action>
<action id="stimulus:ev_reject">allow</action>
<action id="stimulus:ev_reopen">allow</action>
<action id="stimulus:ev_validate">allow</action>
<action id="stimulus:ev_notapprove">allow</action>
<action id="stimulus:ev_replan">allow</action>
<action id="stimulus:ev_implement">allow</action>
<action id="stimulus:ev_monitor">allow</action>
</actions>
</group>
<group id="Problem">

View File

@@ -256,10 +256,6 @@
<code><![CDATA[
public function OnBeforeWriteTicket(Combodo\iTop\Service\Events\EventData $oEventData)
{
// do not update impacted items from portal
if(ContextTag::Check(ContextTag::TAG_PORTAL)){
return;
}
$aChanges = $this->ListChanges();
if ($this->IsNew() || array_key_exists('functionalcis_list', $aChanges) || array_key_exists('contacts_list', $aChanges)) {
$this->UpdateImpactedItems();

View File

@@ -522,7 +522,6 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'UI:Menu:Manage' => 'Spravovat...',
'UI:Menu:EMail' => 'Email',
'UI:Menu:CSVExport' => 'CSV export',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Upravit...',
'UI:Menu:Delete' => 'Odstranit...',
'UI:Menu:BulkDelete' => 'Odstranit...',

View File

@@ -937,7 +937,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'Class:SynchroAttLinkSet' => 'Synchro Attribut (Linksæt)',
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Række separator',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Attribut separator',
'Class:SynchroLog' => 'Synchro Log',
'Class:SynchroLog' => 'Synchr Log',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Kilde',
'Class:SynchroLog/Attribute:start_date' => 'Start Dato',
'Class:SynchroLog/Attribute:end_date' => 'Slut Dato',

View File

@@ -522,7 +522,6 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'UI:Menu:Manage' => 'Administrer...',
'UI:Menu:EMail' => 'eMail',
'UI:Menu:CSVExport' => 'CSV Eksport...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Modificer...',
'UI:Menu:Delete' => 'Slet...',
'UI:Menu:BulkDelete' => 'Slet...',

View File

@@ -521,7 +521,6 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'UI:Menu:Manage' => 'Verwalten...',
'UI:Menu:EMail' => 'E-Mail',
'UI:Menu:CSVExport' => 'CSV-Export...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Modifizieren...',
'UI:Menu:Delete' => 'Löschen...',
'UI:Menu:BulkDelete' => 'Löschen...',

View File

@@ -1014,7 +1014,7 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of
'Class:SynchroAttLinkSet' => 'Synchro Attribute (Linkset)',
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Rows separator',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Attributes separator',
'Class:SynchroLog' => 'Synchro Log',
'Class:SynchroLog' => 'Synchr Log',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroLog/Attribute:start_date' => 'Start Date',
'Class:SynchroLog/Attribute:end_date' => 'End Date',

View File

@@ -543,7 +543,6 @@ Dict::Add('EN US', 'English', 'English', array(
'UI:Menu:Manage' => 'Manage...',
'UI:Menu:EMail' => 'eMail',
'UI:Menu:CSVExport' => 'CSV Export...',
'UI:Menu:OpenOQL' => 'View the OQL query',
'UI:Menu:Modify' => 'Modify...',
'UI:Menu:Delete' => 'Delete...',
'UI:Menu:BulkDelete' => 'Delete...',

View File

@@ -1001,7 +1001,7 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of
'Class:SynchroAttLinkSet' => 'Synchro Attribute (Linkset)',
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Rows separator',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Attributes separator',
'Class:SynchroLog' => 'Synchro Log',
'Class:SynchroLog' => 'Synchr Log',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroLog/Attribute:start_date' => 'Start Date',
'Class:SynchroLog/Attribute:end_date' => 'End Date',

View File

@@ -543,7 +543,6 @@ Dict::Add('EN GB', 'British English', 'British English', array(
'UI:Menu:Manage' => 'Manage...',
'UI:Menu:EMail' => 'eMail',
'UI:Menu:CSVExport' => 'CSV Export...',
'UI:Menu:OpenOQL' => 'View the OQL query',
'UI:Menu:Modify' => 'Modify...',
'UI:Menu:Delete' => 'Delete...',
'UI:Menu:BulkDelete' => 'Delete...',

View File

@@ -520,7 +520,6 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
'UI:Menu:Manage' => 'Administrar',
'UI:Menu:EMail' => 'Enviar por Correo Electrónico',
'UI:Menu:CSVExport' => 'Exportar a CSV...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Modificar',
'UI:Menu:Delete' => 'Borrar',
'UI:Menu:BulkDelete' => 'Borrar',

View File

@@ -535,7 +535,6 @@ Nous espérons que vous aimerez cette version autant que nous avons eu du plaisi
'UI:Menu:Manage' => 'Gérer...',
'UI:Menu:EMail' => 'Envoyer par eMail',
'UI:Menu:CSVExport' => 'Exporter en CSV...',
'UI:Menu:OpenOQL' => 'Voir la requête OQL',
'UI:Menu:Modify' => 'Modifier...',
'UI:Menu:Delete' => 'Supprimer...',
'UI:Menu:BulkDelete' => 'Supprimer...',

View File

@@ -524,7 +524,6 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'UI:Menu:Manage' => 'Kezelés...',
'UI:Menu:EMail' => 'Email',
'UI:Menu:CSVExport' => 'CSV exportálás...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Módosítás...',
'UI:Menu:Delete' => 'Törlés...',
'UI:Menu:BulkDelete' => 'Törlés...',

View File

@@ -524,7 +524,6 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'UI:Menu:Manage' => 'Gestisci...',
'UI:Menu:EMail' => 'eMail',
'UI:Menu:CSVExport' => 'Esporta CSV...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Modifica...',
'UI:Menu:Delete' => 'Cancella...',
'UI:Menu:BulkDelete' => 'Cancella...',

View File

@@ -525,7 +525,6 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'UI:Menu:Manage' => '管理...',
'UI:Menu:EMail' => 'Eメール',
'UI:Menu:CSVExport' => 'CSVエクスポート...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => '修正...',
'UI:Menu:Delete' => '削除...',
'UI:Menu:BulkDelete' => '削除...',

View File

@@ -521,7 +521,6 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'UI:Menu:Manage' => 'Beheer...',
'UI:Menu:EMail' => 'E-mail',
'UI:Menu:CSVExport' => 'CSV Export...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Bewerk...',
'UI:Menu:Delete' => 'Verwijder...',
'UI:Menu:BulkDelete' => 'Verwijder...',

View File

@@ -536,7 +536,6 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'UI:Menu:Manage' => 'Zarządzaj...',
'UI:Menu:EMail' => 'e-mail',
'UI:Menu:CSVExport' => 'Eksport CSV...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Zmień...',
'UI:Menu:Delete' => 'Usuń...',
'UI:Menu:BulkDelete' => 'Usuń...',

View File

@@ -519,7 +519,6 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
'UI:Menu:Manage' => 'Gerenciar...',
'UI:Menu:EMail' => 'Enviar via e-mail',
'UI:Menu:CSVExport' => 'Exportar para CSV...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Editar...',
'UI:Menu:Delete' => 'Excluir...',
'UI:Menu:BulkDelete' => 'Exclução em massa...',

View File

@@ -937,7 +937,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'Class:SynchroAttLinkSet' => 'Synchro Attribute (Linkset)~~',
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Разделитель строк',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Разделитель атрибутов',
'Class:SynchroLog' => 'Synchro Log~~',
'Class:SynchroLog' => 'Synchr Log~~',
'Class:SynchroLog/Attribute:sync_source_id' => 'Синх.исходные данные',
'Class:SynchroLog/Attribute:start_date' => 'Стартовать в',
'Class:SynchroLog/Attribute:end_date' => 'Закончить в',

View File

@@ -522,7 +522,6 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'UI:Menu:Manage' => 'Управление...',
'UI:Menu:EMail' => 'Отправить ссылку по email',
'UI:Menu:CSVExport' => 'Экспорт в CSV...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Редактировать...',
'UI:Menu:Delete' => 'Удалить...',
'UI:Menu:BulkDelete' => 'Удалить...',

View File

@@ -528,7 +528,6 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
'UI:Menu:Manage' => 'Manažovať...',
'UI:Menu:EMail' => 'eMail',
'UI:Menu:CSVExport' => 'CSV Export',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Upraviť...',
'UI:Menu:Delete' => 'Vymazať...',
'UI:Menu:BulkDelete' => 'Vymazať...',

View File

@@ -937,7 +937,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'Class:SynchroAttLinkSet' => 'Synchro niteliği (LinkSet)',
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Satır Ayırıcı',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Nitelik Ayırıcı',
'Class:SynchroLog' => 'Synchro Log',
'Class:SynchroLog' => 'Synchr log',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Veri Kaynağı',
'Class:SynchroLog/Attribute:start_date' => 'Başlangıç tarihi',
'Class:SynchroLog/Attribute:end_date' => 'Bitiş Tarihi',

View File

@@ -525,7 +525,6 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'UI:Menu:Manage' => 'Yönet...',
'UI:Menu:EMail' => 'e-posta',
'UI:Menu:CSVExport' => 'CSV olarak dışarı ver...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => 'Düzenle...',
'UI:Menu:Delete' => 'Sil...',
'UI:Menu:BulkDelete' => 'Sil...',

View File

@@ -525,7 +525,6 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'UI:Menu:Manage' => '管理...',
'UI:Menu:EMail' => '邮件',
'UI:Menu:CSVExport' => 'CSV导出...',
'UI:Menu:OpenOQL' => 'View the OQL query~~',
'UI:Menu:Modify' => '修改...',
'UI:Menu:Delete' => '删除...',
'UI:Menu:BulkDelete' => '删除...',

View File

@@ -717,11 +717,8 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
window[sPromiseId].then(function () {
$('#ac_create_'+me.id).dialog('open');
$('#ac_create_'+me.id).dialog("option", "close", me.OnCloseCreateObject);
// Modify the action of the cancel button and the close button
$('#ac_create_'+me.id+' button.cancel').off('click.navigation.itop').on('click.navigation.itop', me.CloseCreateObject);
$('.ui-dialog-titlebar:has(+ #ac_create_'+me.id+') button.ui-dialog-titlebar-close').off('click').on('click', function() {
$('#ac_create_'+me.id+' button.cancel').trigger('click');
});
// Modify the action of the cancel button
$('#ac_create_'+me.id+' button.cancel').off('click').on('click', me.CloseCreateObject);
me.ajax_request = null;
me.sTargetClass = sLocalTargetClass;
// Adjust the dialog's size to fit into the screen

View File

@@ -390,16 +390,17 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH
this.RegisterChange = function () {
// Listen only used inputs
$('#linkedset_'+me.id+' :input[name^="attr_'+me.sAttCode+'["]').off('change').on('change', function () {
$('body').off('change', '#linkedset_'+me.id+' :input[name^="attr_'+me.sAttCode+'["]')
.on('change', '#linkedset_'+me.id+' :input[name^="attr_'+me.sAttCode+'["]', function () {
if (!($(this).hasClass('selection')))
{
let oCheckbox = $(this).closest('tr').find('.selection');
let iLink = oCheckbox.attr('data-link-id');
let iUniqueId = oCheckbox.attr('data-unique-id');
let sAttCode = $(this).closest('.attribute-edit').attr('data-attcode');
let value = $(this).val();;
return me.OnValueChange(iLink, iUniqueId, sAttCode, value, this);
}
{
let oCheckbox = $(this).closest('tr').find('.selection');
let iLink = oCheckbox.attr('data-link-id');
let iUniqueId = oCheckbox.attr('data-unique-id');
let sAttCode = $(this).closest('.attribute-edit').attr('data-attcode');
let value = $(this).val();;
return me.OnValueChange(iLink, iUniqueId, sAttCode, value, this);
}
return true;
});
};

View File

@@ -369,24 +369,6 @@ function DashletCreationDlg(sOQL, sContext) {
return false;
}
function OpenOql(sOQL) {
sBaseUrl = GetAbsoluteUrlAppRoot() + 'pages/run_query.php';
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", sBaseUrl);
form.setAttribute("target", '_blank');
form.setAttribute("id", 'run_query_form');
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'expression';
input.value = sOQL;
form.appendChild(input);
document.body.appendChild(form);
// form.submit() is blocked by the browser
$('#run_query_form').submit();
document.body.removeChild(form);
}
function ShortcutListDlg(sOQL, sDataTableId, sContext) {
var sDataTableName = 'datatable_'+sDataTableId;
var oTableSettings = {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,5 @@
import { Plugin, type Editor } from 'ckeditor5/src/core.js';
import InsertCarriageReturnAfterBlock from "../insert-carriage-return-after-block/insert-carriage-return-after-block.plugin";
/**
* DetectChanges Plugin.
*
@@ -8,4 +9,5 @@ export default class DetectChanges extends Plugin {
constructor(editor: Editor);
init(): void;
static get pluginName(): string;
static get requires(): (typeof InsertCarriageReturnAfterBlock)[];
}

View File

@@ -1,6 +1,5 @@
import { Plugin } from '@ckeditor/ckeditor5-core';
export default class UpdateInputOnChange extends Plugin {
static get pluginName(): string;
private debounceTimeout;
init(): void;
}

View File

@@ -90,7 +90,7 @@ function ApplyNextAction(Webpage $oP, CMDBObject $oObj, $sNextAction)
$oAppContext = new ApplicationContext();
//echo "<p>Missing Attributes <pre>".print_r($aExpectedAttributes, true)."</pre></p>\n";
$oP->add_header('Location: '.utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=stimulus&class='.get_class($oObj).'&stimulus='.$sNextAction.'&id='.$oObj->getKey().$oAppContext->GetForLink(true));
$oP->add_header('Location: '.utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=stimulus&class='.get_class($oObj).'&stimulus='.$sNextAction.'&id='.$oObj->getKey().'&'.$oAppContext->GetForLink());
}
}
@@ -101,7 +101,7 @@ function ReloadAndDisplay($oPage, $oObj, $sMessageId = '', $sMessage = '', $sSev
{
cmdbAbstractObject::SetSessionMessage(get_class($oObj), $oObj->GetKey(), $sMessageId, $sMessage, $sSeverity, 0, true /* must not exist */);
}
$oPage->add_header('Location: '.utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class='.get_class($oObj).'&id='.$oObj->getKey().$oAppContext->GetForLink(true));
$oPage->add_header('Location: '.utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=details&class='.get_class($oObj).'&id='.$oObj->getKey().'&'.$oAppContext->GetForLink());
}
/**
@@ -993,7 +993,7 @@ try
$oForm->AddHtml($oP->GetDetails($aDetails));
$oForm->AddHtml('</td></tr></table>');
$sURL = "./UI.php?operation=search&filter=".urlencode($sFilter).$oAppContext->GetForLink(true);
$sURL = "./UI.php?operation=search&filter=".urlencode($sFilter)."&".$oAppContext->GetForLink();
$oCancelButton = ButtonUIBlockFactory::MakeForCancel(Dict::S('UI:Button:Cancel'), 'cancel', 'cancel');
$oCancelButton->SetOnClickJsCode("window.location.href='$sURL'");
$oForm->AddSubBlock($oCancelButton);
@@ -1165,7 +1165,7 @@ try
$oP->AddUiBlock($oBlock);
// Back to the list
$sURL = "./UI.php?operation=search&filter=".urlencode($sFilter).$oAppContext->GetForLink(true);
$sURL = "./UI.php?operation=search&filter=".urlencode($sFilter)."&".$oAppContext->GetForLink();
$oSubmitButton = ButtonUIBlockFactory::MakeForSecondaryAction(Dict::S('UI:Button:Done'), 'submit', 'submit', true);
$oSubmitButton->SetOnClickJsCode("window.location.href='$sURL'");
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
@@ -1520,7 +1520,7 @@ catch (Exception $e) {
$oErrorPage->add("<h1>".Dict::S('UI:FatalErrorMessage')."</h1>\n");
}
$sErrorDetails = ($e instanceof CoreException) ? $e->getHtmlDesc() : $e->getMessage();
$oErrorPage->error(Dict::Format('UI:Error_Details', utils::EscapeHtml($sErrorDetails)));
$oErrorPage->error(Dict::Format('UI:Error_Details', $sErrorDetails));
$oErrorPage->output();
$sErrorStackTrace = ($e instanceof CoreException) ? $e->getFullStackTraceAsString() : $e->getTraceAsString();
@@ -1606,7 +1606,7 @@ class UI
// Add user filter
$oFullSetFilter->UpdateContextFromUser();
$aSelectedObj = utils::ReadMultipleSelection($oFullSetFilter);
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter).$oAppContext->GetForLink(true);
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter)."&".$oAppContext->GetForLink();
$aContext = array('filter' => utils::EscapeHtml($sFilter));
cmdbAbstractObject::DisplayBulkModifyForm($oP, $sClass, $aSelectedObj, 'preview_or_modify_all', $sCancelUrl, array(), $aContext);
}
@@ -1640,7 +1640,7 @@ class UI
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'selectObj'));
}
$aSelectedObj = explode(',', $sSelectedObj);
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter).$oAppContext->GetForLink(true);
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter)."&".$oAppContext->GetForLink();
$aContext = array(
'filter' => utils::EscapeHtml($sFilter),
'selectObj' => $sSelectedObj,

View File

@@ -55,11 +55,9 @@ $oP->SetBreadCrumbEntry('ui-tool-universalsearch', Dict::S('Menu:UniversalSearch
//$sSearchHeaderForceDropdown
$sSearchHeaderForceDropdown = '<select id="select_class" name="baseClass" onChange="this.form.submit();">';
$aClassLabels = array();
foreach (MetaModel::GetClasses('bizmodel, grant_by_profile') as $sCurrentClass) {
if ((MetaModel::HasCategory($sCurrentClass, 'grant_by_profile') && UserRights::IsActionAllowed($sCurrentClass, UR_ACTION_BULK_MODIFY))
|| (MetaModel::HasCategory($sCurrentClass, 'bizmodel') && UserRights::IsActionAllowed($sCurrentClass, UR_ACTION_BULK_READ))) {
$aClassLabels[$sCurrentClass] = MetaModel::GetName($sCurrentClass);
}
foreach(MetaModel::GetClasses('bizmodel') as $sCurrentClass)
{
$aClassLabels[$sCurrentClass] = MetaModel::GetName($sCurrentClass);
}
asort($aClassLabels);
foreach($aClassLabels as $sCurrentClass => $sLabel)

View File

@@ -436,7 +436,7 @@ try
foreach ($aErrors as $aErrorRow) {
$aObjectsWithErrors[$aErrorRow['id']] = true;
}
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey().$oAppContext->GetForLink(true)."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey().$oAppContext->GetForLink(true)."\"><img src=\"" . utils::GetAbsoluteUrlAppRoot() . "images/icons/icons8-export-csv.svg\" class=\"ibo-audit--audit-line--csv-download\"></a>";
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\"><img src=\"" . utils::GetAbsoluteUrlAppRoot() . "images/icons/icons8-export-csv.svg\" class=\"ibo-audit--audit-line--csv-download\"></a>";
$aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount));
$aRow['class'] = $oAuditCategory->GetReportColor($iCount, $iErrorsCount);
}

View File

@@ -29,8 +29,9 @@ use Combodo\iTop\Application\WebPage\AjaxPage;
use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
use Combodo\iTop\Service\Import\CSVImportPageProcessor;
use Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin;
use Combodo\iTop\Renderer\BlockRenderer;
try {
require_once('../approot.inc.php');
@@ -82,24 +83,21 @@ try {
*
* @return \Combodo\iTop\Application\UI\Base\Component\Input\Select\
*/
function GetClassesSelectUIBlock(string $sName, $sDefaultValue, int $iActionCode, bool $bAdvanced = false): Select
function GetClassesSelectUIBlock(string $sName, $sDefaultValue, int $iActionCode): Select
{
$oSelectBlock = SelectUIBlockFactory::MakeForSelect($sName, 'select_'.$sName);
$oOption = SelectOptionUIBlockFactory::MakeForSelectOption("", Dict::S('UI:CSVImport:ClassesSelectOne'), false);
$oSelectBlock->AddSubBlock($oOption);
$aValidClasses = array();
$aClassCategories = array('bizmodel', 'addon/authentication');
if ($bAdvanced) {
$aClassCategories[] = 'grant_by_profile';
}
if (UserRights::IsAdministrator()) {
$aClassCategories[] = 'application';
$aClassCategories = array('bizmodel', 'application', 'addon/authentication');
}
foreach ($aClassCategories as $sClassCategory) {
foreach (MetaModel::GetClasses($sClassCategory) as $sClassName) {
if ((is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode)) &&
(!MetaModel::IsAbstract($sClassName))) {
$sDisplayName = ($bAdvanced) ? MetaModel::GetName($sClassName)." ($sClassName)" : MetaModel::GetName($sClassName);
$sDisplayName = MetaModel::GetName($sClassName);
$aValidClasses[$sDisplayName] = SelectOptionUIBlockFactory::MakeForSelectOption($sClassName, $sDisplayName, ($sClassName == $sDefaultValue));
}
}
@@ -335,7 +333,7 @@ try {
$oClassesSelect->AddSubBlock($oDefaultSelect);
$aSynchroUpdate = utils::ReadParam('synchro_update', array());
} else {
$oClassesSelect = GetClassesSelectUIBlock('class_name', $sClassName, UR_ACTION_BULK_MODIFY, (bool)$bAdvanced);
$oClassesSelect = GetClassesSelectUIBlock('class_name', $sClassName, UR_ACTION_BULK_MODIFY);
}
$oPanel = TitleUIBlockFactory::MakeForPage(Dict::S('UI:Title:CSVImportStep3'));
$oPage->AddSubBlock($oPanel);
@@ -400,7 +398,7 @@ try {
$oPage->add_ready_script(
<<<EOF
$('#select_class_name').on('change', function(ev) { DoMapping(); } );
$('#advanced').on('click', function(ev) { DoReload(); } );
$('#advanced').on('click', function(ev) { DoMapping(); } );
EOF
);
if ($sClassName != '')
@@ -418,13 +416,6 @@ EOF
var aDefaultKeys = new Array();
var aReadOnlyKeys = new Array();
function DoReload()
{
$('input[name=step]').val(3);
$('#wizForm').removeAttr('onsubmit'); // No need to perform validation checks when going back
$('#wizForm').submit();
}
function CSVGoBack()
{
$('input[name=step]').val(2);

View File

@@ -1174,7 +1174,11 @@ EOF
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink(true);
$sContext = $oAppContext->GetForLink();
if (!empty($sContext))
{
$sContext = '&'.$sContext;
}
$operation = utils::ReadParam('operation', '');
$oLayout = new PageContentWithSideContent();

View File

@@ -106,8 +106,6 @@ class DBBackup
/** @var string */
protected $sDBName;
/** @var string */
protected $sMySQLBinDir = '';
/** @var string */
protected $sDBSubName;
/**
@@ -135,6 +133,7 @@ class DBBackup
$this->sDBSubName = $oConfig->get('db_subname');
}
protected $sMySQLBinDir = '';
/**
* Create a normalized backup name, depending on the current date/time and Database
@@ -363,9 +362,8 @@ class DBBackup
}
$this->LogInfo("Starting backup of $this->sDBHost/$this->sDBName(suffix:'$this->sDBSubName')");
$sMySQLBinDir = utils::ReadParam('mysql_bindir', $this->sMySQLBinDir, true);
$sMySQLDump = $this->MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump');
$sMySQLDump = $this->GetMysqldumpCommand();
// Store the results in a temporary file
$sTmpFileName = self::EscapeShellArg($sBackupFileName);
@@ -626,22 +624,20 @@ EOF;
/**
* @return string the command to launch mysqldump (without its params)
* @throws \BackupException
*/
public static function MakeSafeMySQLCommand($sMySQLBinDir, string $sCmd)
private function GetMysqldumpCommand()
{
if (empty($sMySQLBinDir)) {
$sMySQLCommand = $sCmd;
$sMySQLBinDir = utils::ReadParam('mysql_bindir', $this->sMySQLBinDir, true);
if (empty($sMySQLBinDir))
{
$sMysqldumpCommand = 'mysqldump';
}
else {
$sMySQLBinDir = escapeshellcmd($sMySQLBinDir);
$sMySQLCommand = '"'.$sMySQLBinDir.'/$sCmd"';
if (!file_exists($sMySQLCommand)) {
throw new BackupException("$sCmd not found in $sMySQLBinDir");
}
else
{
$sMysqldumpCommand = '"'.$sMySQLBinDir.'/mysqldump"';
}
return $sMySQLCommand;
return $sMysqldumpCommand;
}
}

View File

@@ -39,7 +39,7 @@ class DOMFormatException extends Exception
* @param $previous
* @param DesignElement|null $node DOMNode causing the DOMFormatException
*/
public function __construct($message, $code = 0, $previous = null, DesignElement $node = null)
public function __construct($message, $code = null, $previous = null, DesignElement $node = null)
{
if($node !== null)
{
@@ -1826,7 +1826,7 @@ EOF;
// Search field in parent class
$oField = $this->GetFieldInParentClasses($oClass, $sStateAttCode);
if ($oField == null) {
throw new DOMFormatException("Non existing attribute '$sStateAttCode'", 0, null, $oStateAttribute);
throw new DOMFormatException("Non existing attribute '$sStateAttCode'", null, null, $oStateAttribute);
}
}
$oCodeNodes = $this->oFactory->GetNodes('values/value/code', $oField);

View File

@@ -70,7 +70,7 @@ class MFException extends Exception
*
* @inheritDoc
*/
public function __construct($message = null, $code = 0, $iSourceLineNumber = 0, $sXPath = '', $sExtraInfo = '', $previous = null)
public function __construct($message = null, $code = null, $iSourceLineNumber = 0, $sXPath = '', $sExtraInfo = '', $previous = null)
{
parent::__construct($message, $code, $previous);
$this->iSourceLineNumber = $iSourceLineNumber;
@@ -2040,7 +2040,7 @@ class MFElement extends Combodo\iTop\DesignElement
{
// Houston!
$sXPath = DesignDocument::GetItopNodePath($this);
throw new DOMFormatException("id '$key' already used in $sXPath", 0, null, $oItem);
throw new DOMFormatException("id '$key' already used in $sXPath", null, null, $oItem);
}
$res[$key] = $oItem->GetNodeAsArrayOfItems();
}

View File

@@ -40,17 +40,15 @@ class MissingDependencyException extends CoreException
<ul>
HTML;
foreach ($this->aModulesInfo as $sModuleId => $aModuleErrors) {
$sModuleLabel = utils::EscapeHtml($aModuleErrors['module']['label']);
$sModuleId = utils::EscapeHtml($sModuleId);
$sModuleLabel = $aModuleErrors['module']['label'];
$aModuleMissingDependencies = $aModuleErrors['dependencies'];
$sErrorMessage .= <<<HTML
<li><strong>$sModuleLabel</strong> ($sModuleId):
<li><strong>{$sModuleLabel}</strong> ({$sModuleId}):
<ul>
HTML;
foreach ($aModuleMissingDependencies as $sMissingModule) {
$sMissingModule = utils::EscapeHtml($sMissingModule);
$sErrorMessage .= "<li>$sMissingModule</li>";
$sErrorMessage .= "<li>{$sMissingModule}</li>";
}
$sErrorMessage .= <<<HTML
</ul>

View File

@@ -25,7 +25,7 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ModuleInstallation extends DBObject
class ModuleInstallation extends cmdbAbstractObject
{
public static function Init()
{

View File

@@ -552,15 +552,14 @@ class SetupUtils
if (empty($sMySQLBinDir) && null != MetaModel::GetConfig()) {
$sMySQLBinDir = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', '');
}
try {
$sMySQLDump = DBBackup::MakeSafeMySQLCommand($sMySQLBinDir, 'mysqldump');
} catch (Exception $e) {
$aResult[] = new CheckResult(CheckResult::ERROR, $e->getMessage());
return $aResult;
if (empty($sMySQLBinDir)) {
$sMySQLDump = 'mysqldump';
}
else {
$aResult[] = new CheckResult(CheckResult::TRACE, 'Info - Found mysql_bindir: '.$sMySQLBinDir);
$sMySQLDump = '"'.$sMySQLBinDir.'/mysqldump"';
}
if (!empty($sMySQLBinDir)) {
$aResult[] = new CheckResult(CheckResult::TRACE, 'Info - Found mysql_bindir: '.$sMySQLBinDir);
}
$sCommand = "$sMySQLDump -V 2>&1";
$aOutput = array();

View File

@@ -143,8 +143,6 @@ $sDBUser = $aDBXmlSettings['user'];
$sDBPwd = $aDBXmlSettings['pwd'];
$sDBName = $aDBXmlSettings['name'];
$sDBPrefix = $aDBXmlSettings['prefix'];
$bDBTlsEnabled = $aDBXmlSettings['db_tls_enabled'];
$sDBTlsCa = $aDBXmlSettings['db_tls_ca'];
if ($sMode == 'install')
{
@@ -221,10 +219,13 @@ if ($sMode == 'install')
die("Cleanup not implemented for a partial database (prefix= '$sDBPrefix')\nExiting.");
}
try
$oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
if ($oMysqli->connect_errno)
{
die("Cannot connect to the MySQL server (".$oMysqli->connect_errno . ") ".$oMysqli->connect_error."\nExiting");
}
else
{
$oMysqli = CMDBSource::GetMysqliInstance($sDBServer, $sDBUser, $sDBPwd, null, $bDBTlsEnabled, $sDBTlsCa, true);
if ($oMysqli->select_db($sDBName))
{
echo "Deleting database '$sDBName'\n";
@@ -235,10 +236,6 @@ if ($sMode == 'install')
echo "The database '$sDBName' does not seem to exist. Nothing to cleanup.\n";
}
}
catch (MySQLException $e)
{
die($e->getMessage()."\nExiting");
}
}
}
else
@@ -315,9 +312,9 @@ if ($bInstall)
}
else
{
try
$oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
if (!$oMysqli->connect_errno)
{
$oMysqli = CMDBSource::GetMysqliInstance($sDBServer, $sDBUser, $sDBPwd, null, $bDBTlsEnabled, $sDBTlsCa, true);
if ($oMysqli->select_db($sDBName))
{
// Check the presence of a table to record information about the MTP (from the Designer)
@@ -360,10 +357,6 @@ if ($bInstall)
}
}
}
catch (MySQLException $e)
{
// Continue anyway
}
}
}
else

View File

@@ -99,7 +99,7 @@ class DataTable extends UIContentBlock
{
$oAppContext = new ApplicationContext();
if(strpos ($sAjaxUrl,'?')) {
$this->sAjaxUrl = $sAjaxUrl.$oAppContext->GetForLink(true);
$this->sAjaxUrl = $sAjaxUrl."&".$oAppContext->GetForLink();
} else {
$this->sAjaxUrl = $sAjaxUrl."?".$oAppContext->GetForLink();
}

View File

@@ -97,7 +97,7 @@ class BlockLinkSetDisplayAsProperty extends UIContentBlock
$this->oTwigEnv = TwigHelper::GetTwigEnvironment(TwigHelper::ENUM_TEMPLATES_BASE_PATH_BACKOFFICE);
$oAppContext = new ApplicationContext();
$this->sAppContext = $oAppContext->GetForLink(true);
$this->sAppContext = $oAppContext->GetForLink();
$this->sUIPage = cmdbAbstractObject::ComputeStandardUIPage($this->sTargetClass);
}
@@ -160,7 +160,7 @@ class BlockLinkSetDisplayAsProperty extends UIContentBlock
{
return ' href="'
.utils::GetAbsoluteUrlAppRoot()
."pages/$this->sUIPage?operation=details&class=$this->sTargetClass&id=$id$this->sAppContext"
."pages/$this->sUIPage?operation=details&class=$this->sTargetClass&id=$id&$this->sAppContext"
.'" target="_self"';
}
}

View File

@@ -640,7 +640,7 @@ class AjaxRenderController
$aResult = array();
$oAppContext = new ApplicationContext();
$sParams = $oAppContext->GetForLink(true);
$sParams = $oAppContext->GetForLink();
foreach ($aGroupBy as $iRow => $iCount) {
// Build the search for this subset
$oSubsetSearch = $oFilter->DeepClone();
@@ -655,7 +655,7 @@ class AjaxRenderController
$aResult[] = array(
'group' => $aLabels[$iRow],
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>",
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1&$sParams&filter=$sFilter\">$iCount</a>",
); // TO DO: add the context information
}

View File

@@ -82,9 +82,7 @@ class ObjectController extends AbstractController
{
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
}
if (!is_subclass_of($sClass, cmdbAbstractObject::class)) {
throw new SecurityException('The class "'.$sClass.'" is not a subclass of cmdbAbstractObject so it can\'t be created by the user');
}
// If the specified class has subclasses, ask the user an instance of which class to create
$aSubClasses = MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
$aPossibleClasses = array();

View File

@@ -435,7 +435,7 @@ class EMailLaminas extends Email
// Add body content to as a new part
$oNewPart = new Part($sBody);
$oNewPart->encoding = Mime::ENCODING_BASE64;
$oNewPart->encoding = Mime::ENCODING_8BIT;
$oNewPart->type = $sMimeType;
$oNewPart->charset = 'UTF-8';
$oBody->addPart($oNewPart);
@@ -463,7 +463,7 @@ class EMailLaminas extends Email
}
$this->m_aData['parts'][] = array('text' => $sText, 'mimeType' => $sMimeType);
$oNewPart = new Part($sText);
$oNewPart->encoding = Mime::ENCODING_BASE64;
$oNewPart->encoding = Mime::ENCODING_8BIT;
$oNewPart->type = $sMimeType;
// setBody called only to refresh Content-Type to multipart/mixed

Some files were not shown because too many files have changed in this diff Show More