mirror of
https://github.com/Combodo/iTop.git
synced 2026-03-11 12:04:12 +01:00
Merge branch 'develop' into feature/faf_event_service
This commit is contained in:
@@ -36,18 +36,24 @@ clearstatcache();
|
||||
$oiTopComposer = new iTopComposer();
|
||||
$aDeniedButStillPresent = $oiTopComposer->ListDeniedButStillPresent();
|
||||
|
||||
echo "\n";
|
||||
foreach ($aDeniedButStillPresent as $sDir)
|
||||
{
|
||||
if (! preg_match('#[tT]ests?/?$#', $sDir))
|
||||
if (false === iTopComposer::IsTestDir($sDir))
|
||||
{
|
||||
echo "\nfound INVALID denied test dir: '$sDir'\n";
|
||||
echo "ERROR found INVALID denied test dir: '$sDir'\n";
|
||||
throw new \Exception("$sDir must end with /Test/ or /test/");
|
||||
}
|
||||
|
||||
if (false === file_exists($sDir)) {
|
||||
echo "INFO $sDir is in denied list, but not existing on disk => skipping !\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SetupUtils::rrmdir($sDir);
|
||||
echo "Remove denied test dir: '$sDir'\n";
|
||||
echo "OK Remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ require_once (__DIR__.DIRECTORY_SEPARATOR.'update.classes.inc.php');
|
||||
$aFilesUpdaters = array(
|
||||
new iTopVersionFileUpdater(),
|
||||
new DatamodelsModulesFiles(),
|
||||
new ConstantFileUpdater('ITOP_CORE_VERSION', 'approot.inc.php'),
|
||||
);
|
||||
|
||||
if (count($argv) === 1)
|
||||
|
||||
@@ -69,6 +69,40 @@ abstract class AbstractSingleFileVersionUpdater extends FileVersionUpdater
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°4714
|
||||
*/
|
||||
class ConstantFileUpdater extends AbstractSingleFileVersionUpdater {
|
||||
/** @var string */
|
||||
private $sConstantName;
|
||||
|
||||
/**
|
||||
* @param $sConstantName constant to search, for example `ITOP_CORE_VERSION`
|
||||
* @param $sFileToUpdate file containing constant definition
|
||||
*/
|
||||
public function __construct($sConstantName, $sFileToUpdate)
|
||||
{
|
||||
$this->sConstantName = $sConstantName;
|
||||
parent::__construct($sFileToUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
|
||||
{
|
||||
$sConstantSearchPattern = <<<REGEXP
|
||||
/define\('{$this->sConstantName}', ?'[^']+'\);/
|
||||
REGEXP;
|
||||
|
||||
return preg_replace(
|
||||
$sConstantSearchPattern,
|
||||
"define('{$this->sConstantName}', '{$sVersionLabel}');",
|
||||
$sFileContent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class iTopVersionFileUpdater extends AbstractSingleFileVersionUpdater
|
||||
{
|
||||
public function __construct()
|
||||
|
||||
@@ -10,7 +10,7 @@ define('PORTAL_PROFILE_NAME', 'Portal user');
|
||||
class UserRightsBaseClassGUI extends cmdbAbstractObject
|
||||
{
|
||||
// Whenever something changes, reload the privileges
|
||||
|
||||
|
||||
protected function AfterInsert()
|
||||
{
|
||||
UserRights::FlushPrivileges();
|
||||
@@ -59,7 +59,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
}
|
||||
|
||||
protected static $m_aCacheProfiles = null;
|
||||
|
||||
|
||||
public static function DoCreateProfile($sName, $sDescription)
|
||||
{
|
||||
if (is_null(self::$m_aCacheProfiles))
|
||||
@@ -71,7 +71,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
{
|
||||
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sCacheKey = $sName;
|
||||
if (isset(self::$m_aCacheProfiles[$sCacheKey]))
|
||||
@@ -82,10 +82,10 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
$oNewObj->Set('name', $sName);
|
||||
$oNewObj->Set('description', $sDescription);
|
||||
$iId = $oNewObj->DBInsertNoReload();
|
||||
self::$m_aCacheProfiles[$sCacheKey] = $iId;
|
||||
self::$m_aCacheProfiles[$sCacheKey] = $iId;
|
||||
return $iId;
|
||||
}
|
||||
|
||||
|
||||
function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
||||
{
|
||||
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
||||
@@ -102,7 +102,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
return '<span style="background-color: #ffdddd;">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function DoShowGrantSumary($oPage)
|
||||
{
|
||||
if ($this->GetRawName() == "Administrator")
|
||||
@@ -114,7 +114,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
|
||||
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
||||
$oUserRights = UserRights::GetModuleInstance();
|
||||
|
||||
|
||||
$aDisplayData = array();
|
||||
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass)
|
||||
{
|
||||
@@ -123,12 +123,12 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
{
|
||||
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||
if ($bGrant === true)
|
||||
{
|
||||
{
|
||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.htmlentities($oStimulus->GetDescription(), ENT_QUOTES, 'UTF-8').'">'.htmlentities($oStimulus->GetLabel(), ENT_QUOTES, 'UTF-8').'</span>';
|
||||
}
|
||||
}
|
||||
$sStimuli = implode(', ', $aStimuli);
|
||||
|
||||
|
||||
$aDisplayData[] = array(
|
||||
'class' => MetaModel::GetName($sClass),
|
||||
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
||||
@@ -140,7 +140,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
'stimuli' => $sStimuli,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$aDisplayConfig = array();
|
||||
$aDisplayConfig['class'] = array('label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+'));
|
||||
$aDisplayConfig['read'] = array('label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+'));
|
||||
@@ -198,7 +198,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
* @param $aReasons array To store the reasons why the attribute is read-only (info about the synchro replicas)
|
||||
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
||||
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
||||
*/
|
||||
*/
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||
{
|
||||
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
@@ -404,7 +404,7 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
||||
{
|
||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
||||
|
||||
$oUser = UserRights::GetUserObject();
|
||||
$oUser = UserRights::GetUserObject();
|
||||
$oAddon = UserRights::GetModuleInstance();
|
||||
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
||||
if (count($aOrgs) > 0)
|
||||
@@ -528,7 +528,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
$oSearch->AllowAllData();
|
||||
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
||||
$oSearch->AddConditionExpression($oCondition);
|
||||
|
||||
|
||||
$oUserOrgSet = new DBObjectSet($oSearch, array(), array('userid' => $iUser));
|
||||
while ($oUserOrg = $oUserOrgSet->Fetch())
|
||||
{
|
||||
@@ -738,8 +738,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
// load and cache permissions for the current user on the given class
|
||||
//
|
||||
$iUser = $oUser->GetKey();
|
||||
$aTest = @$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
||||
if (is_array($aTest)) return $aTest;
|
||||
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])){
|
||||
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
||||
if (is_array($aTest)) return $aTest;
|
||||
}
|
||||
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
@@ -905,8 +907,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
|
||||
/**
|
||||
* Find out which attribute is corresponding the the dimension 'owner org'
|
||||
* returns null if no such attribute has been found (no filtering should occur)
|
||||
*/
|
||||
* returns null if no such attribute has been found (no filtering should occur)
|
||||
*/
|
||||
public static function GetOwnerOrganizationAttCode($sClass)
|
||||
{
|
||||
$sAttCode = null;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/AjaxPage.php, now loadable using autoloader');
|
||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader');
|
||||
|
||||
/**
|
||||
* Class ajax_page
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CLIPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/CLIPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');
|
||||
@@ -62,11 +62,11 @@ require_once(APPROOT.'application/ui.linksdirectwidget.class.inc.php');
|
||||
require_once(APPROOT.'application/ui.passwordwidget.class.inc.php');
|
||||
require_once(APPROOT.'application/ui.extkeywidget.class.inc.php');
|
||||
require_once(APPROOT.'application/ui.htmleditorwidget.class.inc.php');
|
||||
require_once(APPROOT.'sources/application/search/searchform.class.inc.php');
|
||||
require_once(APPROOT.'sources/application/search/criterionparser.class.inc.php');
|
||||
require_once(APPROOT.'sources/application/search/criterionconversionabstract.class.inc.php');
|
||||
require_once(APPROOT.'sources/application/search/criterionconversion/criteriontooql.class.inc.php');
|
||||
require_once(APPROOT.'sources/application/search/criterionconversion/criteriontosearchform.class.inc.php');
|
||||
require_once(APPROOT.'sources/Application/Search/searchform.class.inc.php');
|
||||
require_once(APPROOT.'sources/Application/Search/criterionparser.class.inc.php');
|
||||
require_once(APPROOT.'sources/Application/Search/criterionconversionabstract.class.inc.php');
|
||||
require_once(APPROOT.'sources/Application/Search/CriterionConversion/criteriontooql.class.inc.php');
|
||||
require_once(APPROOT.'sources/Application/Search/CriterionConversion/criteriontosearchform.class.inc.php');
|
||||
|
||||
/**
|
||||
* Class cmdbAbstractObject
|
||||
@@ -393,7 +393,8 @@ JS
|
||||
$oSingletonFilter = new DBObjectSearch(get_class($this));
|
||||
$oSingletonFilter->AddCondition('id', $this->GetKey(), '=');
|
||||
$oBlock = new MenuBlock($oSingletonFilter, 'details', false);
|
||||
$oActionMenuBlock = $oBlock->GetRenderContent($oPage);
|
||||
$sActionMenuId = utils::Sanitize(uniqid('', true), '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
$oActionMenuBlock = $oBlock->GetRenderContent($oPage, [], $sActionMenuId);
|
||||
$aHeaderBlocks['toolbar'][$oActionMenuBlock->GetId()] = $oActionMenuBlock;
|
||||
}
|
||||
|
||||
@@ -510,32 +511,6 @@ HTML
|
||||
return $aHeaderBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display history tab of an object
|
||||
*
|
||||
* @deprecated 3.0.0 will be removed in 3.1, see N°3824
|
||||
*
|
||||
* @param bool $bEditMode
|
||||
* @param int $iLimitCount
|
||||
* @param int $iLimitStart
|
||||
*
|
||||
* @param \WebPage $oPage
|
||||
*
|
||||
* @throws \CoreException
|
||||
*
|
||||
*/
|
||||
public function DisplayBareHistory(WebPage $oPage, $bEditMode = false, $iLimitCount = 0, $iLimitStart = 0)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod();
|
||||
// history block (with as a tab)
|
||||
$oHistoryFilter = new DBObjectSearch('CMDBChangeOp');
|
||||
$oHistoryFilter->AddCondition('objkey', $this->GetKey(), '=');
|
||||
$oHistoryFilter->AddCondition('objclass', get_class($this), '=');
|
||||
$oBlock = new HistoryBlock($oHistoryFilter, 'table', false);
|
||||
$oBlock->SetLimit($iLimitCount, $iLimitStart);
|
||||
$oBlock->Display($oPage, 'history');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display properties tab of an object
|
||||
*
|
||||
@@ -651,11 +626,17 @@ HTML
|
||||
if ($oAttDef instanceof AttributeDashboard) {
|
||||
if (!$this->IsNew()) {
|
||||
$sHostContainerInEditionUrlParam = ($bEditMode) ? '&host_container_in_edition=true' : '';
|
||||
$oPage->AddAjaxTab($oAttDef->GetLabel(),
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=dashboard&class='.get_class($this).'&id='.$this->GetKey().'&attcode='.$oAttDef->GetCode().$sHostContainerInEditionUrlParam,
|
||||
true,
|
||||
$oPage->AddAjaxTab(
|
||||
'Class:'.$sClass.'/Attribute:'.$sAttCode,
|
||||
AjaxTab::ENUM_TAB_PLACEHOLDER_DASHBOARD);
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=dashboard&class='
|
||||
.get_class($this)
|
||||
.'&id='.$this->GetKey()
|
||||
.'&attcode='.$oAttDef->GetCode()
|
||||
.$sHostContainerInEditionUrlParam,
|
||||
true,
|
||||
$oAttDef->GetLabel(),
|
||||
AjaxTab::ENUM_TAB_PLACEHOLDER_DASHBOARD
|
||||
);
|
||||
// Add graphs dependencies
|
||||
WebResourcesHelper::EnableC3JSToWebPage($oPage);
|
||||
}
|
||||
@@ -1181,8 +1162,6 @@ HTML
|
||||
$oPage->SetCurrentTab('UI:PropertiesTab');
|
||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||
$this->DisplayBareRelations($oPage, $bEditMode);
|
||||
// TODO 3.0.0: What to do with this?
|
||||
//$this->DisplayBareHistory($oPage, $bEditMode);
|
||||
|
||||
// Note: Adding the JS snippet which enables the image upload should have been done directly by the ActivityPanel which would have kept the independance principle
|
||||
// of the UIBlock. For now we keep it this way in order to move on and trace this known limitation in N°3736.
|
||||
@@ -1741,6 +1720,9 @@ HTML
|
||||
* @param array $aParams
|
||||
*
|
||||
* @throws \Exception
|
||||
* only used in old and deprecated export.php
|
||||
*
|
||||
* @internal Only to be used by `/webservices/export.php` : this is a legacy method that produces wrong HTML (no TR on table body rows)
|
||||
*/
|
||||
public static function DisplaySetAsHTMLSpreadsheet(WebPage $oPage, CMDBObjectSet $oSet, $aParams = array())
|
||||
{
|
||||
@@ -1761,6 +1743,8 @@ HTML
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \Exception
|
||||
*
|
||||
* @internal Only to be used by `/webservices/export.php` : this is a legacy method that produces wrong HTML (no TR on table body rows)
|
||||
*/
|
||||
public static function GetSetAsHTMLSpreadsheet(DBObjectSet $oSet, $aParams = array())
|
||||
{
|
||||
@@ -4233,13 +4217,20 @@ HTML;
|
||||
if (!is_null($oImage->GetData()))
|
||||
{
|
||||
$aSize = utils::GetImageSize($oImage->GetData());
|
||||
$oImage = utils::ResizeImageToFit(
|
||||
$oImage,
|
||||
$aSize[0],
|
||||
$aSize[1],
|
||||
$oAttDef->Get('storage_max_width'),
|
||||
$oAttDef->Get('storage_max_height')
|
||||
);
|
||||
if (is_array($aSize) && $aSize[0] > 0 && $aSize[1] > 0)
|
||||
{
|
||||
$oImage = utils::ResizeImageToFit(
|
||||
$oImage,
|
||||
$aSize[0],
|
||||
$aSize[1],
|
||||
$oAttDef->Get('storage_max_width'),
|
||||
$oAttDef->Get('storage_max_height')
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
IssueLog::Warning($sClass . ':' . $this->GetKey() . '/' . $sAttCode . ': Image could not be resized. Mimetype: ' . $oImage->GetMimeType() . ', filename: ' . $oImage->GetFileName());
|
||||
}
|
||||
}
|
||||
$aOtherData = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
||||
if (is_array($aOtherData))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/CSVPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/CSVPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');
|
||||
@@ -583,7 +583,7 @@ JS
|
||||
$oPage->add('<div id="select_dashlet" class="ibo-dashboard--available-dashlets--list" data-role="ibo-dashboard--available-dashlets--list">');
|
||||
$aAvailableDashlets = $this->GetAvailableDashlets();
|
||||
foreach ($aAvailableDashlets as $sDashletClass => $aInfo) {
|
||||
$oPage->add('<span dashlet_class="'.$sDashletClass.'" class="ibo-dashboard-editor--available-dashlet-icon dashlet_icon ui-widget-content ui-corner-all" data-role="ibo-dashboard-editor--available-dashlet-icon" id="dashlet_'.$sDashletClass.'" title="'.$aInfo['label'].'"><img src="'.$sUrl.$aInfo['icon'].'" /></span>');
|
||||
$oPage->add('<span dashlet_class="'.$sDashletClass.'" class="ibo-dashboard-editor--available-dashlet-icon dashlet_icon ui-widget-content ui-corner-all" data-role="ibo-dashboard-editor--available-dashlet-icon" id="dashlet_'.$sDashletClass.'" data-tooltip-content="'.$aInfo['label'].'" title="'.$aInfo['label'].'"><img src="'.$sUrl.$aInfo['icon'].'" /></span>');
|
||||
}
|
||||
$oPage->add('</div>');
|
||||
|
||||
@@ -1066,11 +1066,11 @@ EOF
|
||||
dashboard.html(data);
|
||||
dashboard.unblock();
|
||||
if ($('#ibo-dashboard-selector$sDivId input').prop("checked")) {
|
||||
$('#ibo-dashboard-selector$sDivId').data('tooltip-content', '$sSwitchToStandard');
|
||||
$('#ibo-dashboard-selector$sDivId').attr('data-tooltip-content', '$sSwitchToStandard');
|
||||
} else {
|
||||
$('#ibo-dashboard-selector$sDivId').data('tooltip-content', '$sSwitchToCustom');
|
||||
$('#ibo-dashboard-selector$sDivId').attr('data-tooltip-content', '$sSwitchToCustom');
|
||||
}
|
||||
CombodoTooltip.InitAllNonInstantiatedTooltips($('#ibo-dashboard-selector$sDivId').parent());
|
||||
CombodoTooltip.InitAllNonInstantiatedTooltips($('#ibo-dashboard-selector$sDivId').parent(), true);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -539,8 +539,10 @@ class DisplayBlock
|
||||
* @throws DictExceptionMissingString
|
||||
* @throws MySQLException
|
||||
* @throws Exception
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 add type hinting to $aExtraParams
|
||||
*/
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams = [], string $sId = null)
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
||||
{
|
||||
$sHtml = '';
|
||||
$oBlock = null;
|
||||
@@ -853,7 +855,7 @@ JS
|
||||
{
|
||||
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
||||
$sOQLCondition = $oField->Render()." IN $sListExpr";
|
||||
$sOQLCondition = $oField->RenderExpression()." IN $sListExpr";
|
||||
$oNewCondition = Expression::FromOQL($sOQLCondition);
|
||||
return $oNewCondition;
|
||||
}
|
||||
@@ -1052,6 +1054,11 @@ JS
|
||||
$oBlock->AddSubBlock($oPill);
|
||||
}
|
||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||
if(isset($aExtraParams['query_params']['this->object()'])){
|
||||
$aExtraParams['query_params']['this->class'] = get_class($aExtraParams['query_params']['this->object()']);
|
||||
$aExtraParams['query_params']['this->id'] = $aExtraParams['query_params']['this->object()']->GetKey();
|
||||
unset($aExtraParams['query_params']['this->object()']);
|
||||
}
|
||||
$aRefreshParams = ['filter' => $this->m_oFilter->ToOQL(), "extra_params" => json_encode($aExtraParams)];
|
||||
$oBlock->SetJSRefresh(
|
||||
"$('#".$oBlock->GetId()."').block();
|
||||
@@ -1698,145 +1705,6 @@ JS
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to manage 'blocks' of HTML pieces that are parts of a page and contain some list of cmdb objects
|
||||
*
|
||||
* Each block is actually rendered as a <div></div> tag that can be rendered synchronously
|
||||
* or as a piece of Javascript/JQuery/Ajax that will get its content from another page (ajax.render.php).
|
||||
* The list of cmdbObjects to be displayed into the block is defined by a filter
|
||||
* Right now the type of display is either: list, count or details
|
||||
* - list produces a table listing the objects
|
||||
* - count produces a paragraphs with a sentence saying 'cont' objects found
|
||||
* - details display (as table) the details of each object found (best if only one)
|
||||
*
|
||||
* @deprecated 3.0.0 will be removed in 3.1, see N°3824
|
||||
*/
|
||||
class HistoryBlock extends DisplayBlock
|
||||
{
|
||||
protected $iLimitCount;
|
||||
protected $iLimitStart;
|
||||
|
||||
public function __construct(DBSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod();
|
||||
parent::__construct($oFilter, $sStyle, $bAsynchronous, $aParams, $oSet);
|
||||
$this->iLimitStart = 0;
|
||||
$this->iLimitCount = 0;
|
||||
}
|
||||
|
||||
public function SetLimit($iCount, $iStart = 0)
|
||||
{
|
||||
$this->iLimitStart = $iStart;
|
||||
$this->iLimitCount = $iCount;
|
||||
}
|
||||
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams = [], string $sId = null)
|
||||
{
|
||||
$sHtml = '';
|
||||
$bTruncated = false;
|
||||
$oSet = new CMDBObjectSet($this->m_oFilter, array('date' => false));
|
||||
if (!$oPage->IsPrintableVersion()) {
|
||||
if (($this->iLimitStart > 0) || ($this->iLimitCount > 0)) {
|
||||
$oSet->SetLimit($this->iLimitCount, $this->iLimitStart);
|
||||
if (($this->iLimitCount - $this->iLimitStart) < $oSet->Count()) {
|
||||
$bTruncated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHtml .= "<!-- filter: ".($this->m_oFilter->ToOQL())."-->\n";
|
||||
switch ($this->m_sStyle) {
|
||||
case 'toggle':
|
||||
// First the latest change that the user is allowed to see
|
||||
do {
|
||||
$oLatestChangeOp = $oSet->Fetch();
|
||||
} while (is_object($oLatestChangeOp) && ($oLatestChangeOp->GetDescription() == ''));
|
||||
|
||||
if (is_object($oLatestChangeOp)) {
|
||||
// There is one change in the list... only when the object has been created !
|
||||
$sDate = $oLatestChangeOp->GetAsHTML('date');
|
||||
$oChange = MetaModel::GetObject('CMDBChange', $oLatestChangeOp->Get('change'));
|
||||
$sUserInfo = $oChange->GetAsHTML('userinfo');
|
||||
$sHtml .= $oPage->GetStartCollapsibleSection(Dict::Format('UI:History:LastModified_On_By', $sDate, $sUserInfo));
|
||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
||||
$sHtml .= $oPage->GetEndCollapsibleSection();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'table':
|
||||
default:
|
||||
if ($bTruncated)
|
||||
{
|
||||
$sFilter = htmlentities($this->m_oFilter->serialize(), ENT_QUOTES, 'UTF-8');
|
||||
$sHtml .= '<div id="history_container"><p>';
|
||||
$sHtml .= Dict::Format('UI:TruncatedResults', $this->iLimitCount, $oSet->Count());
|
||||
$sHtml .= ' ';
|
||||
$sHtml .= '<a href="#" onclick="DisplayHistory(\'#history_container\', \''.$sFilter.'\', 0, 0); return false;">'.Dict::S('UI:DisplayAll').'</a>';
|
||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
||||
$sHtml .= '</p></div>';
|
||||
$oPage->add_ready_script("$('#{$sId} table.listResults tr:last td').addClass('truncated');");
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
||||
}
|
||||
$oPage->add_ready_script(InlineImage::FixImagesWidth());
|
||||
|
||||
$oPage->add_ready_script("$('.case-log-history-entry-toggle').on('click', function () { $(this).closest('.case-log-history-entry').toggleClass('expanded');});");
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('.history_entry').each(function() {
|
||||
var jMe = $(this);
|
||||
var oContent = $(this).find('.history_html_content');
|
||||
if (jMe.height() < oContent.height())
|
||||
{
|
||||
jMe.prepend('<span class="history_truncated_toggler"></span>');
|
||||
jMe.find('.history_truncated_toggler').on('click', function() {
|
||||
jMe.toggleClass('history_entry_truncated');
|
||||
});
|
||||
}
|
||||
});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
return new Html($sHtml);
|
||||
}
|
||||
|
||||
protected function GetHistoryTable(WebPage $oPage, DBObjectSet $oSet)
|
||||
{
|
||||
$sHtml = '';
|
||||
// First the latest change that the user is allowed to see
|
||||
$oSet->Rewind(); // Reset the pointer to the beginning of the set
|
||||
$aChanges = array();
|
||||
while($oChangeOp = $oSet->Fetch())
|
||||
{
|
||||
$sChangeDescription = $oChangeOp->GetDescription();
|
||||
if ($sChangeDescription != '')
|
||||
{
|
||||
// The change is visible for the current user
|
||||
$changeId = $oChangeOp->Get('change');
|
||||
$aChanges[$changeId]['date'] = $oChangeOp->Get('date');
|
||||
$aChanges[$changeId]['userinfo'] = $oChangeOp->Get('userinfo');
|
||||
if (!isset($aChanges[$changeId]['log']))
|
||||
{
|
||||
$aChanges[$changeId]['log'] = array();
|
||||
}
|
||||
$aChanges[$changeId]['log'][] = $sChangeDescription;
|
||||
}
|
||||
}
|
||||
$aAttribs = array('date' => array('label' => Dict::S('UI:History:Date'), 'description' => Dict::S('UI:History:Date+')),
|
||||
'userinfo' => array('label' => Dict::S('UI:History:User'), 'description' => Dict::S('UI:History:User+')),
|
||||
'log' => array('label' => Dict::S('UI:History:Changes') , 'description' => Dict::S('UI:History:Changes+')),
|
||||
);
|
||||
$aValues = array();
|
||||
foreach($aChanges as $aChange)
|
||||
{
|
||||
$aValues[] = array('date' => AttributeDateTime::GetFormat()->Format($aChange['date']), 'userinfo' => htmlentities($aChange['userinfo'], ENT_QUOTES, 'UTF-8'), 'log' => "<ul><li>".implode('</li><li>', $aChange['log'])."</li></ul>");
|
||||
}
|
||||
$sHtml .= $oPage->GetTable($aAttribs, $aValues);
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the 'Actions' menu for a given (list of) object(s)
|
||||
* The 'style' of the list (see constructor of DisplayBlock) can be either 'list' or 'details'
|
||||
@@ -1871,11 +1739,10 @@ class MenuBlock extends DisplayBlock
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value and add type hinting on $aExtraParams for PHP 8.0 compatibility
|
||||
*/
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams = [], string $sId = null)
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
||||
{
|
||||
$oRenderBlock = new UIContentBlock();
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/ErrorPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWebPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
// cannot notify depreciation for now as this is still MASSIVELY used in iTop core !
|
||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/iTopWebPage.php, now loadable using autoloader');
|
||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader');
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader');
|
||||
@@ -490,6 +490,7 @@ class LoginWebPage extends NiceWebPage
|
||||
{
|
||||
EventService::FireEvent(EventName::LOGIN, null, array('code' => $iErrorCode, 'state' => $sLoginState));
|
||||
}
|
||||
Session::WriteClose();
|
||||
return $iErrorCode; // Asked to exit FSM, generally login OK
|
||||
}
|
||||
if ($iResponse == self::LOGIN_FSM_ERROR)
|
||||
|
||||
@@ -77,17 +77,28 @@ function _MaintenanceHtmlMessage($sMessage)
|
||||
*/
|
||||
function _MaintenanceJsonMessage($sTitle, $sMessage)
|
||||
{
|
||||
@include_once(APPROOT."/application/ajaxwebpage.class.inc.php");
|
||||
if (class_exists('ajax_page'))
|
||||
if (class_exists('JsonPage'))
|
||||
{
|
||||
$oP = new ajax_page($sTitle);
|
||||
$oP = new JsonPage($sTitle);
|
||||
$oP->add_header('Access-Control-Allow-Origin: *');
|
||||
$oP->SetContentType('application/json');
|
||||
$oP->add('{"code":100, "message":"'.$sMessage.'"}');
|
||||
|
||||
$aMessage = [
|
||||
'code' => 100,
|
||||
'message' =>$sMessage
|
||||
];
|
||||
|
||||
$oP->AddData($aMessage);
|
||||
$oP->Output();
|
||||
}
|
||||
else
|
||||
{
|
||||
_MaintenanceTextMessage($sMessage);
|
||||
} else {
|
||||
@include_once(APPROOT."/application/ajaxwebpage.class.inc.php");
|
||||
if (class_exists('ajax_page')) {
|
||||
$oP = new ajax_page($sTitle);
|
||||
$oP->add_header('Access-Control-Allow-Origin: *');
|
||||
$oP->SetContentType('application/json');
|
||||
$oP->add('{"code":100, "message":"'.$sMessage.'"}');
|
||||
$oP->Output();
|
||||
} else {
|
||||
_MaintenanceTextMessage($sMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\Helper\WebResourcesHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Title\Title;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
@@ -1126,16 +1127,20 @@ class OQLMenuNode extends MenuNode
|
||||
{
|
||||
$sUsageId = utils::GetSafeId($sUsageId);
|
||||
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||
|
||||
$sClass= $oSearch->GetClass();
|
||||
$sIcon = MetaModel::GetClassIcon($sClass, false);
|
||||
if ($bSearchPane) {
|
||||
$aParams = array_merge(['open' => $bSearchOpen, 'table_id' => $sUsageId, 'submit_on_load' => false], $aExtraParams);
|
||||
$oBlock = new DisplayBlock($oSearch, 'search', false /* Asynchronous */, $aParams);
|
||||
$oBlock->Display($oPage, 0);
|
||||
$oPage->add("<div class='sf_results_area ibo-add-margin-top-250' data-target='search_results'>");
|
||||
}
|
||||
|
||||
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
||||
$oTitle = TitleUIBlockFactory::MakeForPage($sTitle);
|
||||
$oPage->AddUiBlock($oTitle);
|
||||
else {
|
||||
$oPage->add("<div class='sf_results_area' data-target='search_results'>");
|
||||
}
|
||||
$aExtraParams['panel_class'] =$sClass;
|
||||
$aExtraParams['panel_title'] = $sTitle;
|
||||
$aExtraParams['panel_icon'] = $sIcon;
|
||||
|
||||
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
|
||||
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/NiceWebPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader');
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/PDFPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/PDFPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader');
|
||||
@@ -18,8 +18,7 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Field\Field;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Field\FieldUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Input\TextArea;
|
||||
|
||||
@@ -51,6 +50,7 @@ abstract class Query extends cmdbAbstractObject
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "description",
|
||||
@@ -68,6 +68,41 @@ abstract class Query extends cmdbAbstractObject
|
||||
'display_style' => 'radio_horizontal',
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("export_count", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "export_count",
|
||||
"default_value" => 0,
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
|
||||
"allowed_values" => null,
|
||||
"sql" => "export_last_date",
|
||||
"default_value" => null,
|
||||
"is_null_allowed" => true,
|
||||
"depends_on" => array(),
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
|
||||
array(
|
||||
"targetclass"=>'User',
|
||||
"allowed_values"=>null,
|
||||
"sql"=>'user_id',
|
||||
"is_null_allowed"=>true,
|
||||
"depends_on"=>array(),
|
||||
"display_style"=>'select',
|
||||
"always_load_in_tables"=>false,
|
||||
"on_target_delete"=>DEL_SILENT
|
||||
)));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
|
||||
array(
|
||||
"allowed_values"=>null,
|
||||
"extkey_attcode"=> "export_last_user_id",
|
||||
"target_attcode"=>"contactid"
|
||||
)));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details',
|
||||
array('name', 'is_template', 'description')); // Attributes to be displayed for the complete details
|
||||
@@ -78,6 +113,54 @@ abstract class Query extends cmdbAbstractObject
|
||||
array('name', 'description', 'is_template')); // Criteria of the default search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||
{
|
||||
// read only attribute
|
||||
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])){
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return export url.
|
||||
*
|
||||
* @param array|null $aValues optional values for the query
|
||||
*
|
||||
* @return string|null
|
||||
* @since 3.1.0
|
||||
*/
|
||||
abstract public function GetExportUrl(array $aValues = null) : ?string;
|
||||
|
||||
/**
|
||||
* Update last export information.
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public function UpdateLastExportInformation() : void
|
||||
{
|
||||
// last export information
|
||||
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
|
||||
$this->Set('export_last_user_id', UserRights::GetUserObject());
|
||||
$this->DBUpdate();
|
||||
|
||||
// increment usage counter
|
||||
$this->DBIncrement('export_count');
|
||||
}
|
||||
}
|
||||
|
||||
class QueryOQL extends Query
|
||||
@@ -116,13 +199,51 @@ class QueryOQL extends Query
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details',
|
||||
array('name', 'is_template', 'description', 'oql', 'fields')); // Attributes to be displayed for the complete details
|
||||
array(
|
||||
'col:col1' => array('fieldset:Query:baseinfo' => array('name', 'is_template', 'description', 'oql', 'fields')),
|
||||
'col:col2' => array('fieldset:Query:exportInfo' => array('export_count', 'export_last_date', 'export_last_user_id', 'export_last_user_contact'))
|
||||
)
|
||||
); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search',
|
||||
array('name', 'description', 'is_template', 'fields', 'oql')); // Criteria of the std search form
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function GetExportUrl(array $aValues = null) : ?string
|
||||
{
|
||||
try{
|
||||
// retrieve attributes
|
||||
$sFields = trim($this->Get('fields'));
|
||||
$sOql = $this->Get('oql');
|
||||
|
||||
// construct base url depending on version
|
||||
$bExportV1Recommended = ($sFields == '');
|
||||
if ($bExportV1Recommended) {
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?format=spreadsheet&login_mode=basic&query='.$this->GetKey();
|
||||
}
|
||||
else{
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'webservices/export-v2.php?format=spreadsheet&login_mode=basic&date_format='.urlencode((string)AttributeDateTime::GetFormat()).'&query='.$this->GetKey();
|
||||
}
|
||||
|
||||
// search object from OQL
|
||||
$oSearch = DBObjectSearch::FromOQL($sOql);
|
||||
|
||||
// inject parameters
|
||||
$aParameters = $oSearch->GetQueryParams();
|
||||
foreach ($aParameters as $sParam => $val) {
|
||||
$paramValue = ($aValues === null || $aValues[$sParam] === null) ? $sParam : $aValues[$sParam];
|
||||
$sUrl .= '&arg_' . $sParam . '=' . $paramValue;
|
||||
}
|
||||
|
||||
return $sUrl;
|
||||
}
|
||||
catch(Exception $e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
{
|
||||
$aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
|
||||
@@ -152,9 +273,11 @@ class QueryOQL extends Query
|
||||
$sUrl .= '&arg_'.$sParam.'=["'.$sParam.'"]';
|
||||
}
|
||||
|
||||
// add text area inside field set
|
||||
$oFieldSet = FieldSetUIBlockFactory::MakeStandard(Dict::S('UI:Query:UrlForExcel'));
|
||||
$oTextArea = new TextArea("", $sUrl, null, 80, 3);
|
||||
$oFieldUrl = FieldUIBlockFactory::MakeFromObject(Dict::S('UI:Query:UrlForExcel'), $oTextArea, Field::ENUM_FIELD_LAYOUT_LARGE);
|
||||
$oPage->AddSubBlock($oFieldUrl);
|
||||
$oFieldSet->AddSubBlock($oTextArea);
|
||||
$oPage->AddSubBlock($oFieldSet);
|
||||
|
||||
if (count($aParameters) == 0) {
|
||||
$oBlock = new DisplayBlock($oSearch, 'list');
|
||||
@@ -178,6 +301,7 @@ class QueryOQL extends Query
|
||||
return $aFieldsMap;
|
||||
}
|
||||
|
||||
|
||||
// Rolled back until 'fields' can be properly managed by AttributeQueryAttCodeSet
|
||||
//
|
||||
// public function ComputeValues()
|
||||
|
||||
@@ -288,7 +288,8 @@ class ShortcutOQL extends Shortcut
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
// Note: the title gets deleted by the validation mechanism
|
||||
$("#attr_auto_reload_sec").tooltip({items: 'input', content: '$sRateTitle'});
|
||||
$("#attr_auto_reload_sec").attr('data-tooltip-content', '$sRateTitle');
|
||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
||||
|
||||
$('#attr_auto_reload').change( function(ev) {
|
||||
|
||||
@@ -66,7 +66,6 @@ register_shutdown_function(function()
|
||||
});
|
||||
$oKPI = new ExecutionKPI();
|
||||
Session::Start();
|
||||
Session::WriteClose();
|
||||
$oKPI->ComputeAndReport("Session Start");
|
||||
|
||||
$sSwitchEnv = utils::ReadParam('switch_env', null);
|
||||
|
||||
@@ -234,7 +234,6 @@ class DisplayTemplate
|
||||
$sTemplate = '<div class="page_header">
|
||||
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $id$ AND objclass = \'$class$\'</itopblock>
|
||||
</div>
|
||||
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||
<itoptabs>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<div class="page_header">
|
||||
<itopblock blockclass="MenuBlock" type="popup" encoding="text/oql" label="Actions">SELECT $class$ WHERE id = $id$</itopblock>
|
||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||
<itopblock blockclass="HistoryBlock" type="toggle" encoding="text/oql">SELECT CMDBChangeOp WHERE objkey = $id$ AND objclass = '$class$'</itopblock>
|
||||
</div>
|
||||
<img src="../../images/clean.png" style="margin-top:-20px; margin-right:10px; float:right">
|
||||
<itopblock blockclass="DisplayBlock" asynchronous="false" type="bare_details" encoding="text/oql">SELECT $class$ WHERE id = $id$</itopblock>
|
||||
|
||||
@@ -29,7 +29,7 @@ class ThemeHandlerService
|
||||
{
|
||||
}
|
||||
|
||||
public function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null){
|
||||
return ThemeHandler::CompileTheme($sThemeId, $bSetup, $sSetupCompilationTimestamp="", $aThemeParameters, $aImportsPaths, $sWorkingPath);
|
||||
public function CompileTheme($sThemeId, $bSetup = false, $sSetupCompilationTimestamp = "", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null){
|
||||
return ThemeHandler::CompileTheme($sThemeId, $bSetup, $sSetupCompilationTimestamp, $aThemeParameters, $aImportsPaths, $sWorkingPath);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Combodo\iTop;
|
||||
|
||||
use AttributeDate;
|
||||
use AttributeDateTime;
|
||||
use Dict;
|
||||
use Exception;
|
||||
@@ -55,6 +56,10 @@ class TwigExtension
|
||||
{
|
||||
return AttributeDateTime::GetFormat()->Format($sDate);
|
||||
}
|
||||
if (preg_match('@^\d\d\d\d-\d\d-\d\d$@', trim($sDate)))
|
||||
{
|
||||
return AttributeDate::GetFormat()->Format($sDate);
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,8 @@ class UIExtKeyWidget
|
||||
protected $sAttCode;
|
||||
protected $bSearchMode;
|
||||
|
||||
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param string $sAttCode
|
||||
@@ -80,18 +82,13 @@ class UIExtKeyWidget
|
||||
* @throws \Exception
|
||||
*
|
||||
* @since 3.0.0 N°3750 new $sInputType parameter
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Add default value for $aArgs for PHP 8.0 compat
|
||||
*/
|
||||
public static function DisplayFromAttCode(
|
||||
$oPage, $sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName = '', $sFormPrefix = '',
|
||||
$aArgs = [], $bSearchMode = false, &$sInputType = ''
|
||||
)
|
||||
{
|
||||
// we will only use key & name, so let's reduce fields loaded !
|
||||
$aAttToLoad = [
|
||||
$sClass => [], // nothing, id and friendlyname are automatically added by the API
|
||||
];
|
||||
$oAllowedValues->OptimizeColumnLoad($aAttToLoad);
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sTargetClass = $oAttDef->GetTargetClass();
|
||||
$iMaxComboLength = $oAttDef->GetMaximumComboLength();
|
||||
@@ -254,7 +251,7 @@ class UIExtKeyWidget
|
||||
$aOption['picture_url'] = $oImage->GetDisplayURL($sClassAllowed, $oObj->GetKey(), $sObjectImageAttCode);
|
||||
$aOption['initials'] = '';
|
||||
} else {
|
||||
$aOption['initials'] = utils::ToAcronym($oObj->Get('friendlyname'));
|
||||
$aOption['initials'] = utils::FormatInitialsForMedallion(utils::ToAcronym($oObj->Get('friendlyname')));
|
||||
}
|
||||
}
|
||||
array_push($aOptions, $aOption);
|
||||
@@ -776,9 +773,11 @@ JS
|
||||
*
|
||||
* @throws CoreException
|
||||
* @throws OQLException
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $oObj for PHP 8.0 compatibility
|
||||
*/
|
||||
public function AutoComplete(
|
||||
WebPage $oP, $sFilter, $oObj = null, $sContains = '', $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null
|
||||
WebPage $oP, $sFilter, $oObj, $sContains, $sOutputFormat = self::ENUM_OUTPUT_FORMAT_CSV, $sOperation = null
|
||||
)
|
||||
{
|
||||
if (is_null($sFilter)) {
|
||||
@@ -830,7 +829,7 @@ JS
|
||||
}
|
||||
|
||||
if (array_key_exists('initials', $aValue)) {
|
||||
$aElt['initials'] = $aValue['initials'];
|
||||
$aElt['initials'] = utils::FormatInitialsForMedallion($aValue['initials']);
|
||||
if (array_key_exists('picture_url', $aValue)) {
|
||||
$aElt['picture_url'] = $aValue['picture_url'];
|
||||
}
|
||||
|
||||
@@ -75,9 +75,15 @@ class UILinksWidgetDirect
|
||||
* @param array $aArgs
|
||||
* @param string $sFormPrefix
|
||||
* @param DBObject $oCurrentObj
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (handling wrong values at method start)
|
||||
*/
|
||||
public function Display(WebPage $oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj)
|
||||
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj)
|
||||
{
|
||||
if (empty($aArgs)) {
|
||||
$aArgs = [];
|
||||
}
|
||||
|
||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||
switch($oLinksetDef->GetEditMode())
|
||||
{
|
||||
@@ -127,8 +133,10 @@ class UILinksWidgetDirect
|
||||
* @param string $sFormPrefix
|
||||
* @param DBObject $oCurrentObj
|
||||
* @param bool $bDisplayMenu
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (protected method, always called with default value)
|
||||
*/
|
||||
protected function DisplayAsBlock(WebPage $oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $bDisplayMenu)
|
||||
protected function DisplayAsBlock(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $bDisplayMenu)
|
||||
{
|
||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||
$sTargetClass = $oLinksetDef->GetLinkedClass();
|
||||
@@ -228,8 +236,10 @@ class UILinksWidgetDirect
|
||||
* @param string $sFormPrefix
|
||||
* @param DBObject $oCurrentObj
|
||||
* @param array $aButtons
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (protected method, caller already handles it)
|
||||
*/
|
||||
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
||||
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
||||
{
|
||||
$aAttribs = $this->GetTableConfig();
|
||||
$oValue->Rewind();
|
||||
@@ -296,7 +306,7 @@ class UILinksWidgetDirect
|
||||
}
|
||||
$oHiddenCriteria = $oHiddenFilter->GetCriteria();
|
||||
$aArgs = $oHiddenFilter->GetInternalParams();
|
||||
$sHiddenCriteria = $oHiddenCriteria->Render($aArgs);
|
||||
$sHiddenCriteria = $oHiddenCriteria->RenderExpression(false, $aArgs);
|
||||
|
||||
$oLinkSetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||
$valuesDef = $oLinkSetDef->GetValuesDef();
|
||||
|
||||
@@ -1944,28 +1944,18 @@ class utils
|
||||
|
||||
return $sCss;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the size of an image from a string.
|
||||
*
|
||||
* @see \getimagesizefromstring()
|
||||
* @param $sImageData string The image data, as a string.
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public static function GetImageSize($sImageData)
|
||||
{
|
||||
if (function_exists('getimagesizefromstring')) // PHP 5.4.0 or higher
|
||||
{
|
||||
$aRet = @getimagesizefromstring($sImageData);
|
||||
}
|
||||
else if(ini_get('allow_url_fopen'))
|
||||
{
|
||||
// work around to avoid creating a tmp file
|
||||
$sUri = 'data://application/octet-stream;base64,'.base64_encode($sImageData);
|
||||
$aRet = @getimagesize($sUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Damned, need to create a tmp file
|
||||
$sTempFile = tempnam(SetupUtils::GetTmpDir(), 'img-');
|
||||
@file_put_contents($sTempFile, $sImageData);
|
||||
$aRet = @getimagesize($sTempFile);
|
||||
@unlink($sTempFile);
|
||||
}
|
||||
return $aRet;
|
||||
return @getimagesizefromstring($sImageData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2118,11 +2108,21 @@ class utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative (to MODULESROOT) path of the root directory of the module containing the file where the call to
|
||||
* this function is made
|
||||
* or an empty string if no such module is found (or not called within a module file)
|
||||
* @param number $iCallDepth The depth of the module in the callstack. Zero when called directly from within the module
|
||||
* @return string
|
||||
* **Warning** : returned result can be invalid as we're using backtrace to find the module dir name
|
||||
*
|
||||
* @param int $iCallDepth The depth of the module in the callstack. Zero when called directly from within the module
|
||||
*
|
||||
* @return string the relative (to MODULESROOT) path of the root directory of the module containing the file where the call to
|
||||
* this function is made
|
||||
* or an empty string if no such module is found (or not called within a module file)
|
||||
*
|
||||
* @uses \debug_backtrace()
|
||||
*
|
||||
* @since 3.0.0 Before writing model.*.php file, compiler will now always delete it.
|
||||
* If you have symlinks enabled, base dir will be original module dir, but since this behavior change this won't be true anymore for model.*.php
|
||||
* In consequence the backtrace analysis won't be possible for this file
|
||||
* See N°4854
|
||||
* @link https://www.itophub.io/wiki/page?id=3_0_0%3Arelease%3A3_0_whats_new#compiler_always_generate_new_model_php compiler behavior change documentation
|
||||
*/
|
||||
public static function GetCurrentModuleDir($iCallDepth)
|
||||
{
|
||||
@@ -2147,9 +2147,14 @@ class utils
|
||||
}
|
||||
|
||||
/**
|
||||
* **Warning** : as this method uses {@see GetCurrentModuleDir} it produces hazardous results.
|
||||
* You should better uses directly {@see GetAbsoluteUrlModulesRoot} and add the module dir name yourself ! See N°4573
|
||||
*
|
||||
* @return string the base URL for all files in the current module from which this method is called
|
||||
* or an empty string if no such module is found (or not called within a module file)
|
||||
* @throws \Exception
|
||||
*
|
||||
* @uses GetCurrentModuleDir
|
||||
*/
|
||||
public static function GetCurrentModuleUrl()
|
||||
{
|
||||
@@ -2404,43 +2409,19 @@ class utils
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg : '2_7_0' ITOP_VERSION is '2.7.1-dev'
|
||||
* @return string eg : '2_7_0' if iTop core version is '2.7.5-2'
|
||||
* @throws \ApplicationException if constant value is invalid
|
||||
* @uses ITOP_CORE_VERSION
|
||||
*/
|
||||
public static function GetItopVersionWikiSyntax() {
|
||||
$sMinorVersion = self::GetItopMinorVersion();
|
||||
public static function GetItopVersionWikiSyntax($sItopVersion = ITOP_CORE_VERSION)
|
||||
{
|
||||
$aExplodedVersion = explode('.', $sItopVersion);
|
||||
|
||||
return str_replace('.', '_', $sMinorVersion).'_0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPatchVersion if non provided, will call GetItopPatchVersion
|
||||
*
|
||||
* @return string eg 2.7 if ITOP_VERSION is '2.7.0-dev'
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function GetItopMinorVersion($sPatchVersion = null) {
|
||||
if (is_null($sPatchVersion)) {
|
||||
$sPatchVersion = self::GetItopPatchVersion();
|
||||
}
|
||||
$aExplodedVersion = explode('.', $sPatchVersion);
|
||||
|
||||
if (count($aExplodedVersion) < 2) {
|
||||
throw new Exception('iTop version is wrongfully configured!');
|
||||
}
|
||||
if (($aExplodedVersion[0] == '') || ($aExplodedVersion[1] == '')) {
|
||||
throw new Exception('iTop version is wrongfully configured!');
|
||||
if ((false === isset($aExplodedVersion[0])) || (false === isset($aExplodedVersion[1]))) {
|
||||
throw new ApplicationException('iTop version is wrongfully configured!');
|
||||
}
|
||||
|
||||
return sprintf('%d.%d', $aExplodedVersion[0], $aExplodedVersion[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg '2.7.0' if ITOP_VERSION is '2.7.0-dev'
|
||||
*/
|
||||
public static function GetItopPatchVersion() {
|
||||
$aExplodedVersion = explode('-', ITOP_VERSION);
|
||||
|
||||
return $aExplodedVersion[0];
|
||||
return "{$aExplodedVersion[0]}_{$aExplodedVersion[1]}_0";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3059,6 +3040,20 @@ HTML;
|
||||
return $aMentionedObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This method is not ideal, but other solutions seemed even less ideal:
|
||||
* * Add a "$sMaxLength" param. to utils::ToAcronym(): Does not work for every use cases (see corresponding ticket) as in some parts utils::ToAcronym isn't necessarly meant to be used in a medallion.
|
||||
*
|
||||
* @param string $sInitials
|
||||
*
|
||||
* @return string Truncates $sInitials so it can fit in medallions
|
||||
* @since 3.0.1 N°4913
|
||||
*/
|
||||
public static function FormatInitialsForMedallion(string $sInitials): string
|
||||
{
|
||||
return mb_substr($sInitials, 0, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sUrl
|
||||
* @param string $sParamName
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/WebPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/WebPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader');
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/application/WebPage/XMLPage.php, now loadable using autoloader
|
||||
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/application/WebPage/XMLPage.php, now loadable using autoloader');
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader');
|
||||
@@ -4,8 +4,25 @@ define('APPROOT', dirname(__FILE__).'/');
|
||||
define('APPCONF', APPROOT.'conf/');
|
||||
|
||||
/**
|
||||
* iTop framework Version
|
||||
* iTop Datamodel XML format version
|
||||
*
|
||||
* It was also used in iTop 3.0.0 to get iTop core version (instead of {@see ITOP_VERSION} which gives the application version).
|
||||
* To address this need you should now use {@see ITOP_CORE_VERSION}
|
||||
*
|
||||
* @see ITOP_CORE_VERSION to get full iTop core version
|
||||
*/
|
||||
define('ITOP_DESIGN_LATEST_VERSION', '3.1');
|
||||
|
||||
/**
|
||||
* Constant containing the iTop core version, whatever application was built
|
||||
*
|
||||
* Note that in iTop 3.0.0 we used {@see ITOP_DESIGN_LATEST_VERSION} to get core version.
|
||||
* When releasing, both constants should be updated : see `.make/release/update-versions.php` for that !
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°4714 constant creation
|
||||
* @used-by utils::GetItopVersionWikiSyntax()
|
||||
* @used-by iTopModulesPhpVersionIntegrationTest
|
||||
*/
|
||||
define('ITOP_CORE_VERSION', '3.1.0');
|
||||
|
||||
require_once APPROOT.'bootstrap.inc.php';
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
"pelago/emogrifier": "3.1.0",
|
||||
"scssphp/scssphp": "1.0.6",
|
||||
"swiftmailer/swiftmailer": "5.4.12",
|
||||
"symfony/console": "3.4.*",
|
||||
"symfony/dotenv": "3.4.*",
|
||||
"symfony/framework-bundle": "3.4.*",
|
||||
"symfony/console": "~3.4.47",
|
||||
"symfony/dotenv": "~3.4.47",
|
||||
"symfony/framework-bundle": "~3.4.47",
|
||||
"symfony/polyfill-php70": "1.*",
|
||||
"symfony/twig-bundle": "3.4.*",
|
||||
"symfony/yaml": "3.4.*"
|
||||
"symfony/twig-bundle": "~3.4.47",
|
||||
"symfony/yaml": "~3.4.47"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/stopwatch": "3.4.*",
|
||||
"symfony/web-profiler-bundle": "3.4.*"
|
||||
"symfony/stopwatch": "~3.4.47",
|
||||
"symfony/web-profiler-bundle": "~3.4.47"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
||||
|
||||
905
composer.lock
generated
905
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -5717,7 +5717,7 @@ class AttributeMetaEnum extends AttributeEnum
|
||||
$aLocalizedValues = array();
|
||||
foreach($aRawValues as $sKey => $sValue)
|
||||
{
|
||||
$aLocalizedValues[$sKey] = Str::pure2html($this->GetValueLabel($sKey));
|
||||
$aLocalizedValues[$sKey] = $this->GetValueLabel($sKey);
|
||||
}
|
||||
|
||||
return $aLocalizedValues;
|
||||
|
||||
@@ -1077,7 +1077,7 @@ class CMDBChangeOpSetAttributeLinksTune extends CMDBChangeOpSetAttributeLinks
|
||||
{
|
||||
$oField = new FieldExpression('objclass', $oSearch->GetClassAlias());
|
||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($aLinkClasses)).')';
|
||||
$sOQLCondition = $oField->Render()." IN $sListExpr";
|
||||
$sOQLCondition = $oField->RenderExpression()." IN $sListExpr";
|
||||
$oNewCondition = Expression::FromOQL($sOQLCondition);
|
||||
$oSearch->AddConditionExpression($oNewCondition);
|
||||
}
|
||||
|
||||
@@ -350,6 +350,12 @@ class CMDBSource
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \MySQLException
|
||||
*
|
||||
* @uses \CMDBSource::QueryToCol() so needs a connection opened !
|
||||
*/
|
||||
public static function GetDBVersion()
|
||||
{
|
||||
$aVersions = self::QueryToCol('SELECT Version() as version', 'version');
|
||||
@@ -367,8 +373,10 @@ class CMDBSource
|
||||
/**
|
||||
* Get the DB vendor between MySQL and its main forks
|
||||
* @return string
|
||||
*
|
||||
* @uses \CMDBSource::GetServerVariable() so needs a connection opened !
|
||||
*/
|
||||
static public function GetDBVendor()
|
||||
public static function GetDBVendor()
|
||||
{
|
||||
$sDBVendor = static::ENUM_DB_VENDOR_MYSQL;
|
||||
|
||||
@@ -672,13 +680,13 @@ class CMDBSource
|
||||
private static function StartTransaction()
|
||||
{
|
||||
$aStackTrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT , 3);
|
||||
$sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].'): '.$aStackTrace[2]['class'].'->'.$aStackTrace[2]['function'].'()';
|
||||
|
||||
$bHasExistingTransactions = self::IsInsideTransaction();
|
||||
if (!$bHasExistingTransactions) {
|
||||
IssueLog::Trace("START TRANSACTION $sCaller", LogChannels::CMDB_SOURCE);
|
||||
IssueLog::Trace("START TRANSACTION was sent to the DB", LogChannels::CMDB_SOURCE, ['stacktrace' => $aStackTrace]);
|
||||
self::DBQuery('START TRANSACTION');
|
||||
} else {
|
||||
IssueLog::Trace("Ignore nested (".self::$m_iTransactionLevel.") START TRANSACTION $sCaller", LogChannels::CMDB_SOURCE);
|
||||
IssueLog::Trace("START TRANSACTION ignored as a transaction is already opened", LogChannels::CMDB_SOURCE, ['stacktrace' => $aStackTrace]);
|
||||
}
|
||||
|
||||
self::AddTransactionLevel();
|
||||
|
||||
@@ -22,7 +22,15 @@
|
||||
|
||||
define('ITOP_APPLICATION', 'iTop');
|
||||
define('ITOP_APPLICATION_SHORT', 'iTop');
|
||||
|
||||
/**
|
||||
* Constant containing the application version
|
||||
* Warning: this might be different from iTop core version!
|
||||
*
|
||||
* @see ITOP_CORE_VERSION to get iTop core version
|
||||
*/
|
||||
define('ITOP_VERSION', '3.1.0-dev');
|
||||
|
||||
define('ITOP_VERSION_NAME', 'Fullmoon');
|
||||
define('ITOP_REVISION', 'svn');
|
||||
define('ITOP_BUILD_DATE', '$WCNOW$');
|
||||
@@ -608,6 +616,13 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
/**
|
||||
* The timezone is automatically set using this parameter in \utils::InitTimeZone
|
||||
* This method is called almost everywhere, cause it's called in \MetaModel::LoadConfig and exec.php... but you might
|
||||
* need to get it yourself !
|
||||
*
|
||||
* @used-by utils::InitTimeZone()
|
||||
*/
|
||||
'timezone' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitly configured in PHP',
|
||||
@@ -851,13 +866,23 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'impact_analysis_lazy_loading' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'In the impact analysis view: display the analysis or filter before display',
|
||||
'default' => false,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
],
|
||||
'url_validation_pattern' => [
|
||||
'type' => 'string',
|
||||
'description' => 'Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)',
|
||||
'default' => '(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\$_.-]*)?',
|
||||
// SHEME.......... USER....................... PASSWORD.......................... HOST/IP........... PORT.......... PATH........................ GET............................................ ANCHOR............................
|
||||
'default' => /** @lang RegExp */
|
||||
'(https?|ftp)\://([a-zA-Z0-9+!*(),;?&=\$_.-]+(\:[a-zA-Z0-9+!*(),;?&=\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\:[0-9]{2,5})?(/([a-zA-Z0-9:%+\$_-]\.?)+)*/?(\?[a-zA-Z+&\$_.-][a-zA-Z0-9;:[\]@&%=+/\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\$_.-]*)?',
|
||||
// SCHEME....... USER....................... PASSWORD.......................... HOST/IP........... PORT.......... PATH......................... GET............................................ ANCHOR..........................
|
||||
// Example: http://User:passWord@127.0.0.1:8888/patH/Page.php?arrayArgument[2]=something:blah20#myAnchor
|
||||
// Origin of this regexp: http://www.php.net/manual/fr/function.preg-match.php#93824
|
||||
// RegExp source: http://www.php.net/manual/fr/function.preg-match.php#93824
|
||||
// Update with N°4515
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
@@ -1175,7 +1200,7 @@ class Config
|
||||
],
|
||||
'compatibility.include_deprecated_js_files' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'Include the deprecated JS files to ease usage of not migrated extensions',
|
||||
'description' => 'Include the deprecated JS files (in iTop previous version) to ease usage of not migrated extensions',
|
||||
'default' => false,
|
||||
'value' => false,
|
||||
'source_of_value' => '',
|
||||
@@ -1191,7 +1216,7 @@ class Config
|
||||
],
|
||||
'compatibility.include_deprecated_css_files' => [
|
||||
'type' => 'bool',
|
||||
'description' => 'Include the deprecated CSS files to ease usage of not migrated extensions',
|
||||
'description' => 'Include the deprecated CSS files (in iTop previous version) to ease usage of not migrated extensions',
|
||||
'default' => false,
|
||||
'value' => false,
|
||||
'source_of_value' => '',
|
||||
@@ -1600,6 +1625,16 @@ class Config
|
||||
return $this->m_aSettings[$sPropCode]['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*
|
||||
* @since 3.0.1 N°4515
|
||||
*/
|
||||
public function GetDefault(string $sPropCode)
|
||||
{
|
||||
return $this->m_aSettings[$sPropCode]['default'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the $sPropCode parameter has a custom value or the default one.
|
||||
*
|
||||
|
||||
@@ -220,16 +220,15 @@ class CSVBulkExport extends TabularBulkExport
|
||||
|
||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="csv_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "csv_date_format_radio", "custom", "csv_date_time_format_custom", "radio");
|
||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||
$oRadioCustom->SetBeforeInput(false);
|
||||
$oRadioCustom->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||
$oFieldSetDate->AddSubBlock($oRadioCustom);
|
||||
|
||||
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
|
||||
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#csv_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
|
||||
$('#form_part_csv_options').on('preview_updated', function() { FormatDatesInPreview('csv', 'csv'); });
|
||||
$('#csv_date_time_format_default').on('click', function() { FormatDatesInPreview('csv', 'csv'); });
|
||||
$('#csv_date_time_format_custom').on('click', function() { FormatDatesInPreview('csv', 'csv'); });
|
||||
|
||||
@@ -2961,6 +2961,9 @@ abstract class DBObject implements iDisplay
|
||||
utils::EnrichRaisedException($oTrigger, $e);
|
||||
}
|
||||
}
|
||||
|
||||
// - TriggerOnObjectMention
|
||||
$this->ActivateOnMentionTriggers(true);
|
||||
|
||||
return $this->m_iKey;
|
||||
}
|
||||
@@ -3226,50 +3229,7 @@ abstract class DBObject implements iDisplay
|
||||
// Activate any existing trigger
|
||||
$sClass = get_class($this);
|
||||
// - TriggerOnObjectMention
|
||||
// 1 - Check if any caselog updated
|
||||
$aUpdatedLogAttCodes = array();
|
||||
foreach($aChanges as $sAttCode => $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if($oAttDef instanceof AttributeCaseLog)
|
||||
{
|
||||
$aUpdatedLogAttCodes[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
// 2 - Find mentioned objects
|
||||
$aMentionedObjects = array();
|
||||
foreach ($aUpdatedLogAttCodes as $sAttCode) {
|
||||
/** @var \ormCaseLog $oUpdatedCaseLog */
|
||||
$oUpdatedCaseLog = $this->Get($sAttCode);
|
||||
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
|
||||
}
|
||||
// 3 - Trigger for those objects
|
||||
// TODO: This should be refactored and moved into the caselogs loop, otherwise, we won't be able to know which case log triggered the action.
|
||||
foreach ($aMentionedObjects as $sMentionedClass => $aMentionedIds) {
|
||||
foreach ($aMentionedIds as $sMentionedId) {
|
||||
/** @var \DBObject $oMentionedObject */
|
||||
$oMentionedObject = MetaModel::GetObject($sMentionedClass, $sMentionedId);
|
||||
$aTriggerArgs = $this->ToArgs('this') + array('mentioned->object()' => $oMentionedObject);
|
||||
|
||||
$aParams = array('class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), array(), $aParams);
|
||||
while ($oTrigger = $oSet->Fetch())
|
||||
{
|
||||
/** @var \TriggerOnObjectMention $oTrigger */
|
||||
try {
|
||||
// Ensure to handle only mentioned object in the trigger's scope
|
||||
if ($oTrigger->IsMentionedObjectInScope($oMentionedObject) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oTrigger->DoActivate($aTriggerArgs);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
utils::EnrichRaisedException($oTrigger, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->ActivateOnMentionTriggers(false);
|
||||
|
||||
$bHasANewExternalKeyValue = false;
|
||||
$aHierarchicalKeys = array();
|
||||
@@ -3483,6 +3443,122 @@ abstract class DBObject implements iDisplay
|
||||
return $this->m_iKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Increment attribute with specified value.
|
||||
* This function is only applicable with AttributeInteger.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sAttCode attribute code
|
||||
* @param int $iValue value to increment (default value 1)
|
||||
*
|
||||
* @return int incremented value
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
public function DBIncrement(string $sAttCode, int $iValue = 1)
|
||||
{
|
||||
// retrieve instance class
|
||||
$sClass = get_class($this);
|
||||
|
||||
// dirty object not allowed
|
||||
if($this->m_bDirty){
|
||||
throw new CoreException("Invalid DBIncrement usage, dirty objects are not allowed. Call DBUpdate before calling DBIncrement.");
|
||||
}
|
||||
|
||||
// ensure attribute type is AttributeInteger
|
||||
$oAttr = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if(!$oAttr instanceof AttributeInteger){
|
||||
throw new CoreException(sprintf("Invalid DBIncrement usage, attribute type of {$sAttCode} is %s. Only AttributeInteger are compatibles with DBIncrement.", get_class($oAttr)));
|
||||
}
|
||||
|
||||
// prepare SQL statement
|
||||
$sTable = MetaModel::DBGetTable($sClass, $sAttCode);
|
||||
$sPKField = '`'.MetaModel::DBGetKey($sClass).'`';
|
||||
$sKey = CMDBSource::Quote($this->m_iKey);
|
||||
$sUpdateSQL = "UPDATE `{$sTable}` SET `{$sAttCode}` = `{$sAttCode}`+{$iValue} WHERE {$sPKField} = {$sKey}";
|
||||
|
||||
// execute SQL query
|
||||
CMDBSource::Query($sUpdateSQL);
|
||||
|
||||
// reload instance with new value
|
||||
$this->Reload();
|
||||
|
||||
return $this->Get($sAttCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate TriggerOnObjectMention triggers for the current object
|
||||
*
|
||||
* @param bool $bNewlyCreatedObject
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
* @since 3.0.1 N°4741
|
||||
*/
|
||||
private function ActivateOnMentionTriggers(bool $bNewlyCreatedObject): void
|
||||
{
|
||||
$sClass = get_class($this);
|
||||
$aChanges = $bNewlyCreatedObject ? $this->m_aOrigValues : $this->ListChanges();
|
||||
|
||||
// 1 - Check if any caselog updated
|
||||
$aUpdatedLogAttCodes = [];
|
||||
foreach ($aChanges as $sAttCode => $value) {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeCaseLog) {
|
||||
// Skip empty log on creation
|
||||
if ($bNewlyCreatedObject && $value->GetModifiedEntry() === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$aUpdatedLogAttCodes[] = $sAttCode;
|
||||
}
|
||||
}
|
||||
|
||||
// 2 - Find mentioned objects
|
||||
$aMentionedObjects = [];
|
||||
foreach ($aUpdatedLogAttCodes as $sAttCode) {
|
||||
/** @var \ormCaseLog $oUpdatedCaseLog */
|
||||
$oUpdatedCaseLog = $this->Get($sAttCode);
|
||||
$aMentionedObjects = array_merge_recursive($aMentionedObjects, utils::GetMentionedObjectsFromText($oUpdatedCaseLog->GetModifiedEntry()));
|
||||
}
|
||||
|
||||
// 3 - Trigger for those objects
|
||||
// TODO: This should be refactored and moved into the caselogs loop, otherwise, we won't be able to know which case log triggered the action.
|
||||
foreach ($aMentionedObjects as $sMentionedClass => $aMentionedIds) {
|
||||
foreach ($aMentionedIds as $sMentionedId) {
|
||||
/** @var \DBObject $oMentionedObject */
|
||||
$oMentionedObject = MetaModel::GetObject($sMentionedClass, $sMentionedId);
|
||||
$aTriggerArgs = $this->ToArgs('this') + ['mentioned->object()' => $oMentionedObject];
|
||||
|
||||
$aParams = ['class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL)];
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectMention AS t WHERE t.target_class IN (:class_list)"), [], $aParams);
|
||||
while ($oTrigger = $oSet->Fetch())
|
||||
{
|
||||
/** @var \TriggerOnObjectMention $oTrigger */
|
||||
try {
|
||||
// Ensure to handle only mentioned object in the trigger's scope
|
||||
if ($oTrigger->IsMentionedObjectInScope($oMentionedObject) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$oTrigger->DoActivate($aTriggerArgs);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
utils::EnrichRaisedException($oTrigger, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Save updated fields previous values for {@see DBObject::DBUpdate()} callbacks
|
||||
@@ -5415,7 +5491,7 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
$oLnk->Set($sRoleAttCode, $sRoleValue);
|
||||
}
|
||||
$oLinkSet->AddObject($oLnk);
|
||||
$oLinkSet->AddItem($oLnk);
|
||||
$this->Set($sTargetListAttCode, $oLinkSet);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -416,6 +416,10 @@ class DBObjectSearch extends DBSearch
|
||||
* @param string $sFilterCode
|
||||
* @param mixed $value
|
||||
* @param string $sOpCode operator to use : 'IN', 'NOT IN', 'Contains',' Begins with', 'Finishes with', ...
|
||||
* If no operator is specified then :
|
||||
* * for id field we will use "="
|
||||
* * for other fields we will call the corresponding {@link AttributeDefinition::GetSmartConditionExpression} method impl
|
||||
* to generate the expression
|
||||
* @param bool $bParseSearchString
|
||||
*
|
||||
* @throws \CoreException
|
||||
@@ -465,14 +469,14 @@ class DBObjectSearch extends DBSearch
|
||||
if (!is_array($value)) $value = array($value);
|
||||
if (count($value) === 0) throw new Exception('AddCondition '.$sOpCode.': Value cannot be an empty array.');
|
||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($value)).')';
|
||||
$sOQLCondition = $oField->Render()." IN $sListExpr";
|
||||
$sOQLCondition = $oField->RenderExpression()." IN $sListExpr";
|
||||
break;
|
||||
|
||||
case 'NOTIN':
|
||||
if (!is_array($value)) $value = array($value);
|
||||
if (count($value) === 0) throw new Exception('AddCondition '.$sOpCode.': Value cannot be an empty array.');
|
||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($value)).')';
|
||||
$sOQLCondition = $oField->Render()." NOT IN $sListExpr";
|
||||
$sOQLCondition = $oField->RenderExpression()." NOT IN $sListExpr";
|
||||
break;
|
||||
|
||||
case 'Contains':
|
||||
@@ -1232,7 +1236,7 @@ class DBObjectSearch extends DBSearch
|
||||
elseif (MetaModel::IsParentClass($oRightFilter->GetFirstJoinedClass(), $oLeftFilter->GetClass()))
|
||||
{
|
||||
// Specialize $oRightFilter
|
||||
$oRightFilter->ChangeClass($oLeftFilter->GetClass());
|
||||
$oRightFilter->ChangeClass($oLeftFilter->GetFirstJoinedClass());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1368,7 +1372,7 @@ class DBObjectSearch extends DBSearch
|
||||
public function GetQueryParams($bExcludeMagicParams = true)
|
||||
{
|
||||
$aParams = array();
|
||||
$this->m_oSearchCondition->Render($aParams, true);
|
||||
$this->m_oSearchCondition->RenderExpression(false, $aParams, true);
|
||||
|
||||
if ($bExcludeMagicParams)
|
||||
{
|
||||
@@ -1457,7 +1461,7 @@ class DBObjectSearch extends DBSearch
|
||||
|
||||
$sRes .= ' ' . $this->GetFirstJoinedClass() . ' AS `' . $this->GetFirstJoinedClassAlias() . '`';
|
||||
$sRes .= $this->ToOQL_Joins();
|
||||
$sRes .= " WHERE ".$this->m_oSearchCondition->Render($aParams, $bRetrofitParams);
|
||||
$sRes .= " WHERE ".$this->m_oSearchCondition->RenderExpression(false, $aParams, $bRetrofitParams);
|
||||
|
||||
if ($bWithAllowAllFlag && $this->m_bAllowAllData)
|
||||
{
|
||||
|
||||
@@ -416,7 +416,11 @@ class DBUnionSearch extends DBSearch
|
||||
$aSearches = array();
|
||||
foreach ($this->aSearches as $oSearch)
|
||||
{
|
||||
$aSearches[] = $oSearch->Filter($sClassAlias, $oFilter);
|
||||
if (!$oSearch->IsAllDataAllowed()) {
|
||||
$aSearches[] = $oSearch->Filter($sClassAlias, $oFilter);
|
||||
} else {
|
||||
$aSearches[] = $oSearch;
|
||||
}
|
||||
}
|
||||
return new DBUnionSearch($aSearches);
|
||||
}
|
||||
|
||||
@@ -302,13 +302,12 @@ class Dict
|
||||
*
|
||||
* @param $sSourceCode
|
||||
* @param $sDestCode
|
||||
* @since 3.0.1 Not clone sSourceCode entry if sDestCode entry already exist
|
||||
*/
|
||||
public static function CloneString($sSourceCode, $sDestCode)
|
||||
{
|
||||
foreach(self::$m_aLanguages as $sLanguageCode => $foo)
|
||||
{
|
||||
if (isset(self::$m_aData[$sLanguageCode][$sSourceCode]))
|
||||
{
|
||||
foreach(self::$m_aLanguages as $sLanguageCode => $foo) {
|
||||
if (isset(self::$m_aData[$sLanguageCode][$sSourceCode]) && !isset(self::$m_aData[$sLanguageCode][$sDestCode] )) {
|
||||
self::$m_aData[$sLanguageCode][$sDestCode] = self::$m_aData[$sLanguageCode][$sSourceCode];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class DisplayableNode extends GraphNode
|
||||
{
|
||||
public $x;
|
||||
public $y;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new node inside a graph
|
||||
* @param SimpleGraph $oGraph
|
||||
@@ -51,27 +51,27 @@ class DisplayableNode extends GraphNode
|
||||
{
|
||||
return $this->GetProperty('icon_url', '');
|
||||
}
|
||||
|
||||
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->GetProperty('label', $this->sId);
|
||||
}
|
||||
|
||||
|
||||
public function GetWidth()
|
||||
{
|
||||
return max(32, 5*strlen($this->GetProperty('label'))); // approximation of the text's bounding box
|
||||
}
|
||||
|
||||
|
||||
public function GetHeight()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
|
||||
public function Distance2(DisplayableNode $oNode)
|
||||
{
|
||||
$dx = $this->x - $oNode->x;
|
||||
$dy = $this->y - $oNode->y;
|
||||
|
||||
|
||||
$d2 = $dx*$dx + $dy*$dy - $this->GetHeight()*$this->GetHeight();
|
||||
if ($d2 < 40)
|
||||
{
|
||||
@@ -79,12 +79,12 @@ class DisplayableNode extends GraphNode
|
||||
}
|
||||
return $d2;
|
||||
}
|
||||
|
||||
|
||||
public function Distance(DisplayableNode $oNode)
|
||||
{
|
||||
return sqrt($this->Distance2($oNode));
|
||||
}
|
||||
|
||||
|
||||
public function GetForRaphael($aContextDefs)
|
||||
{
|
||||
$aNode = array();
|
||||
@@ -100,7 +100,7 @@ class DisplayableNode extends GraphNode
|
||||
$aNode['label'] = $this->GetLabel();
|
||||
$aNode['id'] = $this->GetId();
|
||||
$fOpacity = ($this->GetProperty('is_reached') ? 1 : 0.4);
|
||||
$aNode['icon_attr'] = array('opacity' => $fOpacity);
|
||||
$aNode['icon_attr'] = array('opacity' => $fOpacity);
|
||||
$aNode['text_attr'] = array('opacity' => $fOpacity);
|
||||
$aNode['tooltip'] = $this->GetTooltip($aContextDefs);
|
||||
$aNode['context_icons'] = array();
|
||||
@@ -114,7 +114,7 @@ class DisplayableNode extends GraphNode
|
||||
}
|
||||
return $aNode;
|
||||
}
|
||||
|
||||
|
||||
public function RenderAsPDF(iTopPDF $oPdf, DisplayableGraph $oGraph, $fScale, $aContextDefs)
|
||||
{
|
||||
$Alpha = 1.0;
|
||||
@@ -170,7 +170,7 @@ class DisplayableNode extends GraphNode
|
||||
$oPdf->SetTextColor(0, 0, 0);
|
||||
$oPdf->Text($this->x*$fScale - $width/2, ($this->y + 18)*$fScale, $this->GetProperty('label'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a "whitened" version of the icon (retaining the transparency) to be used a background for masking the underlying lines
|
||||
* @param string $sIconFile The path to the file containing the icon
|
||||
@@ -179,35 +179,35 @@ class DisplayableNode extends GraphNode
|
||||
protected function CreateWhiteIcon(DisplayableGraph $oGraph, $sIconFile)
|
||||
{
|
||||
$aInfo = getimagesize($sIconFile);
|
||||
|
||||
|
||||
$im = null;
|
||||
switch($aInfo['mime'])
|
||||
{
|
||||
case 'image/png':
|
||||
if (function_exists('imagecreatefrompng'))
|
||||
{
|
||||
$im = imagecreatefrompng($sIconFile);
|
||||
}
|
||||
break;
|
||||
|
||||
if (function_exists('imagecreatefrompng'))
|
||||
{
|
||||
$im = imagecreatefrompng($sIconFile);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'image/gif':
|
||||
if (function_exists('imagecreatefromgif'))
|
||||
{
|
||||
$im = imagecreatefromgif($sIconFile);
|
||||
}
|
||||
break;
|
||||
|
||||
if (function_exists('imagecreatefromgif'))
|
||||
{
|
||||
$im = imagecreatefromgif($sIconFile);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'image/jpeg':
|
||||
case 'image/jpg':
|
||||
if (function_exists('imagecreatefromjpeg'))
|
||||
{
|
||||
$im = imagecreatefromjpeg($sIconFile);
|
||||
}
|
||||
break;
|
||||
|
||||
if (function_exists('imagecreatefromjpeg'))
|
||||
{
|
||||
$im = imagecreatefromjpeg($sIconFile);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
if($im && imagefilter($im, IMG_FILTER_COLORIZE, 255, 255, 255))
|
||||
{
|
||||
@@ -222,17 +222,17 @@ class DisplayableNode extends GraphNode
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetObjectCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function GetObjectClass()
|
||||
{
|
||||
return is_object($this->GetProperty('object', null)) ? get_class($this->GetProperty('object', null)) : null;
|
||||
}
|
||||
|
||||
|
||||
protected function AddToStats($oNode, &$aNodesPerClass)
|
||||
{
|
||||
$sClass = $oNode->GetObjectClass();
|
||||
@@ -256,9 +256,9 @@ class DisplayableNode extends GraphNode
|
||||
{
|
||||
$aNodesPerClass[$sClass][$sKey]['nodes'][$oNode->GetId()] = $oNode;
|
||||
$aNodesPerClass[$sClass][$sKey]['count'] += $oNode->GetObjectCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the list of neighbour nodes, in the given direction: 'up' or 'down'
|
||||
* @param bool $bDirectionDown
|
||||
@@ -279,11 +279,11 @@ class DisplayableNode extends GraphNode
|
||||
foreach($this->GetIncomingEdges() as $oEdge)
|
||||
{
|
||||
$aNextNodes[] = $oEdge->GetSourceNode();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aNextNodes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces the next neighbour node (in the given direction: 'up' or 'down') by the supplied group node
|
||||
* preserving the connectivity of the graph
|
||||
@@ -351,7 +351,7 @@ class DisplayableNode extends GraphNode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($oGraph->GetNode($oNextNode->GetId()))
|
||||
{
|
||||
$oGraph->_RemoveNode($oNextNode);
|
||||
@@ -367,9 +367,9 @@ class DisplayableNode extends GraphNode
|
||||
{
|
||||
$oNewNode->AddObject($oNextNode->GetProperty('object'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Group together (as a special kind of nodes) all the similar neighbours of the current node
|
||||
* @param DisplayableGraph $oGraph
|
||||
@@ -381,7 +381,7 @@ class DisplayableNode extends GraphNode
|
||||
{
|
||||
if ($this->GetProperty('grouped') === true) return;
|
||||
$this->SetProperty('grouped', true);
|
||||
|
||||
|
||||
$aNodesPerClass = array();
|
||||
foreach($this->GetNextNodes($bDirectionDown) as $oNode)
|
||||
{
|
||||
@@ -412,7 +412,7 @@ class DisplayableNode extends GraphNode
|
||||
$oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
|
||||
$oNewNode->SetProperty('count', $aGroupProps['count']);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if ($bDirectionDown)
|
||||
@@ -427,8 +427,8 @@ class DisplayableNode extends GraphNode
|
||||
catch(Exception $e)
|
||||
{
|
||||
// Ignore this redundant egde
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach($aGroupProps['nodes'] as $oNextNode)
|
||||
{
|
||||
$this->ReplaceNextNodeBy($oGraph, $oNextNode, $oNewNode, $bDirectionDown);
|
||||
@@ -445,7 +445,7 @@ class DisplayableNode extends GraphNode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetTooltip($aContextDefs)
|
||||
{
|
||||
$sHtml = '';
|
||||
@@ -474,9 +474,9 @@ class DisplayableNode extends GraphNode
|
||||
$sHtml .= '<tr><td>'.$oAttDef->GetLabel().': </td><td>'.$oCurrObj->GetAsHtml($sAttCode).'</td></tr>';
|
||||
}
|
||||
$sHtml .= '</tbody></table>';
|
||||
return $sHtml;
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the description of the node in "dot" language
|
||||
* Used to generate the positions in the graph, but we'd better use fake label
|
||||
@@ -508,7 +508,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
{
|
||||
return 24;
|
||||
}
|
||||
|
||||
|
||||
public function GetForRaphael($aContextDefs)
|
||||
{
|
||||
$aNode = array();
|
||||
@@ -519,7 +519,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
$aNode['x'] = $this->x;
|
||||
$aNode['y']= $this->y;
|
||||
$aNode['label'] = $this->GetLabel();
|
||||
$aNode['id'] = $this->GetId();
|
||||
$aNode['id'] = $this->GetId();
|
||||
$fDiscOpacity = ($this->GetProperty('is_reached') ? 1 : 0.2);
|
||||
$sColor = ($this->GetProperty('is_reached_count') > $this->GetProperty('threshold')) ? '#c33' : '#999';
|
||||
$aNode['disc_attr'] = array('stroke-width' => 2, 'stroke' => '#000', 'fill' => $sColor, 'opacity' => $fDiscOpacity);
|
||||
@@ -550,35 +550,35 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
$height = $oPdf->GetStringHeight(1000, $sLabel);
|
||||
$xPos = (float)$this->x*$fScale - $width/2;
|
||||
$yPos = (float)$this->y*$fScale - $height/2;
|
||||
|
||||
|
||||
$oPdf->SetXY(($this->x - 16)*$fScale, ($this->y - 16)*$fScale);
|
||||
|
||||
|
||||
$oPdf->Cell(32*$fScale, 32*$fScale, $sLabel, 0, 0, 'C', 0, '', 0, false, 'T', 'C');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DisplayableNode::GroupSimilarNeighbours()
|
||||
*/
|
||||
public function GroupSimilarNeighbours(DisplayableGraph $oGraph, $iThresholdCount, $bDirectionUp = false, $bDirectionDown = true)
|
||||
{
|
||||
parent::GroupSimilarNeighbours($oGraph, $iThresholdCount, $bDirectionUp, $bDirectionDown);
|
||||
|
||||
|
||||
if ($bDirectionUp)
|
||||
{
|
||||
$aNodesPerClass = array();
|
||||
foreach($this->GetIncomingEdges() as $oEdge)
|
||||
{
|
||||
$oNode = $oEdge->GetSourceNode();
|
||||
|
||||
|
||||
if (($oNode->GetObjectClass() !== null) && (!$oNode->GetProperty('is_reached')))
|
||||
{
|
||||
{
|
||||
$this->AddToStats($oNode, $aNodesPerClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
//$oNode->GroupSimilarNeighbours($oGraph, $iThresholdCount, $bDirectionUp, $bDirectionDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($aNodesPerClass as $sClass => $aDefs)
|
||||
{
|
||||
foreach($aDefs as $sStatus => $aGroupProps)
|
||||
@@ -591,8 +591,8 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
$oNewNode->SetProperty('is_reached', ($sStatus == 'is_reached'));
|
||||
$oNewNode->SetProperty('class', $sClass);
|
||||
$oNewNode->SetProperty('count', count($aGroupProps['nodes']));
|
||||
|
||||
|
||||
|
||||
|
||||
$sNewId = $this->GetId().'::'.$sClass.'/'.(($sStatus == 'reached') ? '_reached': '');
|
||||
$oNewNode = $oGraph->GetNode($sNewId);
|
||||
if ($oNewNode == null)
|
||||
@@ -604,7 +604,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
$oNewNode->SetProperty('is_reached', ($sStatus == 'reached'));
|
||||
$oNewNode->SetProperty('count', $aGroupProps['count']);
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
$oOutgoingEdge = new DisplayableEdge($oGraph, '-'.$this->GetId().'-'.$oNewNode->GetId().'/'.$sStatus, $oNewNode, $this);
|
||||
@@ -613,7 +613,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
{
|
||||
// Ignore this redundant egde
|
||||
}
|
||||
|
||||
|
||||
foreach($aGroupProps['nodes'] as $oNextNode)
|
||||
{
|
||||
$this->ReplaceNextNodeBy($oGraph, $oNextNode, $oNewNode, !$bDirectionUp);
|
||||
@@ -631,7 +631,7 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetTooltip($aContextDefs)
|
||||
{
|
||||
$sHtml = '';
|
||||
@@ -640,9 +640,9 @@ class DisplayableRedundancyNode extends DisplayableNode
|
||||
$sHtml .= "<tr><td>".Dict::Format('UI:RelationTooltip:ImpactedItems_N_of_M' , $this->GetProperty('is_reached_count'), $this->GetProperty('min_up') + $this->GetProperty('threshold'))."</td></tr>";
|
||||
$sHtml .= "<tr><td>".Dict::Format('UI:RelationTooltip:CriticalThreshold_N_of_M' , $this->GetProperty('threshold'), $this->GetProperty('min_up') + $this->GetProperty('threshold'))."</td></tr>";
|
||||
$sHtml .= '</tbody></table>';
|
||||
return $sHtml;
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function GetObjectCount()
|
||||
{
|
||||
@@ -666,7 +666,7 @@ class DisplayableEdge extends GraphEdge
|
||||
}
|
||||
$xStart = $oSourceNode->x * $fScale;
|
||||
$yStart = $oSourceNode->y * $fScale;
|
||||
|
||||
|
||||
$oSinkNode = $this->GetSinkNode();
|
||||
if (($oSinkNode->x == null) || ($oSinkNode->y == null))
|
||||
{
|
||||
@@ -674,9 +674,9 @@ class DisplayableEdge extends GraphEdge
|
||||
}
|
||||
$xEnd = $oSinkNode->x * $fScale;
|
||||
$yEnd = $oSinkNode->y * $fScale;
|
||||
|
||||
|
||||
$bReached = ($this->GetSourceNode()->GetProperty('is_reached') && $this->GetSinkNode()->GetProperty('is_reached'));
|
||||
|
||||
|
||||
$oPdf->setAlpha(1);
|
||||
if ($bReached)
|
||||
{
|
||||
@@ -688,8 +688,8 @@ class DisplayableEdge extends GraphEdge
|
||||
}
|
||||
$oPdf->SetLineStyle(array('width' => 2*$fScale, 'cap' => 'round', 'join' => 'miter', 'dash' => 0, 'color' => $aColor));
|
||||
$oPdf->Line($xStart, $yStart, $xEnd, $yEnd);
|
||||
|
||||
|
||||
|
||||
|
||||
$vx = $xEnd - $xStart;
|
||||
$vy = $yEnd - $yStart;
|
||||
$l = sqrt($vx*$vx + $vy*$vy);
|
||||
@@ -699,24 +699,24 @@ class DisplayableEdge extends GraphEdge
|
||||
$uy = $vx;
|
||||
$lPos = max($l/2, $l - 40*$fScale);
|
||||
$iArrowSize = 5*$fScale;
|
||||
|
||||
|
||||
$x = $xStart + $lPos * $vx;
|
||||
$y = $yStart + $lPos * $vy;
|
||||
$oPdf->Line($x, $y, $x + $iArrowSize * ($ux-$vx), $y + $iArrowSize * ($uy-$vy));
|
||||
$oPdf->Line($x, $y, $x - $iArrowSize * ($ux+$vx), $y - $iArrowSize * ($uy+$vy));
|
||||
$oPdf->Line($x, $y, $x - $iArrowSize * ($ux+$vx), $y - $iArrowSize * ($uy+$vy));
|
||||
}
|
||||
}
|
||||
|
||||
class DisplayableGroupNode extends DisplayableNode
|
||||
{
|
||||
protected $aObjects;
|
||||
|
||||
|
||||
public function __construct(SimpleGraph $oGraph, $sId, $x = 0, $y = 0)
|
||||
{
|
||||
parent::__construct($oGraph, $sId, $x, $y);
|
||||
$this->aObjects = array();
|
||||
}
|
||||
|
||||
|
||||
public function AddObject(DBObject $oObj = null)
|
||||
{
|
||||
if (is_object($oObj))
|
||||
@@ -729,12 +729,12 @@ class DisplayableGroupNode extends DisplayableNode
|
||||
$this->aObjects[$oObj->GetKey()] = $oObj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetObjects()
|
||||
{
|
||||
return $this->aObjects;
|
||||
}
|
||||
|
||||
|
||||
public function GetWidth()
|
||||
{
|
||||
return 50;
|
||||
@@ -760,7 +760,7 @@ class DisplayableGroupNode extends DisplayableNode
|
||||
$aNode['tooltip'] = $this->GetTooltip($aContextDefs);
|
||||
return $aNode;
|
||||
}
|
||||
|
||||
|
||||
public function RenderAsPDF(iTopPDF $oPdf, DisplayableGraph $oGraph, $fScale, $aContextDefs)
|
||||
{
|
||||
$bReached = $this->GetProperty('is_reached');
|
||||
@@ -790,7 +790,7 @@ class DisplayableGroupNode extends DisplayableNode
|
||||
$oPdf->SetTextColor(0, 0, 0);
|
||||
$oPdf->Text($this->x * $fScale - $width / 2, ($this->y + 25) * $fScale, $this->GetProperty('label'));
|
||||
}
|
||||
|
||||
|
||||
public function GetTooltip($aContextDefs)
|
||||
{
|
||||
$iGroupIdx = $this->GetProperty('group_index');
|
||||
@@ -823,7 +823,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
protected $aTempImages;
|
||||
protected $aSourceObjects;
|
||||
protected $aSinkObjects;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -831,14 +831,14 @@ class DisplayableGraph extends SimpleGraph
|
||||
$this->aSourceObjects = array();
|
||||
$this->aSinkObjects = array();
|
||||
}
|
||||
|
||||
|
||||
public function GetTempImageName()
|
||||
{
|
||||
$sNewTempName = tempnam(APPROOT.'data', 'img-');
|
||||
$this->aTempImages[] = $sNewTempName;
|
||||
return $sNewTempName;
|
||||
}
|
||||
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
foreach($this->aTempImages as $sTempFile)
|
||||
@@ -918,7 +918,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$oSinkNode = $oNewGraph->GetNode($oEdge->GetSinkNode()->GetId());
|
||||
$oNewEdge = new DisplayableEdge($oNewGraph, $oEdge->GetId(), $oSourceNode, $oSinkNode);
|
||||
}
|
||||
|
||||
|
||||
// Remove duplicate edges between two nodes
|
||||
$oEdgesIter = new RelationTypeIterator($oNewGraph, 'Edge');
|
||||
$aEdgeKeys = array();
|
||||
@@ -946,7 +946,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$oNodesIter = new RelationTypeIterator($oNewGraph, 'Node');
|
||||
foreach($oNodesIter as $oNode)
|
||||
{
|
||||
@@ -981,7 +981,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove duplicate edges between two nodes
|
||||
$oEdgesIter = new RelationTypeIterator($oNewGraph, 'Edge');
|
||||
$aEdgeKeys = array();
|
||||
@@ -1010,10 +1010,10 @@ class DisplayableGraph extends SimpleGraph
|
||||
}
|
||||
}
|
||||
set_time_limit(intval($iPreviousTimeLimit));
|
||||
|
||||
|
||||
return $oNewGraph;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the positions by rendering using Graphviz in xdot format
|
||||
* and parsing the output.
|
||||
@@ -1026,7 +1026,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
{
|
||||
throw new Exception($sDot);
|
||||
}
|
||||
|
||||
|
||||
$aChunks = explode(";", $sDot);
|
||||
foreach($aChunks as $sChunk)
|
||||
{
|
||||
@@ -1035,7 +1035,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$sId = $aMatches[1];
|
||||
$xPos = $aMatches[2];
|
||||
$yPos = $aMatches[3];
|
||||
|
||||
|
||||
$oNode = $this->GetNode($sId);
|
||||
if ($oNode !== null)
|
||||
{
|
||||
@@ -1049,7 +1049,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetBoundingBox()
|
||||
{
|
||||
$xMin = null;
|
||||
@@ -1074,10 +1074,10 @@ class DisplayableGraph extends SimpleGraph
|
||||
$yMax = max($yMax, $oNode->y + $oNode->GetHeight() / 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return array('xmin' => $xMin, 'xmax' => $xMax, 'ymin' => $yMin, 'ymax' => $yMax);
|
||||
}
|
||||
|
||||
|
||||
function Translate($dx, $dy)
|
||||
{
|
||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||
@@ -1085,9 +1085,9 @@ class DisplayableGraph extends SimpleGraph
|
||||
{
|
||||
$oNode->x += $dx;
|
||||
$oNode->y += $dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function UpdatePositions($aPositions)
|
||||
{
|
||||
foreach($aPositions as $sNodeId => $aPos)
|
||||
@@ -1107,7 +1107,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
function GetAsJSON($sContextKey)
|
||||
{
|
||||
$aContextDefs = static::GetContextDefinitions($sContextKey, false);
|
||||
|
||||
|
||||
$aData = array('nodes' => array(), 'edges' => array(), 'groups' => array(), 'lists' => array());
|
||||
$iGroupIdx = 0;
|
||||
$oIterator = new RelationTypeIterator($this, 'Node');
|
||||
@@ -1131,7 +1131,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$aData['groups'][$iGroupIdx] = array('class' => $sClass, 'keys' => $aKeys);
|
||||
$oNode->SetProperty('group_index', $iGroupIdx);
|
||||
$iGroupIdx++;
|
||||
|
||||
|
||||
if ($oNode->GetProperty('is_reached'))
|
||||
{
|
||||
// Also add the objects from this group into the 'list' tab
|
||||
@@ -1139,11 +1139,11 @@ class DisplayableGraph extends SimpleGraph
|
||||
{
|
||||
$aData['lists'][$sClass] = $aKeys;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
$aData['lists'][$sClass] = array_merge($aData['lists'][$sClass], $aKeys);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (($oNode instanceof DisplayableNode) && $oNode->GetProperty('is_reached') && is_object($oNode->GetProperty('object')))
|
||||
@@ -1157,9 +1157,9 @@ class DisplayableGraph extends SimpleGraph
|
||||
}
|
||||
$aData['nodes'][] = $oNode->GetForRaphael($aContextDefs);
|
||||
}
|
||||
|
||||
|
||||
uksort($aData['lists'], array(get_class($this), 'SortOnClassLabel')); // sort on the localized names of the classes to provide a consistent and stable order
|
||||
|
||||
|
||||
$oIterator = new RelationTypeIterator($this, 'Edge');
|
||||
foreach($oIterator as $sId => $oEdge)
|
||||
{
|
||||
@@ -1171,7 +1171,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$aEdge['attr'] = array('opacity' => $fOpacity, 'stroke' => '#000');
|
||||
$aData['edges'][] = $aEdge;
|
||||
}
|
||||
|
||||
|
||||
return json_encode($aData);
|
||||
}
|
||||
|
||||
@@ -1200,12 +1200,12 @@ class DisplayableGraph extends SimpleGraph
|
||||
{
|
||||
$aContextDefs = static::GetContextDefinitions($sContextKey, false); // No need to develop the parameters
|
||||
$oPdf = $oPage->get_tcpdf();
|
||||
|
||||
|
||||
$aBB = $this->GetBoundingBox();
|
||||
$this->Translate(-$aBB['xmin'], -$aBB['ymin']);
|
||||
|
||||
|
||||
$aMargins = $oPdf->getMargins();
|
||||
|
||||
|
||||
if ($xMin == -1)
|
||||
{
|
||||
$xMin = $aMargins['left'];
|
||||
@@ -1222,7 +1222,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
{
|
||||
$yMax = $oPdf->getPageHeight() - $aMargins['bottom'];
|
||||
}
|
||||
|
||||
|
||||
$fBreakMargin = $oPdf->getBreakMargin();
|
||||
$oPdf->SetAutoPageBreak(false);
|
||||
$aRemainingArea = $this->RenderKey($oPdf, $sComments, $xMin, $yMin, $xMax, $yMax, $aContextDefs);
|
||||
@@ -1230,19 +1230,19 @@ class DisplayableGraph extends SimpleGraph
|
||||
$xMax = $aRemainingArea['xmax'];
|
||||
$yMin = $aRemainingArea['ymin'];
|
||||
$yMax = $aRemainingArea['ymax'];
|
||||
|
||||
|
||||
//$oPdf->Rect($xMin, $yMin, $xMax - $xMin, $yMax - $yMin, 'D', array(), array(225, 50, 50));
|
||||
|
||||
|
||||
$fPageW = $xMax - $xMin;
|
||||
$fPageH = $yMax - $yMin;
|
||||
|
||||
$w = $aBB['xmax'] - $aBB['xmin'];
|
||||
|
||||
$w = $aBB['xmax'] - $aBB['xmin'];
|
||||
$h = $aBB['ymax'] - $aBB['ymin'] + 10; // Extra space for the labels which may appear "below" the icons
|
||||
|
||||
|
||||
$fScale = min($fPageW / $w, $fPageH / $h);
|
||||
$dx = ($fPageW - $fScale * $w) / 2;
|
||||
$dy = ($fPageH - $fScale * $h) / 2;
|
||||
|
||||
|
||||
$this->Translate(($xMin + $dx)/$fScale, ($yMin + $dy)/$fScale);
|
||||
|
||||
$oIterator = new RelationTypeIterator($this, 'Edge');
|
||||
@@ -1264,7 +1264,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$oPdf->SetAlpha(1);
|
||||
$oPdf->SetTextColor(0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders (in PDF) the key (legend) of the graphics vertically to the left of the specified zone (xmin,ymin, xmax,ymax),
|
||||
* and the comment (if any) at the bottom of the page. Returns the position of remaining area.
|
||||
@@ -1332,7 +1332,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$yPos += $fIconSize + 2 * $fPadding;
|
||||
}
|
||||
$oPdf->Rect($xMin, $yMin, $fMaxWidth + $fIconSize + 3*$fPadding, $yMax - $yMin, 'D');
|
||||
|
||||
|
||||
if ($sComments != '')
|
||||
{
|
||||
// Draw the comment text (surrounded by a rectangle)
|
||||
@@ -1347,10 +1347,10 @@ class DisplayableGraph extends SimpleGraph
|
||||
$oPdf->Rect($xPos, $yPos, $w + 2*$fPadding, $h + 2*$fPadding, 'D');
|
||||
$yMax = $yPos - $fPadding;
|
||||
}
|
||||
|
||||
|
||||
return array('xmin' => $xMin + $fMaxWidth + $fIconSize + 4*$fPadding, 'xmax' => $xMax, 'ymin' => $yMin, 'ymax' => $yMax);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the context definitions from the parameters / configuration. The format of the "key" string is:
|
||||
* <module>/relation_context/<class>/<relation>/<direction>
|
||||
@@ -1372,7 +1372,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
else
|
||||
{
|
||||
$sLeafClass = $aLevels[2];
|
||||
|
||||
|
||||
if (!MetaModel::IsValidClass($sLeafClass))
|
||||
{
|
||||
IssueLog::Warning("GetContextDefinitions: invalid 'sLeafClass' = '$sLeafClass'. A valid class name is expected in 3rd position inside '$sContextKey' !");
|
||||
@@ -1387,7 +1387,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
$aContextDefs = array_merge($aContextDefs, $aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the queries are valid
|
||||
foreach($aContextDefs as $sKey => $sDefs)
|
||||
{
|
||||
@@ -1425,168 +1425,101 @@ class DisplayableGraph extends SimpleGraph
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array())
|
||||
{
|
||||
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
|
||||
$aExcludedByClass = array();
|
||||
foreach($aExcludedObjects as $oObj)
|
||||
{
|
||||
if (!array_key_exists(get_class($oObj), $aExcludedByClass))
|
||||
{
|
||||
$aExcludedByClass[get_class($oObj)] = array();
|
||||
}
|
||||
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
|
||||
}
|
||||
$sSftShort = Dict::S('UI:ElementsDisplayed');
|
||||
$sSearchToggle = Dict::S('UI:Search:Toggle');
|
||||
$oP->add("<div class=\"not-printable\">\n");
|
||||
$oUiSearchBlock = new Panel($sSftShort, [],Panel::ENUM_COLOR_SCHEME_CYAN, 'ds_flash');
|
||||
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"]);
|
||||
$oUiSearchBlock->SetIsCollapsible(true);
|
||||
$oUiHtmlBlock = new Combodo\iTop\Application\UI\Base\Component\Html\Html(
|
||||
<<<EOF
|
||||
<div id="ds_flash" class="search_box ibo-display-graph--search-box">
|
||||
<div id="dh_flash_criterion_outer" class="sf_criterion_area"><div class="sf_criterion_row">
|
||||
EOF
|
||||
);
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$("#dh_flash > .sf_title").on('click', function() {
|
||||
$("#dh_flash").toggleClass('closed');
|
||||
});
|
||||
$('#ReloadMovieBtn').button().button('disable');
|
||||
EOF
|
||||
);
|
||||
$aSortedElements = array();
|
||||
foreach($aResults as $sClassIdx => $aObjects)
|
||||
{
|
||||
foreach($aObjects as $oCurrObj)
|
||||
{
|
||||
$sSubClass = get_class($oCurrObj);
|
||||
$aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass);
|
||||
}
|
||||
}
|
||||
|
||||
asort($aSortedElements);
|
||||
$idx = 0;
|
||||
foreach($aSortedElements as $sSubClass => $sClassName)
|
||||
{
|
||||
$oUiHtmlBlock->AddHtml("<div><input type=\"checkbox\" id=\"exclude_$idx\" name=\"excluded[]\" value=\"$sSubClass\" checked onChange=\"$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_$idx\">");
|
||||
$oUiMedallionBlock= new MedallionIcon(MetaModel::GetClassIcon($sSubClass, false));
|
||||
$oUiMedallionBlock->SetDescription($sClassName);
|
||||
$oUiHtmlBlock->AddHtml(BlockRenderer::RenderBlockTemplates($oUiMedallionBlock));
|
||||
$oUiHtmlBlock->AddHtml("</label></div>");
|
||||
$idx++;
|
||||
}
|
||||
$oUiHtmlBlock->AddHtml("</div>");
|
||||
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"DoReload()\">".Dict::S('UI:Button:Refresh')."</button></div></form>");
|
||||
$oUiHtmlBlock->AddHtml("</div>\n");
|
||||
$oUiHtmlBlock->AddHtml("</div>\n"); // class="not-printable"
|
||||
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array(), bool $sLazyLoading = false)
|
||||
{
|
||||
list($aExcludedByClass, $aAdditionalContexts) = $this->DisplayFiltering($sContextKey, $aContextParams, $aExcludedObjects, $oP, $aResults, $sLazyLoading);
|
||||
|
||||
$oUiSearchBlock->AddSubBlock($oUiHtmlBlock);
|
||||
$oP->AddUiBlock($oUiSearchBlock);
|
||||
$aAdditionalContexts = array();
|
||||
foreach($aContextDefs as $sKey => $aDefinition)
|
||||
{
|
||||
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));
|
||||
}
|
||||
|
||||
$sDirection = utils::ReadParam('d', 'horizontal');
|
||||
$iGroupingThreshold = utils::ReadParam('g', 5);
|
||||
|
||||
WebResourcesHelper::EnableSimpleGraphInWebPage($oP);
|
||||
try
|
||||
{
|
||||
try {
|
||||
$this->InitFromGraphviz();
|
||||
$sExportAsPdfURL = '';
|
||||
$sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=relation_pdf&relation='.$sRelation.'&direction='.($this->bDirectionDown ? 'down' : 'up');
|
||||
$oAppcontext = new ApplicationContext();
|
||||
$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 = '';
|
||||
if (($sObjClass != null) && ($iObjKey != null))
|
||||
{
|
||||
if (($sObjClass != null) && ($iObjKey != null)) {
|
||||
$oTargetObj = MetaModel::GetObject($sObjClass, $iObjKey, false);
|
||||
if ($oTargetObj)
|
||||
{
|
||||
if ($oTargetObj) {
|
||||
$sAttachmentExportTitle = Dict::Format('UI:Relation:AttachmentExportOptions_Name', $oTargetObj->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sId = 'graph';
|
||||
$sStyle = '';
|
||||
if ($oP->IsPrintableVersion())
|
||||
{
|
||||
if ($oP->IsPrintableVersion()) {
|
||||
// Optimize for printing on A4/Letter vertically
|
||||
$sStyle = 'margin-left:auto; margin-right:auto;';
|
||||
$oP->add_ready_script("$('.simple-graph').width(18/2.54*96).resizable({ stop: function() { $(window).trigger('resized'); }});"); // Default width about 18 cm, since most browsers assume 96 dpi
|
||||
}
|
||||
$oP->add('<div id="'.$sId.'" class="simple-graph" style="'.$sStyle.'"></div>');
|
||||
$aParams = array(
|
||||
'source_url' => $sLoadFromURL,
|
||||
'sources' => ($this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects),
|
||||
'excluded' => $aExcludedByClass,
|
||||
'grouping_threshold' => $iGroupingThreshold,
|
||||
'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')),
|
||||
'source_url' => $sLoadFromURL,
|
||||
'sources' => ($this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects),
|
||||
'excluded' => $aExcludedByClass,
|
||||
'grouping_threshold' => $iGroupingThreshold,
|
||||
'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')),
|
||||
'export_as_attachment' => array('url' => $sExportAsDocumentURL, 'label' => Dict::S('UI:Relation:ExportAsAttachment'), 'obj_class' => $sObjClass, 'obj_key' => $iObjKey),
|
||||
'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')),
|
||||
'labels' => array(
|
||||
'export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'),
|
||||
'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')),
|
||||
'labels' => array(
|
||||
'export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'),
|
||||
'export_as_attachment_title' => $sAttachmentExportTitle,
|
||||
'export' => Dict::S('UI:Button:Export'),
|
||||
'cancel' => Dict::S('UI:Button:Cancel'),
|
||||
'title' => Dict::S('UI:RelationOption:Title'),
|
||||
'untitled' => Dict::S('UI:RelationOption:Untitled'),
|
||||
'include_list' => Dict::S('UI:RelationOption:IncludeList'),
|
||||
'comments' => Dict::S('UI:RelationOption:Comments'),
|
||||
'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'),
|
||||
'refresh' => Dict::S('UI:Button:Refresh'),
|
||||
'check_all' => Dict::S('UI:SearchValue:CheckAll'),
|
||||
'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'),
|
||||
'none_selected' => Dict::S('UI:Relation:NoneSelected'),
|
||||
'nb_selected' => Dict::S('UI:SearchValue:NbSelected'),
|
||||
'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'),
|
||||
'zoom' => Dict::S('UI:Relation:Zoom'),
|
||||
'loading' => Dict::S('UI:Loading'),
|
||||
'export' => Dict::S('UI:Button:Export'),
|
||||
'cancel' => Dict::S('UI:Button:Cancel'),
|
||||
'title' => Dict::S('UI:RelationOption:Title'),
|
||||
'untitled' => Dict::S('UI:RelationOption:Untitled'),
|
||||
'include_list' => Dict::S('UI:RelationOption:IncludeList'),
|
||||
'comments' => Dict::S('UI:RelationOption:Comments'),
|
||||
'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'),
|
||||
'refresh' => Dict::S('UI:Button:Refresh'),
|
||||
'check_all' => Dict::S('UI:SearchValue:CheckAll'),
|
||||
'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'),
|
||||
'none_selected' => Dict::S('UI:Relation:NoneSelected'),
|
||||
'nb_selected' => Dict::S('UI:SearchValue:NbSelected'),
|
||||
'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'),
|
||||
'zoom' => Dict::S('UI:Relation:Zoom'),
|
||||
'loading' => Dict::S('UI:Loading'),
|
||||
),
|
||||
'page_format' => array(
|
||||
'label' => Dict::S('UI:Relation:PDFExportPageFormat'),
|
||||
'page_format' => array(
|
||||
'label' => Dict::S('UI:Relation:PDFExportPageFormat'),
|
||||
'values' => array(
|
||||
'A3' => Dict::S('UI:PageFormat_A3'),
|
||||
'A4' => Dict::S('UI:PageFormat_A4'),
|
||||
'A3' => Dict::S('UI:PageFormat_A3'),
|
||||
'A4' => Dict::S('UI:PageFormat_A4'),
|
||||
'Letter' => Dict::S('UI:PageFormat_Letter'),
|
||||
),
|
||||
),
|
||||
'page_orientation' => array(
|
||||
'label' => Dict::S('UI:Relation:PDFExportPageOrientation'),
|
||||
'page_orientation' => array(
|
||||
'label' => Dict::S('UI:Relation:PDFExportPageOrientation'),
|
||||
'values' => array(
|
||||
'P' => Dict::S('UI:PageOrientation_Portrait'),
|
||||
'L' => Dict::S('UI:PageOrientation_Landscape'),
|
||||
),
|
||||
),
|
||||
'additional_contexts' => $aAdditionalContexts,
|
||||
'context_key' => $sContextKey,
|
||||
'additional_contexts' => $aAdditionalContexts,
|
||||
'context_key' => $sContextKey,
|
||||
);
|
||||
if (!extension_loaded('gd'))
|
||||
{
|
||||
if (!extension_loaded('gd')) {
|
||||
// PDF export requires GD
|
||||
unset($aParams['export_as_pdf']);
|
||||
}
|
||||
if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey))
|
||||
{
|
||||
if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey)) {
|
||||
// Export as Attachment requires GD (for building the PDF) AND a valid objclass/objkey couple
|
||||
unset($aParams['export_as_attachment']);
|
||||
}
|
||||
$oP->add_ready_script("$('#$sId').simple_graph(".json_encode($aParams).");");
|
||||
if ($oP->IsPrintableVersion() || !$sLazyLoading) {
|
||||
$oP->add_ready_script(" $('#$sId').simple_graph(".json_encode($aParams).");");
|
||||
} else {
|
||||
$oP->add_script("function Load(){var aExcluded = []; $('input[name^=excluded]').each( function() {if (!$(this).prop('checked')) { aExcluded.push($(this).val()); }} ); var params= $.extend(".json_encode($aParams).", {excluded_classes: aExcluded}); $('#$sId').simple_graph(params);}");
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$oP->add('<div>'.$e->getMessage().'</div>');
|
||||
}
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
<<<EOF
|
||||
|
||||
function DoReload()
|
||||
{
|
||||
@@ -1611,5 +1544,95 @@ EOF
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $sContextKey
|
||||
* @param array $aContextParams
|
||||
* @param array $aExcludedObjects
|
||||
* @param \WebPage $oP
|
||||
* @param array $aResults
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function DisplayFiltering(string $sContextKey, array $aContextParams, array $aExcludedObjects, WebPage $oP, array $aResults, bool $sLazyLoading = false): array
|
||||
{
|
||||
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
|
||||
$aExcludedByClass = array();
|
||||
foreach ($aExcludedObjects as $oObj) {
|
||||
if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
|
||||
$aExcludedByClass[get_class($oObj)] = array();
|
||||
}
|
||||
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
|
||||
}
|
||||
$sSftShort = Dict::S('UI:ElementsDisplayed');
|
||||
$oP->add("<div class=\"not-printable\">\n");
|
||||
$oUiSearchBlock = new Panel($sSftShort, [], Panel::ENUM_COLOR_SCHEME_CYAN, 'dh_flash');
|
||||
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"]);
|
||||
$oUiSearchBlock->SetIsCollapsible(true);
|
||||
$oUiHtmlBlock = new Combodo\iTop\Application\UI\Base\Component\Html\Html(
|
||||
<<<EOF
|
||||
|
||||
<div id="ds_flash" class="search_box ibo-display-graph--search-box">
|
||||
<div id="dh_flash_criterion_outer" class="sf_criterion_area"><div class="sf_criterion_row">
|
||||
EOF
|
||||
);
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$("#dh_flash > .sf_title").on("click", function() {
|
||||
$("#dh_flash").toggleClass("closed");
|
||||
});
|
||||
$("#ReloadMovieBtn").button().button("disable");
|
||||
EOF
|
||||
);
|
||||
if ($sLazyLoading) {
|
||||
$oP->add_ready_script("$('#ReloadMovieBtn').button('enable');");
|
||||
} else {
|
||||
$oP->add_ready_script("$('#dh_flash').addClass('closed');");
|
||||
}
|
||||
$aSortedElements = array();
|
||||
foreach ($aResults as $sClassIdx => $aObjects) {
|
||||
foreach ($aObjects as $oCurrObj) {
|
||||
$sSubClass = get_class($oCurrObj);
|
||||
$aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass);
|
||||
}
|
||||
}
|
||||
|
||||
asort($aSortedElements);
|
||||
$idx = 0;
|
||||
foreach ($aSortedElements as $sSubClass => $sClassName) {
|
||||
$oUiHtmlBlock->AddHtml("<div><input type=\"checkbox\" id=\"exclude_$idx\" name=\"excluded[]\" value=\"$sSubClass\" checked onChange=\"$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_$idx\">");
|
||||
$oUiMedallionBlock = new MedallionIcon(MetaModel::GetClassIcon($sSubClass, false));
|
||||
$oUiMedallionBlock->SetDescription($sClassName);
|
||||
$oUiHtmlBlock->AddHtml(BlockRenderer::RenderBlockTemplates($oUiMedallionBlock));
|
||||
$oUiHtmlBlock->AddHtml("</label></div>");
|
||||
$idx++;
|
||||
}
|
||||
$oUiHtmlBlock->AddHtml("</div>");
|
||||
if ($sLazyLoading) {
|
||||
$sOnCLick = "Load(); $('#ReloadMovieBtn').attr('onclick','DoReload()');$('#ReloadMovieBtn').html('".Dict::S('UI:Button:Refresh')."');";
|
||||
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"$sOnCLick\">".Dict::S('Relation:impacts/LoadData')."</button></div></form>");
|
||||
} else {
|
||||
$sOnCLick = "DoReload()";
|
||||
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"$sOnCLick\">".Dict::S('UI:Button:Refresh')."</button></div></form>");
|
||||
}
|
||||
$oUiHtmlBlock->AddHtml("</div>\n");
|
||||
$oUiHtmlBlock->AddHtml("</div>\n"); // class="not-printable"
|
||||
|
||||
$oUiSearchBlock->AddSubBlock($oUiHtmlBlock);
|
||||
$oP->AddUiBlock($oUiSearchBlock);
|
||||
|
||||
$aAdditionalContexts = array();
|
||||
foreach ($aContextDefs as $sKey => $aDefinition) {
|
||||
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));
|
||||
}
|
||||
|
||||
return array($aExcludedByClass, $aAdditionalContexts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,16 +111,15 @@ class ExcelBulkExport extends TabularBulkExport
|
||||
|
||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="excel_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "excel_date_format_radio", "custom", "excel_date_time_format_custom", "radio");
|
||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||
$oRadioCustom->SetBeforeInput(false);
|
||||
$oRadioCustom->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||
$oFieldSetDate->AddSubBlock($oRadioCustom);
|
||||
|
||||
|
||||
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#excel_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
|
||||
$('#form_part_xlsx_options').on('preview_updated', function() { FormatDatesInPreview('excel', 'xlsx'); });
|
||||
$('#excel_date_time_format_default').on('click', function() { FormatDatesInPreview('excel', 'xlsx'); });
|
||||
$('#excel_date_time_format_custom').on('click', function() { FormatDatesInPreview('excel', 'xlsx'); });
|
||||
|
||||
@@ -542,14 +542,26 @@ class FileLog
|
||||
*/
|
||||
class LogChannels
|
||||
{
|
||||
public const CLI = 'CLI';
|
||||
public const CONSOLE = 'console';
|
||||
public const DEADLOCK = 'DeadLock';
|
||||
public const INLINE_IMAGE = 'InlineImage';
|
||||
public const PORTAL = 'portal';
|
||||
public const CMDB_SOURCE = 'cmdbsource';
|
||||
public const CORE = 'core';
|
||||
public const APC = 'apc';
|
||||
|
||||
public const CLI = 'CLI';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 2.7.7 N°4558 use this new channel when logging DB transactions
|
||||
* @since 3.0.0 logs info in CMDBSource (see commit a117906f)
|
||||
*/
|
||||
public const CMDB_SOURCE = 'cmdbsource';
|
||||
|
||||
public const CONSOLE = 'console';
|
||||
|
||||
public const CORE = 'core';
|
||||
|
||||
public const DEADLOCK = 'DeadLock';
|
||||
|
||||
public const INLINE_IMAGE = 'InlineImage';
|
||||
|
||||
public const PORTAL = 'portal';
|
||||
}
|
||||
|
||||
|
||||
@@ -992,6 +1004,11 @@ class DeadLockLog extends LogAPI
|
||||
class DeprecatedCallsLog extends LogAPI
|
||||
{
|
||||
public const ENUM_CHANNEL_PHP_METHOD = 'deprecated-php-method';
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const ENUM_CHANNEL_PHP_ENDPOINT = 'deprecated-php-endpoint';
|
||||
public const ENUM_CHANNEL_PHP_LIBMETHOD = 'deprecated-php-libmethod';
|
||||
public const ENUM_CHANNEL_FILE = 'deprecated-file';
|
||||
public const CHANNEL_DEFAULT = self::ENUM_CHANNEL_PHP_METHOD;
|
||||
@@ -1137,7 +1154,12 @@ class DeprecatedCallsLog extends LogAPI
|
||||
*/
|
||||
public static function NotifyDeprecatedFile(?string $sAdditionalMessage = null): void
|
||||
{
|
||||
if (!static::IsLogLevelEnabled(self::LEVEL_WARNING, self::ENUM_CHANNEL_FILE)) {
|
||||
try {
|
||||
if (!static::IsLogLevelEnabled(self::LEVEL_WARNING, self::ENUM_CHANNEL_FILE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ConfigException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1199,6 +1221,35 @@ class DeprecatedCallsLog extends LogAPI
|
||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sAdditionalMessage
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static function NotifyDeprecatedPhpEndpoint(?string $sAdditionalMessage = null): void
|
||||
{
|
||||
try {
|
||||
if (!static::IsLogLevelEnabled(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_ENDPOINT)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ConfigException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
|
||||
$iStackDeprecatedMethodLevel = 0; // level 0 = current method, level 1 = method containing the `NotifyDeprecatedPhpMethod` call
|
||||
$sDeprecatedUrl = $_SERVER['REQUEST_URI'];
|
||||
$sCallerFile = $aStack[$iStackDeprecatedMethodLevel]['file'];
|
||||
$sCallerLine = $aStack[$iStackDeprecatedMethodLevel]['line'];
|
||||
$sMessage = "Call to endpoint {$sDeprecatedUrl} in {$sCallerFile}#L{$sCallerLine}";
|
||||
|
||||
if (!is_null($sAdditionalMessage)) {
|
||||
$sMessage .= ' : '.$sAdditionalMessage;
|
||||
}
|
||||
|
||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_ENDPOINT);
|
||||
}
|
||||
|
||||
public static function Log($sLevel, $sMessage, $sChannel = null, $aContext = array()): void
|
||||
{
|
||||
if (true === utils::IsDevelopmentEnvironment()) {
|
||||
|
||||
@@ -655,7 +655,7 @@ abstract class MetaModel
|
||||
* @param string $sRuleId
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @since 2.6.1 N°1918 (sous les pavés, la plage) initialize in 'root_class' property the class that has the first
|
||||
* @since 2.6.1 N°1968 (sous les pavés, la plage) initialize in 'root_class' property the class that has the first
|
||||
* definition of the rule in the hierarchy
|
||||
*/
|
||||
private static function SetUniquenessRuleRootClass($sRootClass, $sRuleId)
|
||||
@@ -7145,20 +7145,28 @@ abstract class MetaModel
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param string $sAttCode
|
||||
* @param $value
|
||||
* @param mixed $value
|
||||
* @param bool $bMustBeFoundUnique
|
||||
* @param bool $bAllowAllData
|
||||
*
|
||||
* @return \DBObject if $bMustBeFoundUnique=true and no object or multiple objects found will throw a CoreException
|
||||
* else will return null
|
||||
*
|
||||
* @return \DBObject
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*
|
||||
* @since 2.7.7 Add new $bAllowAllData parameter
|
||||
*/
|
||||
public static function GetObjectByColumn($sClass, $sAttCode, $value, $bMustBeFoundUnique = true)
|
||||
public static function GetObjectByColumn($sClass, $sAttCode, $value, $bMustBeFoundUnique = true, $bAllowAllData = false)
|
||||
{
|
||||
if (!isset(self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value]))
|
||||
{
|
||||
if (!isset(self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value])) {
|
||||
self::_check_subclass($sClass);
|
||||
|
||||
$oObjSearch = new DBObjectSearch($sClass);
|
||||
$oObjSearch->AllowAllData($bAllowAllData);
|
||||
$oObjSearch->AddCondition($sAttCode, $value, '=');
|
||||
$oSet = new DBObjectSet($oObjSearch);
|
||||
if ($oSet->Count() == 1)
|
||||
|
||||
@@ -31,13 +31,13 @@ class iTopOwnershipToken extends DBObject
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
'category' => 'application',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('obj_class', 'obj_key'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array(''),
|
||||
'db_table' => 'priv_ownership_token',
|
||||
'db_key_field' => 'id',
|
||||
'category' => '',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('obj_class', 'obj_key'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array(''),
|
||||
'db_table' => 'priv_ownership_token',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => '',
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
|
||||
@@ -95,15 +95,14 @@ class PDFBulkExport extends HTMLBulkExport
|
||||
|
||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="pdf_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "pdf_date_format_radio", "custom", "pdf_date_time_format_custom", "radio");
|
||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||
$oRadioCustom->SetBeforeInput(false);
|
||||
$oRadioCustom->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||
$oFieldSetDate->AddSubBlock($oRadioCustom);
|
||||
|
||||
$sJSTooltip = json_encode('<div id="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#pdf_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
|
||||
$('#form_part_pdf_options').on('preview_updated', function() { FormatDatesInPreview('pdf', 'html'); });
|
||||
$('#pdf_date_time_format_default').on('click', function() { FormatDatesInPreview('pdf', 'html'); });
|
||||
$('#pdf_date_time_format_custom').on('click', function() { FormatDatesInPreview('pdf', 'html'); });
|
||||
|
||||
@@ -135,6 +135,7 @@ class ObjectResult
|
||||
*/
|
||||
class RestResultWithObjects extends RestResult
|
||||
{
|
||||
/** @var array "DBObject_class:DBObject_key" as key, {@see \ObjectResult} as value */
|
||||
public $objects;
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,15 +84,14 @@ class SpreadsheetBulkExport extends TabularBulkExport
|
||||
|
||||
$sFormatInput = '<input type="text" size="15" name="date_format" id="spreadsheet_custom_date_time_format" title="" value="'.htmlentities($sDateTimeFormat, ENT_QUOTES, 'UTF-8').'"/>';
|
||||
$oRadioCustom = InputUIBlockFactory::MakeForInputWithLabel(Dict::Format('Core:BulkExport:DateTimeFormatCustom_Format', $sFormatInput), "spreadsheet_date_format_radio", "custom", "spreadsheet_date_time_format_custom", "radio");
|
||||
$oRadioCustom->SetDescription(Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip'));
|
||||
$oRadioCustom->GetInput()->SetIsChecked($sDateTimeFormat !== (string)AttributeDateTime::GetFormat());
|
||||
$oRadioCustom->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||
$oRadioCustom->SetBeforeInput(false);
|
||||
$oFieldSetDate->AddSubBlock($oRadioCustom);
|
||||
|
||||
$sJSTooltip = json_encode('<div class="date_format_tooltip">'.Dict::S('UI:CSVImport:CustomDateTimeFormatTooltip').'</div>');
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#spreadsheet_custom_date_time_format').tooltip({content: function() { return $sJSTooltip; } });
|
||||
$('#form_part_spreadsheet_options').on('preview_updated', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); });
|
||||
$('#spreadsheet_date_time_format_default').on('click', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); });
|
||||
$('#spreadsheet_date_time_format_custom').on('click', function() { FormatDatesInPreview('spreadsheet', 'spreadsheet'); });
|
||||
|
||||
@@ -494,7 +494,17 @@ class SQLObjectQuery extends SQLQuery
|
||||
}
|
||||
}
|
||||
|
||||
private function PrepareSingleTable(SQLObjectQuery $oRootQuery, &$aFrom, $sCallerAlias = '', $aJoinData)
|
||||
/**
|
||||
* @param \SQLObjectQuery $oRootQuery
|
||||
* @param $aFrom
|
||||
* @param $sCallerAlias
|
||||
* @param $aJoinData
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $sCallerAlias for PHP 8.0 compat (Private method with only 2 calls in the class, both providing the optional parameter)
|
||||
*/
|
||||
private function PrepareSingleTable(SQLObjectQuery $oRootQuery, &$aFrom, $sCallerAlias, $aJoinData)
|
||||
{
|
||||
$aTranslationTable[$this->m_sTable]['*'] = $this->m_sTableAlias;
|
||||
$sJoinCond = '';
|
||||
@@ -613,6 +623,7 @@ class SQLObjectQuery extends SQLQuery
|
||||
$aTempFrom = array(); // temporary subset of 'from' specs, to be grouped in the final query
|
||||
foreach ($this->m_aJoinSelects as $aJoinData)
|
||||
{
|
||||
/** @var \SQLObjectQuery $oRightSelect */
|
||||
$oRightSelect = $aJoinData["select"];
|
||||
|
||||
$oRightSelect->PrepareSingleTable($oRootQuery, $aTempFrom, $this->m_sTableAlias, $aJoinData);
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
*/
|
||||
|
||||
@import "collapsible-section-with-blocks";
|
||||
@import "collapsible-section-within-caselog-list";
|
||||
@import "collapsible-section-within-caselog-list";
|
||||
@import "collapsible-section-within-alert";
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
/* SCSS variables */
|
||||
$ibo-collapsible-section-within-alert--body--padding: $ibo-spacing-300 !default;
|
||||
$ibo-collapsible-section-within-alert--body--text-color: $ibo-color-grey-900 !default;
|
||||
|
||||
.ibo-alert--body {
|
||||
.ibo-collapsible-section {
|
||||
.ibo-collapsible-section--header .ibo-collapsible-section--title,
|
||||
.ibo-collapsible-section--body {
|
||||
@extend %ibo-font-size-150;
|
||||
}
|
||||
|
||||
.ibo-collapsible-section--body {
|
||||
color: $ibo-collapsible-section-within-alert--body--text-color;
|
||||
padding: $ibo-collapsible-section-within-alert--body--padding;
|
||||
}
|
||||
}
|
||||
> * + .ibo-collapsible-section {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@import "field-with-field";
|
||||
@import "field-with-field";
|
||||
@import "field-with-fieldset";
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-field--spacing-top--with-fieldset: $ibo-spacing-700 !default;
|
||||
|
||||
.ibo-fieldset + .ibo-field {
|
||||
margin-top: $ibo-field--spacing-top--with-fieldset;
|
||||
}
|
||||
@@ -3,5 +3,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@import "fieldset-with-field";
|
||||
@import "fieldset-with-fieldset";
|
||||
@import "fieldset-with-multicolumn";
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-fieldset--spacing-top--with-field: $ibo-spacing-700 !default;
|
||||
|
||||
.ibo-field + .ibo-fieldset:not(.ibo-column) {
|
||||
margin-top: $ibo-fieldset--spacing-top--with-field;
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-fieldset--spacing-left--with-fieldset: $ibo-spacing-800 !default;
|
||||
$ibo-fieldset--spacing-top--with-fieldset: $ibo-spacing-800 !default;
|
||||
|
||||
.ibo-fieldset + .ibo-fieldset:not(.ibo-column) {
|
||||
margin-top: $ibo-fieldset--spacing-left--with-fieldset;
|
||||
margin-top: $ibo-fieldset--spacing-top--with-fieldset;
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-fieldset--spacing-left--with-multicolumn: $ibo-spacing-800 !default;
|
||||
$ibo-fieldset--spacing-top--with-multicolumn: $ibo-spacing-800 !default;
|
||||
|
||||
|
||||
.ibo-multi-column + .ibo-fieldset {
|
||||
margin-top: $ibo-fieldset--spacing-left--with-multicolumn;
|
||||
margin-top: $ibo-fieldset--spacing-top--with-multicolumn;
|
||||
}
|
||||
|
||||
@@ -11,4 +11,18 @@ $ibo-input--spacing-left--with-label: $ibo-spacing-300 !default;
|
||||
select + label, label + select, label > select,
|
||||
input + label, label + input, label > input {
|
||||
margin-left: $ibo-input--spacing-left--with-label;
|
||||
}
|
||||
|
||||
.ibo-input-with-label--label {
|
||||
&.ibo-has-description {
|
||||
&::after {
|
||||
content: $ibo-field--label--description--content;
|
||||
padding-left: $ibo-field--label--description--padding-left;
|
||||
vertical-align: top;
|
||||
|
||||
cursor: pointer;
|
||||
color: $ibo-field--label--description--color;
|
||||
@extend %ibo-font-ral-bol-50;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,6 +479,22 @@ $ibo-button-colors: (
|
||||
&.ibo-action-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ibo-button--loading-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.ibo-is-loading {
|
||||
.ibo-button--icon{
|
||||
display: none;
|
||||
}
|
||||
.ibo-button--loading-icon {
|
||||
display: inline-block;
|
||||
&+ .ibo-button--label{
|
||||
margin-left: $ibo-button--label--margin-left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-button--label {
|
||||
|
||||
@@ -122,6 +122,7 @@ $ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-datatable--selected-count{
|
||||
.ibo-datatable--selected-count, .ibo-datatable--result-count{
|
||||
padding-right: 0.2em;
|
||||
padding-left: 0.1em;
|
||||
}
|
||||
@@ -345,6 +345,7 @@ $ibo-search-results-area--datatable-scrollhead--border--is-sticking: $ibo-search
|
||||
/* Form group (operators) is displayed only when the criteria is toggled to opened state */
|
||||
display: none;
|
||||
max-width: 450px;
|
||||
width: max-content;
|
||||
max-height: 520px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
@@ -374,7 +375,7 @@ $ibo-search-results-area--datatable-scrollhead--border--is-sticking: $ibo-search
|
||||
}
|
||||
|
||||
.sfc_op_name {
|
||||
width: 90px;
|
||||
width: 96px;
|
||||
}
|
||||
|
||||
.sfc_op_content {
|
||||
|
||||
@@ -8,6 +8,8 @@ $ibo-title--padding-y: $ibo-spacing-400 !default;
|
||||
$ibo-title--padding-x: $ibo-spacing-0 !default;
|
||||
|
||||
$ibo-title--icon--size: 90px !default;
|
||||
$ibo-title--icon--size-2: 80px !default;
|
||||
$ibo-title--icon--size-3: 70px !default;
|
||||
|
||||
$ibo-title--icon-background--size--must-contain: contain !default;
|
||||
$ibo-title--icon-background--size--must-cover: cover !default;
|
||||
@@ -29,6 +31,18 @@ $ibo-title--icon-background--size--must-zoomout: 66.67% !default;
|
||||
min-height: $ibo-title--icon--size;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ibo-title--icon > .ibo-title--icon-level-2{
|
||||
width: $ibo-title--icon--size-2;
|
||||
height: $ibo-title--icon--size-2;
|
||||
min-width: $ibo-title--icon--size-2;
|
||||
min-height: $ibo-title--icon--size-2;
|
||||
}
|
||||
.ibo-title--icon > .ibo-title--icon-level-3{
|
||||
width: $ibo-title--icon--size-3;
|
||||
height: $ibo-title--icon--size-3;
|
||||
min-width: $ibo-title--icon--size-3;
|
||||
min-height: $ibo-title--icon--size-3;
|
||||
}
|
||||
|
||||
.ibo-title--icon-background {
|
||||
width: 100%;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-input-image--image-view--min-height: 96px !default;
|
||||
$ibo-input-image--image-view--background-color: $ibo-color-grey-200 !default;
|
||||
$ibo-input-image--image-view--border-radius: $ibo-border-radius-500 !default;
|
||||
|
||||
@@ -18,6 +19,7 @@ $ibo-input-image--edit-buttons--elements-spacing: $ibo-input-image--edit-buttons
|
||||
.ibo-input-image--image-view {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-height: $ibo-input-image--image-view--min-height;
|
||||
background-color: $ibo-input-image--image-view--background-color;
|
||||
border-radius: $ibo-input-image--image-view--border-radius;
|
||||
@extend %ibo-fully-centered-content;
|
||||
|
||||
@@ -64,6 +64,8 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
|
||||
color: inherit;
|
||||
border-color: $ibo-color-white-100;
|
||||
padding-left: $ibo-input-select--padding-x;
|
||||
|
||||
@extend %ibo-font-ral-nor-150;
|
||||
}
|
||||
|
||||
> [data-value] {
|
||||
@@ -102,6 +104,13 @@ $ibo-input-select--autocomplete-item-image--border: 1px solid $ibo-color-grey-60
|
||||
> input {
|
||||
background-color: unset;
|
||||
border: unset;
|
||||
&:focus{
|
||||
outline: none !important; /* Overwrite browsers default focus outline */
|
||||
}
|
||||
}
|
||||
|
||||
&.input-active{
|
||||
border: 1px solid $ibo-input--focus--border-color;
|
||||
}
|
||||
}
|
||||
.ibo-input-select-wrapper{
|
||||
|
||||
@@ -22,7 +22,6 @@ $ibo-input--placeholder--color: $ibo-color-grey-600 !default;
|
||||
$ibo-input--disabled--background-color: $ibo-color-grey-300 !default;
|
||||
$ibo-input--placeholder--color: $ibo-color-grey-700 !default;
|
||||
|
||||
$ibo-input-wrapper--is-error--background-color: $ibo-color-red-200 !default;
|
||||
$ibo-input-wrapper--is-error--border-color: $ibo-color-red-600 !default;
|
||||
$ibo-field-validation: $ibo-color-red-700 !default;
|
||||
|
||||
@@ -38,6 +37,8 @@ $ibo-input--margin-x: $ibo-spacing-200 !default;
|
||||
border: 1px solid $ibo-input--border-color;
|
||||
border-radius: $ibo-input--border-radius;
|
||||
|
||||
@extend %ibo-font-ral-nor-150;
|
||||
|
||||
&:focus{
|
||||
border: 1px solid $ibo-input--focus--border-color;
|
||||
}
|
||||
@@ -55,7 +56,6 @@ textarea.ibo-input{
|
||||
.ibo-input-wrapper.is-error, .ibo-input-field-wrapper.is-error {
|
||||
.ibo-input, .ibo-input-vanilla, .cke, textarea {
|
||||
border: 1px solid $ibo-input-wrapper--is-error--border-color;
|
||||
background-color: $ibo-input-wrapper--is-error--background-color;
|
||||
}
|
||||
.ibo-input-vanilla input{
|
||||
border: 0;
|
||||
|
||||
@@ -41,6 +41,12 @@ $ibo-activity-panel--tab-title-decoration--border-radius: $ibo-border-radius-300
|
||||
|
||||
$ibo-activity-panel--tab-title-draft-indicator--margin-x: $ibo-activity-panel--tab-title-decoration--margin-right !default;
|
||||
|
||||
$ibo-activity-panel--tab-title-messages-count--margin-left: $ibo-activity-panel--tab-title-draft-indicator--margin-x !default;
|
||||
$ibo-activity-panel--tab-title-messages-count--background-color: $ibo-color-grey-200 !default;
|
||||
$ibo-activity-panel--tab-title-messages-count--padding-x: $ibo-spacing-200 !default;
|
||||
$ibo-activity-panel--tab-title-messages-count--padding-y: $ibo-spacing-0 !default;
|
||||
$ibo-activity-panel--tab-title-messages-count--border-radius: $ibo-border-radius-300 !default;
|
||||
|
||||
$ibo-activity-panel--tab-title-text--max-width: 100px !default;
|
||||
|
||||
/* - Tab toolbar */
|
||||
@@ -180,6 +186,9 @@ $ibo-activity-panel--open-icon--margin-left: 0.75rem !default;
|
||||
.ibo-activity-panel--tab-title{
|
||||
background-color: $ibo-activity-panel--tab-title--is-active--background-color;
|
||||
}
|
||||
.ibo-activity-panel--tab-title-messages-count{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.ibo-is-draft{
|
||||
.ibo-activity-panel--tab-title-draft-indicator{
|
||||
@@ -213,6 +222,17 @@ $ibo-activity-panel--open-icon--margin-left: 0.75rem !default;
|
||||
border-radius: $ibo-activity-panel--tab-title-decoration--border-radius;
|
||||
@extend %ibo-depression-100;
|
||||
}
|
||||
.ibo-activity-panel--tab-title-messages-count{
|
||||
display: inline-block;
|
||||
margin-left: $ibo-activity-panel--tab-title-messages-count--margin-left;
|
||||
background-color: $ibo-activity-panel--tab-title-messages-count--background-color;
|
||||
padding: $ibo-activity-panel--tab-title-messages-count--padding-y $ibo-activity-panel--tab-title-messages-count--padding-x;
|
||||
border-radius: $ibo-activity-panel--tab-title-messages-count--border-radius;
|
||||
|
||||
&[data-messages-count="0"]{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.ibo-activity-panel--tab-title-draft-indicator{
|
||||
display: none;
|
||||
margin-left: $ibo-activity-panel--tab-title-draft-indicator--margin-x;
|
||||
|
||||
@@ -12,4 +12,5 @@
|
||||
@import "datamodel-viewer";
|
||||
@import "csv-import";
|
||||
@import "global-search";
|
||||
@import "run-query";
|
||||
@import "welcome-popup";
|
||||
10
css/backoffice/pages/_run-query.scss
Normal file
10
css/backoffice/pages/_run-query.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2021 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-run-query--highlight--background-color: $ibo-color-primary-300 !default;
|
||||
|
||||
.ibo-run-query--highlight{
|
||||
background-color: $ibo-run-query--highlight--background-color;
|
||||
}
|
||||
@@ -134,6 +134,9 @@ body.ibo-has-fullscreen-descendant {
|
||||
@extend %ibo-font-code-150;
|
||||
}
|
||||
|
||||
.ibo-add-margin-top-250{
|
||||
margin-top: $ibo-spacing-400;
|
||||
}
|
||||
/*
|
||||
* A single class to handle WYSIWYG generated content, where only HTML tags are available
|
||||
* See https://bulma.io/documentation/elements/content/
|
||||
@@ -158,7 +161,7 @@ body.ibo-has-fullscreen-descendant {
|
||||
|
||||
/* Preserve original text color in code blocks, except for the Highlight.js blocks which have their own colors */
|
||||
& > code,
|
||||
:not(pre.hljs) code {
|
||||
code:not(.hljs) {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
4
css/backoffice/vendors/_ckeditor.scss
vendored
4
css/backoffice/vendors/_ckeditor.scss
vendored
@@ -52,6 +52,10 @@ $ibo-vendors-ckeditor--autocomplete-item-title--text-color: #3A3A3A !default;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.ibo-hljs-container{
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Mentions in caselogs */
|
||||
/* Note: Mind the "ul", it allows us to have a more precise rule than the original plugin's CSS so we can override it */
|
||||
ul.cke_autocomplete_panel{
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
// Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0
|
||||
$version: "v2.7.7";
|
||||
$approot-relative: "../../../../" !default; // relative to env-***/branding/themes/***/main.css
|
||||
|
||||
// Base colors
|
||||
|
||||
@@ -29,6 +29,8 @@ use utils;
|
||||
*/
|
||||
class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExtension, iLoginUIExtension
|
||||
{
|
||||
const LOGIN_MODE = 'cas';
|
||||
|
||||
/**
|
||||
* Return the list of supported login modes for this plugin
|
||||
*
|
||||
@@ -36,7 +38,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
*/
|
||||
public function ListSupportedLoginModes()
|
||||
{
|
||||
return array('cas');
|
||||
return array(static::LOGIN_MODE);
|
||||
}
|
||||
|
||||
protected function OnStart(&$iErrorCode)
|
||||
@@ -47,12 +49,12 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
|
||||
protected function OnReadCredentials(&$iErrorCode)
|
||||
{
|
||||
if (Session::Get('login_mode') == 'cas')
|
||||
if (empty(Session::Get('login_mode')) || Session::Get('login_mode') == static::LOGIN_MODE)
|
||||
{
|
||||
static::InitCASClient();
|
||||
if (phpCAS::isAuthenticated())
|
||||
{
|
||||
Session::Set('login_mode', 'cas');
|
||||
Session::Set('login_mode', static::LOGIN_MODE);
|
||||
Session::Set('auth_user', phpCAS::getUser());
|
||||
Session::Unset('login_will_redirect');
|
||||
}
|
||||
@@ -68,7 +70,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
$iErrorCode = LoginWebPage::EXIT_CODE_MISSINGLOGIN;
|
||||
return LoginWebPage::LOGIN_FSM_ERROR;
|
||||
}
|
||||
Session::Set('login_mode', 'cas');
|
||||
Session::Set('login_mode', static::LOGIN_MODE);
|
||||
phpCAS::forceAuthentication(); // Redirect to CAS and exit
|
||||
}
|
||||
}
|
||||
@@ -77,7 +79,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
|
||||
protected function OnCheckCredentials(&$iErrorCode)
|
||||
{
|
||||
if (Session::Get('login_mode') == 'cas')
|
||||
if (Session::Get('login_mode') == static::LOGIN_MODE)
|
||||
{
|
||||
if (!Session::IsSet('auth_user'))
|
||||
{
|
||||
@@ -94,7 +96,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
|
||||
protected function OnCredentialsOK(&$iErrorCode)
|
||||
{
|
||||
if (Session::Get('login_mode') == 'cas')
|
||||
if (Session::Get('login_mode') == static::LOGIN_MODE)
|
||||
{
|
||||
$sAuthUser = Session::Get('auth_user');
|
||||
if (!LoginWebPage::CheckUser($sAuthUser))
|
||||
@@ -109,7 +111,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
|
||||
protected function OnError(&$iErrorCode)
|
||||
{
|
||||
if (Session::Get('login_mode') == 'cas')
|
||||
if (Session::Get('login_mode') == static::LOGIN_MODE)
|
||||
{
|
||||
Session::Unset('phpCAS');
|
||||
if ($iErrorCode != LoginWebPage::EXIT_CODE_MISSINGLOGIN)
|
||||
@@ -124,7 +126,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
|
||||
protected function OnConnected(&$iErrorCode)
|
||||
{
|
||||
if (Session::Get('login_mode') == 'cas')
|
||||
if (Session::Get('login_mode') == static::LOGIN_MODE)
|
||||
{
|
||||
Session::Set('can_logoff', true);
|
||||
return LoginWebPage::CheckLoggedUser($iErrorCode);
|
||||
@@ -205,7 +207,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
|
||||
$oLoginContext->SetLoaderPath(APPROOT.'env-'.utils::GetCurrentEnvironment().'/authent-cas/view');
|
||||
|
||||
$aData = array(
|
||||
'sLoginMode' => 'cas',
|
||||
'sLoginMode' => static::LOGIN_MODE,
|
||||
'sLabel' => Dict::S('CAS:Login:SignIn'),
|
||||
'sTooltip' => Dict::S('CAS:Login:SignInTooltip'),
|
||||
);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
@@ -30,11 +29,9 @@
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Class:UserLocal' => 'Użytkownik '.ITOP_APPLICATION_SHORT,
|
||||
'Class:UserLocal+' => 'Użytkownik uwierzytelniony przez '.ITOP_APPLICATION_SHORT,
|
||||
@@ -49,10 +46,13 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'Class:UserLocal/Attribute:expiration/Value:never_expire+' => '',
|
||||
'Class:UserLocal/Attribute:expiration/Value:force_expire' => 'Wygasło',
|
||||
'Class:UserLocal/Attribute:expiration/Value:force_expire+' => '',
|
||||
'Class:UserLocal/Attribute:expiration/Value:otp_expire' => 'One-time Password~~',
|
||||
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => 'Password cannot be changed by the user.~~',
|
||||
'Class:UserLocal/Attribute:password_renewed_date' => 'Odnowienie hasła',
|
||||
'Class:UserLocal/Attribute:password_renewed_date+' => 'Kiedy ostatnio zmieniano hasło',
|
||||
|
||||
'Error:UserLocalPasswordValidator:UserPasswordPolicyRegex:ValidationFailed' => 'Hasło musi mieć co najmniej 8 znaków i zawierać duże, małe litery, cyfry i znaki specjalne.',
|
||||
|
||||
'UserLocal:password:expiration' => 'Poniższe pola wymagają rozszerzenia'
|
||||
'UserLocal:password:expiration' => 'Poniższe pola wymagają rozszerzenia',
|
||||
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => 'Setting password expiration to "One-time password" is not allowed for your own User~~',
|
||||
));
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -183,6 +183,9 @@ $ibo-tab-container--tabs-list--background-color: $ibo-color-grey-500;
|
||||
$ibo-tab-container--tab-header--text-color--is-active: $ibo-color-blue-300;
|
||||
$ibo-tab-container--tab-header--text-color--on-hover: $ibo-color-blue-200;
|
||||
$ibo-tab-container--tab-header--background-color--on-hover: $ibo-color-grey-400;
|
||||
$ibo-tab-container--extra-tab-toggler--text-color: $ibo-color-blue-100 !default;
|
||||
$ibo-tab-container--extra-tab-toggler--text-color--on-hover: $ibo-color-blue-200 !default;
|
||||
$ibo-tab-container--extra-tab-toggler--background-color--on-hover: $ibo-color-grey-500 !default;
|
||||
$ibo-activity-panel--header--background-color: $ibo-color-grey-400;
|
||||
$ibo-activity-panel--tab-toggler--is-active--background-color: $ibo-color-grey-200;
|
||||
$ibo-activity-panel--tab-toolbar--background-color: $ibo-activity-panel--tab-toggler--is-active--background-color;
|
||||
@@ -244,3 +247,5 @@ $ibo-vendors-c3--legend--fill: $ibo-color-white-200;
|
||||
$ibo-vendors-c3--legend--background-color: $ibo-color-white-100;
|
||||
$ibo-vendors-c3--legend-item--fill: $ibo-color-grey-100;
|
||||
$ibo-vendors-c3--axis--fill: $ibo-color-grey-200;
|
||||
|
||||
$ibo-run-query--highlight--background-color: $ibo-color-primary-700;
|
||||
@@ -1,90 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Database inconsistencies
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
// Dictionary entries go here
|
||||
'Menu:DBToolsMenu' => 'Integralność bazy danych',
|
||||
'DBTools:Class' => 'Klasa',
|
||||
'DBTools:Title' => 'Narzędzia do konserwacji bazy danych',
|
||||
'DBTools:ErrorsFound' => 'Znalezione błędy',
|
||||
'DBTools:Error' => 'Błąd',
|
||||
'DBTools:Count' => 'Liczba',
|
||||
'DBTools:SQLquery' => 'Zapytanie SQL',
|
||||
'DBTools:FixitSQLquery' => 'Zapytanie SQL, aby to naprawić (wskazanie)',
|
||||
'DBTools:SQLresult' => 'Wynik SQL',
|
||||
'DBTools:NoError' => 'Baza danych jest w porządku',
|
||||
'DBTools:HideIds' => 'Lista błędów',
|
||||
'DBTools:ShowIds' => 'Widok szczegółowy',
|
||||
'DBTools:ShowReport' => 'Raport',
|
||||
'DBTools:IntegrityCheck' => 'Sprawdzanie integralności',
|
||||
'DBTools:FetchCheck' => 'Sprawdzenie przestrzeni (długie)',
|
||||
|
||||
'DBTools:Analyze' => 'Analiza',
|
||||
'DBTools:Details' => 'Pokaż szczegóły',
|
||||
'DBTools:ShowAll' => 'Pokaż wszystkie błędy',
|
||||
|
||||
'DBTools:Inconsistencies' => 'Niespójności bazy danych',
|
||||
|
||||
'DBAnalyzer-Integrity-OrphanRecord' => 'Osierocony rekord w `%1$s`, powinien mieć swój odpowiednik w tabeli `%2$s`',
|
||||
'DBAnalyzer-Integrity-InvalidExtKey' => 'Nieprawidłowy klucz zewnętrzny %1$s (kolumna: `%2$s.%3$s`)',
|
||||
'DBAnalyzer-Integrity-MissingExtKey' => 'Brak klucza zewnętrznego %1$s (kolumna: `%2$s.%3$s`)',
|
||||
'DBAnalyzer-Integrity-InvalidValue' => 'Nieprawidłowa wartość dla %1$s (kolumna: `%2$s.%3$s`)',
|
||||
'DBAnalyzer-Integrity-UsersWithoutProfile' => 'Niektóre konta użytkowników w ogóle nie mają profilu',
|
||||
'DBAnalyzer-Fetch-Count-Error' => 'Błąd liczby wpisów w `%1$s`, %2$d pobrane wpisy / %3$d obliczone',
|
||||
'DBAnalyzer-Integrity-FinalClass' => 'Pole `%2$s`.`%1$s` musi mieć taką samą wartość jak `%3$s`.`%1$s`',
|
||||
'DBAnalyzer-Integrity-RootFinalClass' => 'Pole `%2$s`.`%1$s` musi zawierać prawidłową klasę',
|
||||
));
|
||||
|
||||
// Database Info
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'DBTools:DatabaseInfo' => 'Informacje o bazie danych',
|
||||
'DBTools:Base' => 'Baza',
|
||||
'DBTools:Size' => 'Rozmiar',
|
||||
));
|
||||
|
||||
// Lost attachments
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'DBTools:LostAttachments' => 'Utracone załączniki',
|
||||
'DBTools:LostAttachments:Disclaimer' => 'Tutaj możesz przeszukiwać bazę danych w poszukiwaniu zagubionych załączników. To NIE jest narzędzie do odzyskiwania danych, nie pobiera usuniętych danych.',
|
||||
|
||||
'DBTools:LostAttachments:Button:Analyze' => 'Analiza',
|
||||
'DBTools:LostAttachments:Button:Restore' => 'Przywróć',
|
||||
'DBTools:LostAttachments:Button:Restore:Confirm' => 'Tej czynności nie można cofnąć, potwierdź, że chcesz przywrócić wybrane pliki.',
|
||||
'DBTools:LostAttachments:Button:Busy' => 'Proszę czekać...',
|
||||
|
||||
'DBTools:LostAttachments:Step:Analyze' => 'Najpierw wyszukaj zagubione załączniki, analizując bazę danych.',
|
||||
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults' => 'Wynik analizy:',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:None' => 'Świetnie! Wszystko wydaje się być na właściwym miejscu.',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Some' => 'Niektóre załączniki (%1$d) wydają się być zagubione. Spójrz na poniższą listę i zaznacz te, które chcesz przenieść.',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Item:Filename' => 'Nazwa pliku',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Item:CurrentLocation' => 'Aktualna lokalizacja',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Item:TargetLocation' => 'Przenieś do...',
|
||||
|
||||
'DBTools:LostAttachments:Step:RestoreResults' => 'Wyniki przywracania:',
|
||||
'DBTools:LostAttachments:Step:RestoreResults:Results' => '%1$d/%2$d załączniki zostały przywrócone.',
|
||||
|
||||
'DBTools:LostAttachments:StoredAsInlineImage' => 'Zapisane jako obraz w treści',
|
||||
'DBTools:LostAttachments:History' => 'Załącznik "%1$s" przywrócony za pomocą narzędzi DB'
|
||||
));
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
// Database inconsistencies
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
// Dictionary entries go here
|
||||
'Menu:DBToolsMenu' => 'Integralność bazy danych',
|
||||
'DBTools:Class' => 'Klasa',
|
||||
'DBTools:Title' => 'Narzędzia do konserwacji bazy danych',
|
||||
'DBTools:ErrorsFound' => 'Znalezione błędy',
|
||||
'DBTools:Indication' => 'Important: after fixing errors in the database you\'ll have to run the analysis again as new inconsistencies will be generated~~',
|
||||
'DBTools:Disclaimer' => 'DISCLAIMER: BACKUP YOUR DATABASE BEFORE RUNNING THE FIXES~~',
|
||||
'DBTools:Error' => 'Błąd',
|
||||
'DBTools:Count' => 'Liczba',
|
||||
'DBTools:SQLquery' => 'Zapytanie SQL',
|
||||
'DBTools:FixitSQLquery' => 'Zapytanie SQL, aby to naprawić (wskazanie)',
|
||||
'DBTools:SQLresult' => 'Wynik SQL',
|
||||
'DBTools:NoError' => 'Baza danych jest w porządku',
|
||||
'DBTools:HideIds' => 'Lista błędów',
|
||||
'DBTools:ShowIds' => 'Widok szczegółowy',
|
||||
'DBTools:ShowReport' => 'Raport',
|
||||
'DBTools:IntegrityCheck' => 'Sprawdzanie integralności',
|
||||
'DBTools:FetchCheck' => 'Sprawdzenie przestrzeni (długie)',
|
||||
'DBTools:SelectAnalysisType' => 'Select analysis type~~',
|
||||
|
||||
'DBTools:Analyze' => 'Analiza',
|
||||
'DBTools:Details' => 'Pokaż szczegóły',
|
||||
'DBTools:ShowAll' => 'Pokaż wszystkie błędy',
|
||||
|
||||
'DBTools:Inconsistencies' => 'Niespójności bazy danych',
|
||||
'DBTools:DetailedErrorTitle' => '%2$s error(s) in class %1$s: %3$s~~',
|
||||
|
||||
'DBAnalyzer-Integrity-OrphanRecord' => 'Osierocony rekord w `%1$s`, powinien mieć swój odpowiednik w tabeli `%2$s`',
|
||||
'DBAnalyzer-Integrity-InvalidExtKey' => 'Nieprawidłowy klucz zewnętrzny %1$s (kolumna: `%2$s.%3$s`)',
|
||||
'DBAnalyzer-Integrity-MissingExtKey' => 'Brak klucza zewnętrznego %1$s (kolumna: `%2$s.%3$s`)',
|
||||
'DBAnalyzer-Integrity-InvalidValue' => 'Nieprawidłowa wartość dla %1$s (kolumna: `%2$s.%3$s`)',
|
||||
'DBAnalyzer-Integrity-UsersWithoutProfile' => 'Niektóre konta użytkowników w ogóle nie mają profilu',
|
||||
'DBAnalyzer-Integrity-HKInvalid' => 'Broken hierarchical key `%1$s`~~',
|
||||
'DBAnalyzer-Fetch-Count-Error' => 'Błąd liczby wpisów w `%1$s`, %2$d pobrane wpisy / %3$d obliczone',
|
||||
'DBAnalyzer-Integrity-FinalClass' => 'Pole `%2$s`.`%1$s` musi mieć taką samą wartość jak `%3$s`.`%1$s`',
|
||||
'DBAnalyzer-Integrity-RootFinalClass' => 'Pole `%2$s`.`%1$s` musi zawierać prawidłową klasę',
|
||||
));
|
||||
|
||||
// Database Info
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'DBTools:DatabaseInfo' => 'Informacje o bazie danych',
|
||||
'DBTools:Base' => 'Baza',
|
||||
'DBTools:Size' => 'Rozmiar',
|
||||
));
|
||||
|
||||
// Lost attachments
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
'DBTools:LostAttachments' => 'Utracone załączniki',
|
||||
'DBTools:LostAttachments:Disclaimer' => 'Tutaj możesz przeszukiwać bazę danych w poszukiwaniu zagubionych załączników. To NIE jest narzędzie do odzyskiwania danych, nie pobiera usuniętych danych.',
|
||||
|
||||
'DBTools:LostAttachments:Button:Analyze' => 'Analiza',
|
||||
'DBTools:LostAttachments:Button:Restore' => 'Przywróć',
|
||||
'DBTools:LostAttachments:Button:Restore:Confirm' => 'Tej czynności nie można cofnąć, potwierdź, że chcesz przywrócić wybrane pliki.',
|
||||
'DBTools:LostAttachments:Button:Busy' => 'Proszę czekać...',
|
||||
|
||||
'DBTools:LostAttachments:Step:Analyze' => 'Najpierw wyszukaj zagubione załączniki, analizując bazę danych.',
|
||||
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults' => 'Wynik analizy:',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:None' => 'Świetnie! Wszystko wydaje się być na właściwym miejscu.',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Some' => 'Niektóre załączniki (%1$d) wydają się być zagubione. Spójrz na poniższą listę i zaznacz te, które chcesz przenieść.',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Item:Filename' => 'Nazwa pliku',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Item:CurrentLocation' => 'Aktualna lokalizacja',
|
||||
'DBTools:LostAttachments:Step:AnalyzeResults:Item:TargetLocation' => 'Przenieś do...',
|
||||
|
||||
'DBTools:LostAttachments:Step:RestoreResults' => 'Wyniki przywracania:',
|
||||
'DBTools:LostAttachments:Step:RestoreResults:Results' => '%1$d/%2$d załączniki zostały przywrócone.',
|
||||
|
||||
'DBTools:LostAttachments:StoredAsInlineImage' => 'Zapisane jako obraz w treści',
|
||||
'DBTools:LostAttachments:History' => 'Załącznik "%1$s" przywrócony za pomocą narzędzi DB'
|
||||
));
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
<module>combodo-db-tools</module>
|
||||
<module>itop-core-update</module>
|
||||
<module>itop-hub-connector</module>
|
||||
<module>combodo-backoffice-darkmoon-theme</module>
|
||||
<module>combodo-backoffice-darkmoon-theme</module>
|
||||
<module>itop-themes-compat</module>
|
||||
</modules>
|
||||
<mandatory>true</mandatory>
|
||||
</choice>
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
|
||||
require_once('../../approot.inc.php');
|
||||
require_once(APPROOT.'/application/application.inc.php');
|
||||
require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
|
||||
|
||||
/**
|
||||
* @param \ajax_page $oPage
|
||||
* @param \AjaxPage $oPage
|
||||
* @param int $iTransactionId
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
function RenderAttachments(ajax_page $oPage, $iTransactionId)
|
||||
function RenderAttachments(AjaxPage $oPage, $iTransactionId)
|
||||
{
|
||||
$sClass = utils::ReadParam('objclass', '', false, 'class');
|
||||
$sId = utils::ReadParam('objkey', '');
|
||||
@@ -59,7 +58,7 @@ try
|
||||
require_once APPROOT.'/application/loginwebpage.class.inc.php';
|
||||
LoginWebPage::DoLoginEx(null /* any portal */, false);
|
||||
|
||||
$oPage = new ajax_page("");
|
||||
$oPage = new AjaxPage("");
|
||||
|
||||
$sOperation = utils::ReadParam('operation', '');
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ abstract class AbstractAttachmentsRenderer
|
||||
function RefreshAttachmentsDisplay(dataUpload)
|
||||
{
|
||||
var sContentNode = '#AttachmentsListContainer',
|
||||
aAttachmentsDeletedHiddenInputs = $('table.attachmentsList>tbody>tr[id^="display_attachment_"]>td input[name="removed_attachments[]"]'),
|
||||
aAttachmentsDeletedHiddenInputs = $('#AttachmentsListContainer table>tbody>tr[id^="display_attachment_"]>td input[name="removed_attachments[]"]'),
|
||||
aAttachmentsDeletedIds = aAttachmentsDeletedHiddenInputs.map(function() { return $(this).val() }).toArray();
|
||||
$(sContentNode).block();
|
||||
$.post(GetAbsoluteUrlModulesRoot()+'itop-attachments/ajax.itop-attachment.php',
|
||||
@@ -416,7 +416,6 @@ class TableDetailsAttachmentsRenderer extends AbstractAttachmentsRenderer
|
||||
$sFileDate = Dict::S('Attachments:File:Date');
|
||||
$sFileUploader = Dict::S('Attachments:File:Uploader');
|
||||
$sFileType = Dict::S('Attachments:File:MimeType');
|
||||
$sDeleteColumn = '';
|
||||
|
||||
if ($bWithDeleteButton)
|
||||
{
|
||||
@@ -488,17 +487,9 @@ JS
|
||||
{
|
||||
$iAttachmentId = $oAttachment->GetKey();
|
||||
|
||||
$sLineClass = '';
|
||||
if ($bIsEven)
|
||||
{
|
||||
$sLineClass = 'class="even"';
|
||||
}
|
||||
|
||||
$sLineStyle = '';
|
||||
$bIsDeletedAttachment = false;
|
||||
if (in_array($iAttachmentId, $aAttachmentsDeleted, true))
|
||||
{
|
||||
$sLineStyle = 'style="display: none;"';
|
||||
$bIsDeletedAttachment = true;
|
||||
}
|
||||
|
||||
@@ -513,7 +504,6 @@ JS
|
||||
$sFileFormattedSize = $oDoc->GetFormattedSize();
|
||||
$bIsTempAttachment = ($oAttachment->Get('item_id') === 0);
|
||||
$sAttachmentDateFormatted = '';
|
||||
$iAttachmentDateRaw = '';
|
||||
if (!$bIsTempAttachment)
|
||||
{
|
||||
$sAttachmentDate = $oAttachment->Get('creation_date');
|
||||
@@ -523,7 +513,6 @@ JS
|
||||
}
|
||||
$oAttachmentDate = DateTime::createFromFormat(AttributeDateTime::GetInternalFormat(), $sAttachmentDate);
|
||||
$sAttachmentDateFormatted = AttributeDateTime::GetFormat()->Format($oAttachmentDate);
|
||||
$iAttachmentDateRaw = AttributeDateTime::GetAsUnixSeconds($sAttachmentDate);
|
||||
}
|
||||
|
||||
$sAttachmentUploader = $oAttachment->Get('contact_id_friendlyname');
|
||||
@@ -560,7 +549,11 @@ JS
|
||||
'type' => $sFileType,
|
||||
'js' => '',
|
||||
);
|
||||
|
||||
|
||||
if ($bIsDeletedAttachment) {
|
||||
$aAttachmentLine['@class'] = 'ibo-is-hidden';
|
||||
}
|
||||
|
||||
if ($bWithDeleteButton)
|
||||
{
|
||||
$sDeleteButton = $this->GetDeleteAttachmentButton($iAttachmentId);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
if (!defined('__DIR__')) define('__DIR__', dirname(__FILE__));
|
||||
if (!defined('APPROOT')) require_once(__DIR__.'/../../approot.inc.php');
|
||||
require_once(APPROOT.'/application/application.inc.php');
|
||||
require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
|
||||
|
||||
require_once(APPROOT.'core/mutex.class.inc.php');
|
||||
|
||||
@@ -49,7 +48,7 @@ function DisplayErrorAndDie($oPage, $sHtmlErrorMessage, $exitCode = null)
|
||||
|
||||
$sOperation = utils::ReadParam('operation', '');
|
||||
|
||||
$oPage = new ajax_page('');
|
||||
$oPage = new AjaxPage('');
|
||||
$oPage->SetContentType('text/html');
|
||||
|
||||
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
|
||||
'bkp-backup-running' => 'Kopia zapasowa jest uruchomiona. Proszę czekać...',
|
||||
'bkp-restore-running' => 'Trwa przywracanie. Proszę czekać...',
|
||||
|
||||
'Menu:BackupStatus' => 'Kopie zapasowe',
|
||||
'bkp-status-title' => 'Kopie zapasowe',
|
||||
'bkp-status-checks' => 'Ustawienia i kontrole',
|
||||
'bkp-mysqldump-ok' => 'mysqldump jest obecny: %1$s',
|
||||
'bkp-mysqldump-notfound' => 'mysqldump nie znaleziony: %1$s - Upewnij się, że jest zainstalowany i znajduje się w ścieżce, lub edytuj plik konfiguracyjny, aby ustawić mysql_bindir.',
|
||||
'bkp-mysqldump-issue' => 'mysqldump nie mógł zostać wykonany (retcode=%1$d): Upewnij się, że jest zainstalowany i znajduje się w ścieżce, lub edytuj plik konfiguracyjny, aby ustawić mysql_bindir',
|
||||
'bkp-missing-dir' => 'The target directory %1$s nie został znaleziony',
|
||||
'bkp-free-disk-space' => '<b>%1$s wolne</b> w %2$s',
|
||||
'bkp-dir-not-writeable' => '%1$s jest niezapisywalny',
|
||||
'bkp-wrong-format-spec' => 'Bieżąca specyfikacja formatowania nazw plików jest nieprawidłowa (%1$s). Obowiązuje specyfikacja domyślna: %2$s',
|
||||
'bkp-name-sample' => 'Pliki kopii zapasowych są nazywane w zależności od identyfikatorów bazy danych, daty i godziny. Przykład: %1$s',
|
||||
'bkp-week-days' => 'Kopie zapasowe będą wykonywane <b>co %1$s w %2$s</b>',
|
||||
'bkp-retention' => 'Co najwyżej <b>%1$d plików kopii zapasowych będzie przechowywanych</b> w katalogu docelowym.',
|
||||
'bkp-next-to-delete' => 'Zostanie usunięty po wykonaniu następnej kopii zapasowej (patrz ustawienie "retention_count")',
|
||||
'bkp-table-file' => 'Plik',
|
||||
'bkp-table-file+' => 'Tylko pliki z rozszerzeniem .zip są traktowane jako pliki kopii zapasowych',
|
||||
'bkp-table-size' => 'Rozmiar',
|
||||
'bkp-table-size+' => '',
|
||||
'bkp-table-actions' => 'Działania',
|
||||
'bkp-table-actions+' => '',
|
||||
'bkp-status-backups-auto' => 'Zaplanowane kopie zapasowe',
|
||||
'bkp-status-backups-manual' => 'Ręczne kopie zapasowe',
|
||||
'bkp-status-backups-none' => 'Nie ma jeszcze kopii zapasowej',
|
||||
'bkp-next-backup' => 'Następna kopia zapasowa zostanie utworzona <b>%1$s</b> (%2$s) w %3$s',
|
||||
'bkp-button-backup-now' => 'Utwórz kopię teraz!',
|
||||
'bkp-button-restore-now' => 'Przywróć!',
|
||||
'bkp-confirm-backup' => 'Potwierdź, że chcesz teraz wykonać kopię zapasową.',
|
||||
'bkp-confirm-restore' => 'Potwierdź, że chcesz przywrócić kopię zapasową %1$s.',
|
||||
'bkp-wait-backup' => 'Poczekaj na zakończenie tworzenia kopii zapasowej...',
|
||||
'bkp-wait-restore' => 'Poczekaj na zakończenie przywracania...',
|
||||
'bkp-success-restore' => 'Przywracanie zakończone pomyślnie.',
|
||||
));
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', array(
|
||||
|
||||
'bkp-backup-running' => 'Kopia zapasowa jest uruchomiona. Proszę czekać...',
|
||||
'bkp-restore-running' => 'Trwa przywracanie. Proszę czekać...',
|
||||
|
||||
'Menu:BackupStatus' => 'Kopie zapasowe',
|
||||
'bkp-status-title' => 'Kopie zapasowe',
|
||||
'bkp-status-checks' => 'Ustawienia i kontrole',
|
||||
'bkp-mysqldump-ok' => 'mysqldump jest obecny: %1$s',
|
||||
'bkp-mysqldump-notfound' => 'mysqldump nie znaleziony: %1$s - Upewnij się, że jest zainstalowany i znajduje się w ścieżce, lub edytuj plik konfiguracyjny, aby ustawić mysql_bindir.',
|
||||
'bkp-mysqldump-issue' => 'mysqldump nie mógł zostać wykonany (retcode=%1$d): Upewnij się, że jest zainstalowany i znajduje się w ścieżce, lub edytuj plik konfiguracyjny, aby ustawić mysql_bindir',
|
||||
'bkp-missing-dir' => 'The target directory %1$s nie został znaleziony',
|
||||
'bkp-free-disk-space' => '<b>%1$s wolne</b> w %2$s',
|
||||
'bkp-dir-not-writeable' => '%1$s jest niezapisywalny',
|
||||
'bkp-wrong-format-spec' => 'Bieżąca specyfikacja formatowania nazw plików jest nieprawidłowa (%1$s). Obowiązuje specyfikacja domyślna: %2$s',
|
||||
'bkp-name-sample' => 'Pliki kopii zapasowych są nazywane w zależności od identyfikatorów bazy danych, daty i godziny. Przykład: %1$s',
|
||||
'bkp-week-days' => 'Kopie zapasowe będą wykonywane <b>co %1$s w %2$s</b>',
|
||||
'bkp-retention' => 'Co najwyżej <b>%1$d plików kopii zapasowych będzie przechowywanych</b> w katalogu docelowym.',
|
||||
'bkp-next-to-delete' => 'Zostanie usunięty po wykonaniu następnej kopii zapasowej (patrz ustawienie "retention_count")',
|
||||
'bkp-table-file' => 'Plik',
|
||||
'bkp-table-file+' => 'Tylko pliki z rozszerzeniem .zip są traktowane jako pliki kopii zapasowych',
|
||||
'bkp-table-size' => 'Rozmiar',
|
||||
'bkp-table-size+' => '',
|
||||
'bkp-table-actions' => 'Działania',
|
||||
'bkp-table-actions+' => '',
|
||||
'bkp-status-backups-auto' => 'Zaplanowane kopie zapasowe',
|
||||
'bkp-status-backups-manual' => 'Ręczne kopie zapasowe',
|
||||
'bkp-status-backups-none' => 'Nie ma jeszcze kopii zapasowej',
|
||||
'bkp-next-backup' => 'Następna kopia zapasowa zostanie utworzona <b>%1$s</b> (%2$s) w %3$s',
|
||||
'bkp-next-backup-unknown' => 'The next backup is <b>not scheduled</b> yet.~~',
|
||||
'bkp-button-backup-now' => 'Utwórz kopię teraz!',
|
||||
'bkp-button-restore-now' => 'Przywróć!',
|
||||
'bkp-confirm-backup' => 'Potwierdź, że chcesz teraz wykonać kopię zapasową.',
|
||||
'bkp-confirm-restore' => 'Potwierdź, że chcesz przywrócić kopię zapasową %1$s.',
|
||||
'bkp-wait-backup' => 'Poczekaj na zakończenie tworzenia kopii zapasowej...',
|
||||
'bkp-wait-restore' => 'Poczekaj na zakończenie przywracania...',
|
||||
'bkp-success-restore' => 'Przywracanie zakończone pomyślnie.',
|
||||
));
|
||||
|
||||
@@ -439,7 +439,7 @@ function LaunchBackupNow()
|
||||
if (data.search(/error|exceptio|notice|warning/i) != -1)
|
||||
{
|
||||
$('#backup_errors').html(data);
|
||||
$('#backup_errors').show();
|
||||
$('#backup_errors').removeClass('ibo-is-hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -31,24 +31,24 @@
|
||||
// Class: lnkFunctionalCIToTicket
|
||||
//
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:lnkFunctionalCIToTicket' => 'Link FunctionalCI / Ticket~~',
|
||||
'Class:lnkFunctionalCIToTicket' => 'İşlevsel CI / Çağrı kaydı bağla',
|
||||
'Class:lnkFunctionalCIToTicket+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Ticket~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Çağrı Kaydı',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Ref~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Ref',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_title' => 'Ticket title~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_title+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id' => 'CI',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name' => 'CI Name~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name' => 'CI Adı',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact' => 'Impact (text)~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact' => 'Etki (Metin)',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact+' => '~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code' => 'Impact~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:manual' => 'Added manually~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:computed' => 'Computed~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:not_impacted' => 'Not impacted~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code' => 'Etki',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:manual' => 'Elle eklendi',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:computed' => 'Hesaplandı',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:not_impacted' => 'Etkilemedi',
|
||||
));
|
||||
|
||||
//
|
||||
@@ -56,15 +56,15 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
//
|
||||
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:lnkFunctionalCIToProviderContract' => 'Link FunctionalCI / ProviderContract~~',
|
||||
'Class:lnkFunctionalCIToProviderContract' => 'İşlevsel CI / Sağlayıcı Sözleşmesi bağla',
|
||||
'Class:lnkFunctionalCIToProviderContract+' => '~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id' => 'Provider contract~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id' => 'Sağlayıcı Sözleşmesi',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id+' => '~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name' => 'Provider contract Name~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name' => 'Sağlayıcı Sözleşme Adı',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name+' => '~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id' => 'CI',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id+' => '~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name' => 'CI Name~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name' => 'CI Adı',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name+' => '~~',
|
||||
));
|
||||
|
||||
@@ -73,15 +73,15 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
//
|
||||
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:lnkFunctionalCIToService' => 'Link FunctionalCI / Service~~',
|
||||
'Class:lnkFunctionalCIToService' => 'İşlevsel CI / servis bağla',
|
||||
'Class:lnkFunctionalCIToService+' => '~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Service~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Servis',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id+' => '~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Service Name~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Servis Adı',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_name+' => '~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id' => 'CI',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id+' => '~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_name' => 'CI Name~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_name' => 'CI Adı',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_name+' => '~~',
|
||||
));
|
||||
|
||||
@@ -90,10 +90,10 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
//
|
||||
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:FunctionalCI/Attribute:providercontracts_list' => 'Provider contracts~~',
|
||||
'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~',
|
||||
'Class:FunctionalCI/Attribute:services_list' => 'Services~~',
|
||||
'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~',
|
||||
'Class:FunctionalCI/Attribute:tickets_list' => 'Tickets~~',
|
||||
'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~',
|
||||
'Class:FunctionalCI/Attribute:providercontracts_list' => 'Tedarikçi Sözleşmeleri',
|
||||
'Class:FunctionalCI/Attribute:providercontracts_list+' => 'Bu yapılandırma öğesi için tüm tedarikçi sözleşmeleri',
|
||||
'Class:FunctionalCI/Attribute:services_list' => 'Hizmetler',
|
||||
'Class:FunctionalCI/Attribute:services_list+' => 'Bu yapılandırma öğesinden etkilenen tüm hizmetler',
|
||||
'Class:FunctionalCI/Attribute:tickets_list' => 'Çağrı Kayıtları',
|
||||
'Class:FunctionalCI/Attribute:tickets_list+' => 'Bu yapılandırma öğesi için tüm çağrı kayıtları',
|
||||
));
|
||||
|
||||
@@ -40,12 +40,12 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Menu:Changes+' => '',
|
||||
'Menu:MyChanges' => 'Bana atanan değişiklik istekleri',
|
||||
'Menu:MyChanges+' => 'Bana atanan değişiklik istekleri',
|
||||
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Changes by category for the last 7 days~~',
|
||||
'UI-ChangeManagementOverview-Last-7-days' => 'Number of changes for the last 7 days~~',
|
||||
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Changes by domain for the last 7 days~~',
|
||||
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Changes by status for the last 7 days~~',
|
||||
'Tickets:Related:OpenChanges' => 'Open changes~~',
|
||||
'Tickets:Related:RecentChanges' => 'Recent changes (72h)~~',
|
||||
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Son 7 gün için kategoriye göre değişiklikler',
|
||||
'UI-ChangeManagementOverview-Last-7-days' => 'Son 7 gün için değişiklik sayısı',
|
||||
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Son 7 gün için etki alanı tarafından yapılan değişiklikler',
|
||||
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Son 7 gün için duruma göre değişiklikler',
|
||||
'Tickets:Related:OpenChanges' => 'Açık değişiklikler',
|
||||
'Tickets:Related:RecentChanges' => 'Son değişiklikler (72H)',
|
||||
));
|
||||
|
||||
// Dictionnay conventions
|
||||
@@ -122,21 +122,21 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:Change/Attribute:outage/Value:yes+' => '',
|
||||
'Class:Change/Attribute:fallback' => 'Geridönüş planı',
|
||||
'Class:Change/Attribute:fallback+' => '',
|
||||
'Class:Change/Attribute:parent_id' => 'Parent change~~',
|
||||
'Class:Change/Attribute:parent_id' => 'Ana Kaynak Değişimi',
|
||||
'Class:Change/Attribute:parent_id+' => '~~',
|
||||
'Class:Change/Attribute:parent_name' => 'Parent change Ref~~',
|
||||
'Class:Change/Attribute:parent_name' => 'Ana Kaynak Değişimi Ref',
|
||||
'Class:Change/Attribute:parent_name+' => '~~',
|
||||
'Class:Change/Attribute:related_request_list' => 'Related requests~~',
|
||||
'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~',
|
||||
'Class:Change/Attribute:related_problems_list' => 'Related problems~~',
|
||||
'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~',
|
||||
'Class:Change/Attribute:related_incident_list' => 'Related incidents~~',
|
||||
'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Child changes~~',
|
||||
'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent friendly name~~',
|
||||
'Class:Change/Attribute:related_request_list' => 'İlgili Talepler',
|
||||
'Class:Change/Attribute:related_request_list+' => 'Bu değişikliğe bağlı tüm kullanıcı istekleri',
|
||||
'Class:Change/Attribute:related_problems_list' => 'İlgili problemler',
|
||||
'Class:Change/Attribute:related_problems_list+' => 'Bu değişiklikle bağlantılı tüm problemler',
|
||||
'Class:Change/Attribute:related_incident_list' => 'İlişkili Olaylar',
|
||||
'Class:Change/Attribute:related_incident_list+' => 'Bu değişikliğe bağlı tüm olaylar',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Alt bağlantı değişiklikleri',
|
||||
'Class:Change/Attribute:child_changes_list+' => 'Bu değişikliğe bağlı tüm alt değişiklikler',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Ana Kaynak Bilinen Adı',
|
||||
'Class:Change/Attribute:parent_id_friendlyname+' => '~~',
|
||||
'Class:Change/Attribute:parent_id_finalclass_recall' => 'Change type~~',
|
||||
'Class:Change/Attribute:parent_id_finalclass_recall' => 'Değişim türü',
|
||||
'Class:Change/Attribute:parent_id_finalclass_recall+' => '~~',
|
||||
'Class:Change/Stimulus:ev_validate' => 'Doğrula',
|
||||
'Class:Change/Stimulus:ev_validate+' => '',
|
||||
@@ -171,7 +171,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:RoutineChange+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_validate' => 'Doğrulanan',
|
||||
'Class:RoutineChange/Stimulus:ev_validate+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_reject' => 'Reject~~',
|
||||
'Class:RoutineChange/Stimulus:ev_reject' => 'Reddet',
|
||||
'Class:RoutineChange/Stimulus:ev_reject+' => '~~',
|
||||
'Class:RoutineChange/Stimulus:ev_assign' => 'Atanan',
|
||||
'Class:RoutineChange/Stimulus:ev_assign+' => '',
|
||||
@@ -179,11 +179,11 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:RoutineChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_plan' => 'Planlanan',
|
||||
'Class:RoutineChange/Stimulus:ev_plan+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_approve' => 'Approve~~',
|
||||
'Class:RoutineChange/Stimulus:ev_approve' => 'Onayla',
|
||||
'Class:RoutineChange/Stimulus:ev_approve+' => '~~',
|
||||
'Class:RoutineChange/Stimulus:ev_replan' => 'Tekrar planlanan',
|
||||
'Class:RoutineChange/Stimulus:ev_replan+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove' => 'Do Not Approve~~',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove' => 'Onaylama',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove+' => '~~',
|
||||
'Class:RoutineChange/Stimulus:ev_implement' => 'Uygula',
|
||||
'Class:RoutineChange/Stimulus:ev_implement+' => '',
|
||||
|
||||
@@ -38,12 +38,12 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Menu:Changes+' => 'All open changes~~',
|
||||
'Menu:MyChanges' => 'Bana atanan değişiklik istekleri',
|
||||
'Menu:MyChanges+' => 'Bana atanan değişiklik istekleri',
|
||||
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Changes by category for the last 7 days~~',
|
||||
'UI-ChangeManagementOverview-Last-7-days' => 'Number of changes for the last 7 days~~',
|
||||
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Changes by domain for the last 7 days~~',
|
||||
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Changes by status for the last 7 days~~',
|
||||
'Tickets:Related:OpenChanges' => 'Open changes~~',
|
||||
'Tickets:Related:RecentChanges' => 'Recent changes (72h)~~',
|
||||
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Son 7 gün için kategoriye göre değişiklikler',
|
||||
'UI-ChangeManagementOverview-Last-7-days' => 'Son 7 gün için değişiklik sayısı',
|
||||
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Son 7 gün için etki alanı tarafından yapılan değişiklikler',
|
||||
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Son 7 gün için duruma göre değişiklikler',
|
||||
'Tickets:Related:OpenChanges' => 'Açık değişiklikler',
|
||||
'Tickets:Related:RecentChanges' => 'Son değişiklikler (72H)',
|
||||
));
|
||||
|
||||
// Dictionnay conventions
|
||||
@@ -98,9 +98,9 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:Change/Attribute:changemanager_id+' => '~~',
|
||||
'Class:Change/Attribute:changemanager_email' => 'Change manager email~~',
|
||||
'Class:Change/Attribute:changemanager_email+' => '~~',
|
||||
'Class:Change/Attribute:parent_id' => 'Parent change~~',
|
||||
'Class:Change/Attribute:parent_id' => 'Ana Kaynak Değişimi',
|
||||
'Class:Change/Attribute:parent_id+' => '~~',
|
||||
'Class:Change/Attribute:parent_name' => 'Parent change ref~~',
|
||||
'Class:Change/Attribute:parent_name' => 'Ana Kaynak Değişimi Ref',
|
||||
'Class:Change/Attribute:parent_name+' => '~~',
|
||||
'Class:Change/Attribute:creation_date' => 'Yaratıldı',
|
||||
'Class:Change/Attribute:creation_date+' => '~~',
|
||||
@@ -108,15 +108,15 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:Change/Attribute:approval_date+' => '~~',
|
||||
'Class:Change/Attribute:fallback_plan' => 'Fallback plan~~',
|
||||
'Class:Change/Attribute:fallback_plan+' => '~~',
|
||||
'Class:Change/Attribute:related_request_list' => 'Related requests~~',
|
||||
'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~',
|
||||
'Class:Change/Attribute:related_incident_list' => 'Related incidents~~',
|
||||
'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~',
|
||||
'Class:Change/Attribute:related_problems_list' => 'Related problems~~',
|
||||
'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Child changes~~',
|
||||
'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent change friendly name~~',
|
||||
'Class:Change/Attribute:related_request_list' => 'İlgili Talepler',
|
||||
'Class:Change/Attribute:related_request_list+' => 'Bu değişikliğe bağlı tüm kullanıcı istekleri',
|
||||
'Class:Change/Attribute:related_incident_list' => 'İlişkili Olaylar',
|
||||
'Class:Change/Attribute:related_incident_list+' => 'Bu değişikliğe bağlı tüm olaylar',
|
||||
'Class:Change/Attribute:related_problems_list' => 'İlgili problemler',
|
||||
'Class:Change/Attribute:related_problems_list+' => 'Bu değişiklikle bağlantılı tüm problemler',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Alt bağlantı değişiklikleri',
|
||||
'Class:Change/Attribute:child_changes_list+' => 'Bu değişikliğe bağlı tüm alt değişiklikler',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Ana Kaynak Bilinen Adı',
|
||||
'Class:Change/Attribute:parent_id_friendlyname+' => '~~',
|
||||
'Class:Change/Stimulus:ev_assign' => 'Ata',
|
||||
'Class:Change/Stimulus:ev_assign+' => '~~',
|
||||
|
||||
@@ -85,7 +85,7 @@ class ChangeManagementInstaller extends ModuleInstallerAPI
|
||||
|
||||
if (CMDBSource::IsField($sSourceTable, $sField) && CMDBSource::IsField($sTargetTable, $sField) && CMDBSource::IsField($sSourceTable, $sSourceKeyField) && CMDBSource::IsField($sTargetTable, $sTargetKeyField))
|
||||
{
|
||||
SetupWebPage::log_info("Issue #464 - Copying change/start_date into ticket/start_date");
|
||||
SetupLog::Info("Issue #464 - Copying change/start_date into ticket/start_date");
|
||||
$sRepair = "UPDATE `$sTargetTable`, `$sSourceTable` SET `$sTargetTable`.`$sField` = `$sSourceTable`.`$sField` WHERE `$sTargetTable`.`$sField` IS NULL AND`$sTargetTable`.`$sTargetKeyField` = `$sSourceTable`.`$sSourceKeyField`";
|
||||
CMDBSource::Query($sRepair);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Relation:depends on/Description' => 'Elements impacting',
|
||||
'Relation:depends on/DownStream' => 'Depends on...',
|
||||
'Relation:depends on/UpStream' => 'Impacts...',
|
||||
'Relation:impacts/LoadData' => 'Load data',
|
||||
'Relation:impacts/NoFilteredData' => 'please select objects in Graphical view tag',
|
||||
));
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Relation:depends on/Description' => 'Eléments dont dépend',
|
||||
'Relation:depends on/DownStream' => 'Dépend de...',
|
||||
'Relation:depends on/UpStream' => 'Impacte...',
|
||||
'Relation:impacts/LoadData' => 'Charger les données',
|
||||
'Relation:impacts/NoFilteredData' => 'Veuillez sélectionner des objets dans l\'onglet Graph',
|
||||
));
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,7 +75,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Application can be updated~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'You must use the <a href="%1$s">setup</a> to update the application.<br />Some modified files were detected, a partial update cannot be executed.~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Ready to start~~',
|
||||
|
||||
@@ -75,7 +75,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Application can be updated~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'You must use the <a href="%1$s">setup</a> to update the application.<br />Some modified files were detected, a partial update cannot be executed.~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Ready to start~~',
|
||||
|
||||
@@ -75,7 +75,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Anwendungsupgrade kann durchgeführt werden',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Anwendungsupgrade nicht möglich: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Vorsicht: App-Upgrade kann fehlerschlagen: %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'Sie müssen das <a href="%1$s">Setup</a> benutzen, um Ihre Applikation zu aktualisieren.<br />Einige angepasste Dateien wurden erkannt, eine Teil-Update kann nicht ausgeführt werden.',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Einige angepasste Dateien wurden erkannt</b>, eine Teil-Update kann nicht ausgeführt werden.<br/>Befolgen Sie das <a href="%2$s">Verfahren</a>, um Ihr iTop manuell zu aktualisieren. Sie müssen das <a href="%1$s">Setup</a> benutzen, um Ihre Applikation zu aktualisieren.<br />',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Bereit zum Upgrade',
|
||||
|
||||
@@ -75,7 +75,10 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Application can be updated',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'You must use the <a href="%1$s">setup</a> to update the application.<br />Some modified files were detected, a partial update cannot be executed.',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check',
|
||||
|
||||
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Ready to start',
|
||||
|
||||
@@ -76,7 +76,8 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'La aplicación puede ser actualizada',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'La aplicación no puede ser actualizada: %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Advertencia: la actualización de la aplicación puede fallar: %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'You must use the <a href="%1$s">setup</a> to update the application.<br />Some modified files were detected, a partial update cannot be executed.~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Listo para empezar',
|
||||
|
||||
@@ -75,7 +75,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'L\'application peut être mise à jour',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'L\'application ne peut pas être mise à jour : %1$s',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Attention : la mise à jour de l\'application peut échouer : %1$s',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'Vous devez utiliser la page <a href="%1$s">d\'installation</a> pour mettre à jour l\'application.<br />Des fichiers modifiés ont été détectés, une mise à jour partielle ne peut pas être effectuée.',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Des fichiers modifiés ont été détectés</b>, une mise à jour partielle ne peut pas être effectuée.<br />Suivez la <a href="%2$s"> procedure</a> pour mettre à jour manuellement votre iTop. Vous devez utiliser la page <a href="%1$s">d\'installation</a> pour mettre à jour l\'application.',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Veuillez patienter pendant la vérification des fichiers',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Prêt pour l\\installation',
|
||||
|
||||
@@ -75,7 +75,8 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Application can be updated~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'You must use the <a href="%1$s">setup</a> to update the application.<br />Some modified files were detected, a partial update cannot be executed.~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Ready to start~~',
|
||||
|
||||
@@ -75,7 +75,8 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Application can be updated~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:No' => 'Application cannot be updated: %1$s~~',
|
||||
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Warning: application update can fail: %1$s~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => 'You must use the <a href="%1$s">setup</a> to update the application.<br />Some modified files were detected, a partial update cannot be executed.~~',
|
||||
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
|
||||
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
|
||||
|
||||
// Setup Messages
|
||||
'iTopUpdate:UI:SetupMessage:Ready' => 'Ready to start~~',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user