mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-14 07:54:10 +01:00
Compare commits
179 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f844cef03e | ||
|
|
4c0e176f3e | ||
|
|
f0f519e351 | ||
|
|
9a68890660 | ||
|
|
806ed2102c | ||
|
|
14b9778c50 | ||
|
|
0142910c26 | ||
|
|
0068d7c8be | ||
|
|
302811986e | ||
|
|
f773433a93 | ||
|
|
880653f191 | ||
|
|
02ee41ef09 | ||
|
|
d6344568c7 | ||
|
|
38a2fd75c0 | ||
|
|
7ca8c3e834 | ||
|
|
7d3a93c374 | ||
|
|
a978bb9c17 | ||
|
|
3ed01cde51 | ||
|
|
67471e2636 | ||
|
|
4c44159a88 | ||
|
|
5f5125a131 | ||
|
|
f6d0bda737 | ||
|
|
a64b299644 | ||
|
|
e022bf03db | ||
|
|
bab6ca7954 | ||
|
|
bb70884041 | ||
|
|
58cb67ecd3 | ||
|
|
4920cc4aee | ||
|
|
12c587896e | ||
|
|
eb74288c85 | ||
|
|
922049e8f2 | ||
|
|
d83edb803b | ||
|
|
9f41c7e577 | ||
|
|
1335a15c30 | ||
|
|
d847272264 | ||
|
|
8054d7b17a | ||
|
|
1ba2ed809c | ||
|
|
b2feca5eb5 | ||
|
|
87ce86880e | ||
|
|
d4de0d2ee3 | ||
|
|
730f522ab2 | ||
|
|
008cac25b4 | ||
|
|
ede552968b | ||
|
|
686848a0ae | ||
|
|
61b5b5cc71 | ||
|
|
ec16c5f86f | ||
|
|
d602bb2190 | ||
|
|
1b9d3d3304 | ||
|
|
02e5d57998 | ||
|
|
6236d96a65 | ||
|
|
6473a8f245 | ||
|
|
ab93eaefff | ||
|
|
037803c033 | ||
|
|
06582cfe35 | ||
|
|
a72e15023f | ||
|
|
7ddd74a95e | ||
|
|
4fccf5c815 | ||
|
|
a6d984e23f | ||
|
|
7bf3f97a72 | ||
|
|
e78743d309 | ||
|
|
6b86ac5090 | ||
|
|
14c78cb543 | ||
|
|
5007e6ffc3 | ||
|
|
1d4784b0c7 | ||
|
|
d497020733 | ||
|
|
98afb2dd49 | ||
|
|
f89792e171 | ||
|
|
8141f8c619 | ||
|
|
2009a10204 | ||
|
|
d2961c585e | ||
|
|
9b5fc043cb | ||
|
|
67ef671632 | ||
|
|
d07ca49e53 | ||
|
|
44aff84dfa | ||
|
|
c9ffdb9342 | ||
|
|
65343a485f | ||
|
|
74cda2831f | ||
|
|
c4632cda1a | ||
|
|
d7ba4166e5 | ||
|
|
ee3795ef6d | ||
|
|
e8a7695353 | ||
|
|
e4bb0acd94 | ||
|
|
1572d9da5a | ||
|
|
2d0ca37f27 | ||
|
|
df09182878 | ||
|
|
20bb9a62bb | ||
|
|
a6f5436d07 | ||
|
|
53e58d5887 | ||
|
|
ef1178c78d | ||
|
|
5456d9d20a | ||
|
|
7c8ff071d2 | ||
|
|
e4010b4b13 | ||
|
|
dbb9558b45 | ||
|
|
8f83970239 | ||
|
|
102b6c248b | ||
|
|
946b4212d3 | ||
|
|
e2e6861b03 | ||
|
|
7b7e69a890 | ||
|
|
92b2131d3b | ||
|
|
43130aef71 | ||
|
|
ba4e5ec786 | ||
|
|
3e79dad435 | ||
|
|
b0a84f96f1 | ||
|
|
85fa578f2a | ||
|
|
364bce90e4 | ||
|
|
fcfc1e7307 | ||
|
|
85cb04a3f3 | ||
|
|
ec77e58276 | ||
|
|
196fba7d81 | ||
|
|
317344da2e | ||
|
|
cd37a78800 | ||
|
|
9ed5ceb11e | ||
|
|
f47327fdd4 | ||
|
|
5ec37c8060 | ||
|
|
bb65153351 | ||
|
|
389b97dc50 | ||
|
|
31e30810f6 | ||
|
|
4bffe7aec9 | ||
|
|
fafa442b08 | ||
|
|
b095c6b1a3 | ||
|
|
d950422912 | ||
|
|
b504830f45 | ||
|
|
4dabb566a8 | ||
|
|
7459ec4844 | ||
|
|
678f982024 | ||
|
|
d628c4f670 | ||
|
|
e1336d7ebc | ||
|
|
01496f9595 | ||
|
|
a60d60bfab | ||
|
|
31cb0065b5 | ||
|
|
4dbc5d97b8 | ||
|
|
4800da1653 | ||
|
|
8f25fb8e64 | ||
|
|
b43884a760 | ||
|
|
caef02720c | ||
|
|
ce9806b01c | ||
|
|
7a193d1c24 | ||
|
|
31ea53435e | ||
|
|
dcb48d0f35 | ||
|
|
40aa78bb3d | ||
|
|
82e9e42939 | ||
|
|
1ecec1dd6d | ||
|
|
8dc5b05ac4 | ||
|
|
3b257eeb3a | ||
|
|
2574a0c8a4 | ||
|
|
404f6772fd | ||
|
|
d6dbe0fce7 | ||
|
|
8e26ca763b | ||
|
|
b4bc3ad716 | ||
|
|
80fac28106 | ||
|
|
5f11c97aef | ||
|
|
d36a03bfc3 | ||
|
|
8e0c57fce0 | ||
|
|
cb4c2a8e84 | ||
|
|
f993f07751 | ||
|
|
0167a66973 | ||
|
|
b7d8953ecb | ||
|
|
cba75527b3 | ||
|
|
bc0f48721b | ||
|
|
a6693d9535 | ||
|
|
6f2c404415 | ||
|
|
b00aae2536 | ||
|
|
6334370ef0 | ||
|
|
868748efb3 | ||
|
|
c67e7e18e6 | ||
|
|
16f1fd56ec | ||
|
|
1cab84e793 | ||
|
|
991fe9ccc1 | ||
|
|
0a53f8ec3f | ||
|
|
cd7af7a2ce | ||
|
|
319b3b81ce | ||
|
|
4235eae9b3 | ||
|
|
32ec19e09d | ||
|
|
63ea142168 | ||
|
|
23ec4faa65 | ||
|
|
da36fc673e | ||
|
|
3b65f33325 | ||
|
|
e980b051b1 | ||
|
|
c84a22c503 |
@@ -210,6 +210,25 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
||||
$oLnk->DBDelete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of flags (OPT_ATT_HIDDEN, OPT_ATT_READONLY, OPT_ATT_MANDATORY...)
|
||||
* for the given attribute in the current state of the object
|
||||
* @param $sAttCode string $sAttCode The code of the attribute
|
||||
* @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);
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
||||
$iFlags |= OPT_ATT_READONLY;
|
||||
}
|
||||
return $iFlags;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,16 +26,14 @@
|
||||
|
||||
require_once(APPROOT."/application/webpage.class.inc.php");
|
||||
|
||||
class ajax_page extends WebPage
|
||||
class ajax_page extends WebPage implements iTabbedPage
|
||||
{
|
||||
/**
|
||||
* Jquery style ready script
|
||||
* @var Hash
|
||||
*/
|
||||
protected $m_sReadyScript;
|
||||
protected $m_sCurrentTab;
|
||||
protected $m_sCurrentTabContainer;
|
||||
protected $m_aTabs;
|
||||
protected $m_oTabs;
|
||||
private $m_sMenu; // If set, then the menu will be updated
|
||||
|
||||
/**
|
||||
@@ -48,9 +46,7 @@ class ajax_page extends WebPage
|
||||
$this->m_sReadyScript = "";
|
||||
//$this->add_header("Content-type: text/html; charset=utf-8");
|
||||
$this->add_header("Cache-control: no-cache");
|
||||
$this->m_sCurrentTabContainer = '';
|
||||
$this->m_sCurrentTab = '';
|
||||
$this->m_aTabs = array();
|
||||
$this->m_oTabs = new TabManager();
|
||||
$this->sContentType = 'text/html';
|
||||
$this->sContentDisposition = 'inline';
|
||||
$this->m_sMenu = "";
|
||||
@@ -58,41 +54,69 @@ class ajax_page extends WebPage
|
||||
|
||||
public function AddTabContainer($sTabContainer, $sPrefix = '')
|
||||
{
|
||||
$this->m_aTabs[$sTabContainer] = array('content' =>'', 'prefix' => $sPrefix);
|
||||
$this->add("\$Tabs:$sTabContainer\$");
|
||||
$this->add($this->m_oTabs->AddTabContainer($sTabContainer, $sPrefix));
|
||||
}
|
||||
|
||||
|
||||
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
|
||||
{
|
||||
if (!isset($this->m_aTabs[$sTabContainer]['content'][$sTabLabel]))
|
||||
{
|
||||
// Set the content of the tab
|
||||
$this->m_aTabs[$sTabContainer]['content'][$sTabLabel] = $sHtml;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append to the content of the tab
|
||||
$this->m_aTabs[$sTabContainer]['content'][$sTabLabel] .= $sHtml;
|
||||
}
|
||||
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabLabel, $sHtml));
|
||||
}
|
||||
|
||||
public function SetCurrentTabContainer($sTabContainer = '')
|
||||
{
|
||||
$sPreviousTabContainer = $this->m_sCurrentTabContainer;
|
||||
$this->m_sCurrentTabContainer = $sTabContainer;
|
||||
return $sPreviousTabContainer;
|
||||
return $this->m_oTabs->SetCurrentTabContainer($sTabContainer);
|
||||
}
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '')
|
||||
{
|
||||
$sPreviousTab = $this->m_sCurrentTab;
|
||||
$this->m_sCurrentTab = $sTabLabel;
|
||||
return $sPreviousTab;
|
||||
return $this->m_oTabs->SetCurrentTab($sTabLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tab which content will be loaded asynchronously via the supplied URL
|
||||
*
|
||||
* Limitations:
|
||||
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to pull content from another server.
|
||||
* Static content cannot be added inside such tabs.
|
||||
*
|
||||
* @param string $sTabLabel The (localised) label of the tab
|
||||
* @param string $sUrl The URL to load (on the same server)
|
||||
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause the tab to be reloaded upon each activation.
|
||||
* @since 2.0.3
|
||||
*/
|
||||
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true)
|
||||
{
|
||||
$this->add($this->m_oTabs->AddAjaxTab($sTabLabel, $sUrl, $bCache));
|
||||
}
|
||||
|
||||
public function GetCurrentTab()
|
||||
{
|
||||
return $this->m_sCurrentTab;
|
||||
return $this->m_oTabs->GetCurrentTab();
|
||||
}
|
||||
|
||||
public function RemoveTab($sTabLabel, $sTabContainer = null)
|
||||
{
|
||||
$this->m_oTabs->RemoveTab($sTabLabel, $sTabContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the tab whose title matches a given pattern
|
||||
* @return mixed The name of the tab as a string or false if not found
|
||||
*/
|
||||
public function FindTab($sPattern, $sTabContainer = null)
|
||||
{
|
||||
return $this->m_oTabs->FindTab($sPattern, $sTabContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given tab the active one, as if it were clicked
|
||||
* DOES NOT WORK: apparently in the *old* version of jquery
|
||||
* that we are using this is not supported... TO DO upgrade
|
||||
* the whole jquery bundle...
|
||||
*/
|
||||
public function SelectTab($sTabContainer, $sTabLabel)
|
||||
{
|
||||
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabLabel));
|
||||
}
|
||||
|
||||
public function AddToMenu($sHtml)
|
||||
@@ -118,7 +142,7 @@ class ajax_page extends WebPage
|
||||
{
|
||||
header($s_header);
|
||||
}
|
||||
if (count($this->m_aTabs) > 0)
|
||||
if ($this->m_oTabs->TabsContainerCount() > 0)
|
||||
{
|
||||
$this->add_ready_script(
|
||||
<<<EOF
|
||||
@@ -173,36 +197,7 @@ EOF
|
||||
);
|
||||
}
|
||||
// Render the tabs in the page (if any)
|
||||
foreach($this->m_aTabs as $sTabContainerName => $aTabContainer)
|
||||
{
|
||||
$sTabs = '';
|
||||
$m_aTabs = $aTabContainer['content'];
|
||||
$sPrefix = $aTabContainer['prefix'];
|
||||
$container_index = 0;
|
||||
if (count($m_aTabs) > 0)
|
||||
{
|
||||
$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$sPrefix}{$sTabContainerName}\" class=\"light\">\n";
|
||||
$sTabs .= "<ul>\n";
|
||||
// Display the unordered list that will be rendered as the tabs
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<li><a href=\"#tab_{$sPrefix}{$sTabContainerName}$i\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</ul>\n";
|
||||
// Now add the content of the tabs themselves
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<div id=\"tab_{$sPrefix}{$sTabContainerName}$i\">".$sTabContent."</div>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</div>\n<!-- end of tabs-->\n";
|
||||
}
|
||||
$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
|
||||
$container_index++;
|
||||
}
|
||||
$this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content);
|
||||
|
||||
// Additional UI widgets to be activated inside the ajax fragment ??
|
||||
if (($this->sContentType == 'text/html') && (preg_match('/class="date-pick"/', $this->s_content) || preg_match('/class="datetime-pick"/', $this->s_content)) )
|
||||
@@ -302,9 +297,9 @@ EOF
|
||||
|
||||
public function add($sHtml)
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
if (($this->m_oTabs->GetCurrentTabContainer() != '') && ($this->m_oTabs->GetCurrentTab() != ''))
|
||||
{
|
||||
$this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
|
||||
$this->m_oTabs->AddToTab($this->m_oTabs->GetCurrentTabContainer(), $this->m_oTabs->GetCurrentTab(), $sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -318,15 +313,18 @@ EOF
|
||||
*/
|
||||
public function start_capture()
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
{
|
||||
$iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer]['content'][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer]['content'][$this->m_sCurrentTab]): 0;
|
||||
return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::start_capture();
|
||||
}
|
||||
$sCurrentTabContainer = $this->m_oTabs->GetCurrentTabContainer();
|
||||
$sCurrentTab = $this->m_oTabs->GetCurrentTab();
|
||||
|
||||
if (!empty($sCurrentTabContainer) && !empty($sCurrentTab))
|
||||
{
|
||||
$iOffset = $this->m_oTabs->GetCurrentTabLength();
|
||||
return array('tc' => $sCurrentTabContainer, 'tab' => $sCurrentTab, 'offset' => $iOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::start_capture();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,23 +335,22 @@ EOF
|
||||
*/
|
||||
public function end_capture($offset)
|
||||
{
|
||||
if (is_array($offset))
|
||||
{
|
||||
if (isset($this->m_aTabs[$offset['tc']]['content'][$offset['tab']]))
|
||||
{
|
||||
$sCaptured = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], $offset['offset']);
|
||||
$this->m_aTabs[$offset['tc']]['content'][$offset['tab']] = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], 0, $offset['offset']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCaptured = '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCaptured = parent::end_capture($offset);
|
||||
}
|
||||
return $sCaptured;
|
||||
if (is_array($offset))
|
||||
{
|
||||
if ($this->m_oTabs->TabExists($offset['tc'], $offset['tab']))
|
||||
{
|
||||
$sCaptured = $this->m_oTabs->TruncateTab($offset['tc'], $offset['tab'], $offset['offset']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCaptured = '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sCaptured = parent::end_capture($offset);
|
||||
}
|
||||
return $sCaptured;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -450,7 +450,8 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array ('label' => $this->GetLabel(), 'onclick' => $this->sJSCode, 'url' => '#');
|
||||
// Note: the semicolumn is a must here!
|
||||
return array ('label' => $this->GetLabel(), 'onclick' => $this->sJSCode.'; return false;', 'url' => '#');
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
@@ -580,6 +581,14 @@ class RestResult
|
||||
* Result: the input structure is not a valid JSON string
|
||||
*/
|
||||
const INVALID_JSON = 4;
|
||||
/**
|
||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||
*/
|
||||
const MISSING_AUTH_USER = 5;
|
||||
/**
|
||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||
*/
|
||||
const MISSING_AUTH_PWD = 6;
|
||||
/**
|
||||
* Result: no operation is available for the specified version
|
||||
*/
|
||||
@@ -706,7 +715,7 @@ class RestUtils
|
||||
* @param string $sClass Name of the class
|
||||
* @param StdClass $oData Structured input data.
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @return void
|
||||
* @return An array of class => list of attributes (see RestResultWithObjects::AddObject that uses it)
|
||||
* @throws Exception
|
||||
* @api
|
||||
*/
|
||||
@@ -718,7 +727,17 @@ class RestUtils
|
||||
{
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
$aShowFields[] = $sAttCode;
|
||||
$aShowFields[$sClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
elseif ($sFields == '*+')
|
||||
{
|
||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass)
|
||||
{
|
||||
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
$aShowFields[$sRefClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -730,7 +749,7 @@ class RestUtils
|
||||
{
|
||||
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
||||
}
|
||||
$aShowFields[] = $sAttCode;
|
||||
$aShowFields[$sClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
return $aShowFields;
|
||||
@@ -749,11 +768,15 @@ class RestUtils
|
||||
$aCriteriaReport = array();
|
||||
if (isset($oCriteria->finalclass))
|
||||
{
|
||||
$sClass = $oCriteria->finalclass;
|
||||
if (!MetaModel::IsValidClass($sClass))
|
||||
if (!MetaModel::IsValidClass($oCriteria->finalclass))
|
||||
{
|
||||
throw new Exception("finalclass: Unknown class '$sClass'");
|
||||
throw new Exception("finalclass: Unknown class '".$oCriteria->finalclass."'");
|
||||
}
|
||||
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass))
|
||||
{
|
||||
throw new Exception("finalclass: '".$oCriteria->finalclass."' is not a child class of '$sClass'");
|
||||
}
|
||||
$sClass = $oCriteria->finalclass;
|
||||
}
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
foreach ($oCriteria as $sAttCode => $value)
|
||||
@@ -944,7 +967,14 @@ class RestUtils
|
||||
foreach ($aFields as $sAttCode => $value)
|
||||
{
|
||||
$realValue = self::MakeValue($sClass, $sAttCode, $value);
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
try
|
||||
{
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
return $oObject;
|
||||
}
|
||||
@@ -964,7 +994,14 @@ class RestUtils
|
||||
foreach ($aFields as $sAttCode => $value)
|
||||
{
|
||||
$realValue = self::MakeValue($sClass, $sAttCode, $value);
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
try
|
||||
{
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ class CLIPage implements Page
|
||||
{
|
||||
MetaModel::RecordQueryTrace();
|
||||
}
|
||||
if (class_exists('ExecutionKPI'))
|
||||
{
|
||||
ExecutionKPI::ReportStats();
|
||||
}
|
||||
}
|
||||
|
||||
public function add($sText)
|
||||
|
||||
@@ -43,39 +43,6 @@ require_once(APPROOT.'/application/ui.extkeywidget.class.inc.php');
|
||||
require_once(APPROOT.'/application/ui.htmleditorwidget.class.inc.php');
|
||||
require_once(APPROOT.'/application/datatable.class.inc.php');
|
||||
|
||||
/**
|
||||
* All objects to be displayed in the application (either as a list or as details)
|
||||
* must implement this interface.
|
||||
*/
|
||||
interface iDisplay
|
||||
{
|
||||
|
||||
/**
|
||||
* Maps the given context parameter name to the appropriate filter/search code for this class
|
||||
* @param string $sContextParam Name of the context parameter, i.e. 'org_id'
|
||||
* @return string Filter code, i.e. 'customer_id'
|
||||
*/
|
||||
public static function MapContextParam($sContextParam);
|
||||
/**
|
||||
* This function returns a 'hilight' CSS class, used to hilight a given row in a table
|
||||
* There are currently (i.e defined in the CSS) 4 possible values HILIGHT_CLASS_CRITICAL,
|
||||
* HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
|
||||
* To Be overridden by derived classes
|
||||
* @param void
|
||||
* @return String The desired higlight class for the object/row
|
||||
*/
|
||||
public function GetHilightClass();
|
||||
/**
|
||||
* Returns the relative path to the page that handles the display of the object
|
||||
* @return string
|
||||
*/
|
||||
public static function GetUIPage();
|
||||
/**
|
||||
* Displays the details of the object
|
||||
*/
|
||||
public function DisplayDetails(WebPage $oPage, $bEditMode = false);
|
||||
}
|
||||
|
||||
abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
{
|
||||
protected $m_iFormId; // The ID of the form used to edit the object (when in edition mode !)
|
||||
@@ -255,14 +222,15 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
|
||||
}
|
||||
|
||||
function DisplayBareHistory(WebPage $oPage, $bEditMode = false)
|
||||
function DisplayBareHistory(WebPage $oPage, $bEditMode = false, $iLimitCount = 0, $iLimitStart = 0)
|
||||
{
|
||||
// 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->Display($oPage, -1);
|
||||
$oBlock->SetLimit($iLimitCount, $iLimitStart);
|
||||
$oBlock->Display($oPage, 'history');
|
||||
}
|
||||
|
||||
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
|
||||
@@ -286,6 +254,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
{
|
||||
$sComment = (isset($aExtraParams['fieldsComments'][$sAttCode])) ? $aExtraParams['fieldsComments'][$sAttCode] : '';
|
||||
$this->DisplayCaseLog($oPage, $sAttCode, $sComment, $sPrefix, $bEditMode);
|
||||
$aFieldsMap[$sAttCode] = $this->m_iFormId.'_'.$sAttCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,6 +305,39 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
{
|
||||
$iFlags = $this->GetAttributeFlags($sAttCode);
|
||||
}
|
||||
// Adjust the flags according to user rights
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
// n:n links => must be allowed to modify the linking class AND read the target class in order to edit the linkedset
|
||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_MODIFY) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ))
|
||||
{
|
||||
$iFlags |= OPT_ATT_READONLY;
|
||||
}
|
||||
// n:n links => must be allowed to read the linking class AND the target class in order to display the linkedset
|
||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_READ) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ))
|
||||
{
|
||||
$iFlags |= OPT_ATT_HIDDEN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1:n links => must be allowed to modify the linked class in order to edit the linkedset
|
||||
if (!UserRights::IsActionAllowed($oAttDef->GetLinkedClass(), UR_ACTION_MODIFY))
|
||||
{
|
||||
$iFlags |= OPT_ATT_READONLY;
|
||||
}
|
||||
// 1:n links => must be allowed to read the linked class in order to display the linkedset
|
||||
if (!UserRights::IsActionAllowed($oAttDef->GetLinkedClass(), UR_ACTION_READ))
|
||||
{
|
||||
$iFlags |= OPT_ATT_HIDDEN;
|
||||
}
|
||||
}
|
||||
// Non-readable/hidden linkedset... don't display anything
|
||||
if ($iFlags & OPT_ATT_HIDDEN) continue;
|
||||
|
||||
$bReadOnly = ($iFlags & (OPT_ATT_READONLY|OPT_ATT_SLAVE));
|
||||
if ($bEditMode && (!$bReadOnly))
|
||||
{
|
||||
@@ -543,6 +545,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0))
|
||||
{
|
||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||
if ($oAttDef->IsWritable())
|
||||
{
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
@@ -553,7 +556,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
}
|
||||
else
|
||||
{
|
||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||
if ($iFlags & OPT_ATT_HIDDEN)
|
||||
{
|
||||
// Attribute is hidden, add a hidden input
|
||||
@@ -602,7 +604,8 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
}
|
||||
else
|
||||
{
|
||||
$val = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => $this->GetAsHTML($sAttCode), 'comments' => $sComments, 'infos' => $sInfos);
|
||||
$val = array('label' => '<span title="'.$oAttDef->GetDescription().'">'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_{$sInputId}\">".$this->GetAsHTML($sAttCode)."</span>", 'comments' => $sComments, 'infos' => $sInfos);
|
||||
$aFieldsMap[$sAttCode] = $sInputId;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -666,8 +669,9 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
|
||||
$this->DisplayBareProperties($oPage, $bEditMode);
|
||||
$this->DisplayBareRelations($oPage, $bEditMode);
|
||||
$oPage->SetCurrentTab(Dict::S('UI:HistoryTab'));
|
||||
$this->DisplayBareHistory($oPage, $bEditMode);
|
||||
//$oPage->SetCurrentTab(Dict::S('UI:HistoryTab'));
|
||||
//$this->DisplayBareHistory($oPage, $bEditMode);
|
||||
$oPage->AddAjaxTab(Dict::S('UI:HistoryTab'), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=history&class='.get_class($this).'&id='.$this->GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1225,6 +1229,8 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
else
|
||||
{
|
||||
$rawValue = $oObj->Get($sAttCodeEx);
|
||||
// Due to custom formatting rules, empty friendlynames may be rendered as non-empty strings
|
||||
// let's fix this and make sure we render an empty string if the key == 0
|
||||
if ($oAttDef instanceof AttributeFriendlyName)
|
||||
{
|
||||
$sKeyAttCode = $oAttDef->GetKeyAttCode();
|
||||
@@ -1599,7 +1605,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
|
||||
$bMandatory = 'true';
|
||||
}
|
||||
$sValidationField = "<span class=\"form_validation\" id=\"v_{$iId}\"></span>";
|
||||
$sHelpText = $oAttDef->GetHelpOnEdition();
|
||||
$sHelpText = htmlentities($oAttDef->GetHelpOnEdition(), ENT_QUOTES, 'UTF-8');
|
||||
$aEventsList = array();
|
||||
switch($oAttDef->GetEditClass())
|
||||
{
|
||||
@@ -2118,6 +2124,138 @@ EOF
|
||||
}
|
||||
return $oObj->DisplayModifyForm( $oPage, $aExtraParams);
|
||||
}
|
||||
|
||||
public function DisplayStimulusForm(WebPage $oPage, $sStimulus)
|
||||
{
|
||||
$sClass = get_class($this);
|
||||
$aTransitions = $this->EnumTransitions();
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
// Invalid stimulus
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $this->GetName(), $this->GetStateLabel()));
|
||||
}
|
||||
$sActionLabel = $aStimuli[$sStimulus]->GetLabel();
|
||||
$sActionDetails = $aStimuli[$sStimulus]->GetDescription();
|
||||
$aTransition = $aTransitions[$sStimulus];
|
||||
$sTargetState = $aTransition['target_state'];
|
||||
$aTargetStates = MetaModel::EnumStates($sClass);
|
||||
$oPage->add("<div class=\"page_header\">\n");
|
||||
$oPage->add("<h1>$sActionLabel - <span class=\"hilite\">{$this->GetName()}</span></h1>\n");
|
||||
$oPage->set_title($sActionLabel);
|
||||
$oPage->add("</div>\n");
|
||||
$aTargetState = $aTargetStates[$sTargetState];
|
||||
$aExpectedAttributes = $aTargetState['attribute_list'];
|
||||
$oPage->add("<h1>$sActionDetails</h1>\n");
|
||||
$sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
|
||||
if ($sButtonsPosition == 'bottom')
|
||||
{
|
||||
// bottom: Displays the ticket details BEFORE the actions
|
||||
$oPage->add('<div class="ui-widget-content">');
|
||||
$this->DisplayBareProperties($oPage);
|
||||
$oPage->add('</div>');
|
||||
}
|
||||
$oPage->add("<div class=\"wizContainer\">\n");
|
||||
$oPage->add("<form id=\"apply_stimulus\" method=\"post\" onSubmit=\"return OnSubmit('apply_stimulus');\">\n");
|
||||
$aDetails = array();
|
||||
$iFieldIndex = 0;
|
||||
$aFieldsMap = array();
|
||||
|
||||
$aDetailsList =$this->FlattenZList(MetaModel::GetZListItems($sClass, 'details'));
|
||||
// Order the fields based on their dependencies, set the fields for which there is only one possible value
|
||||
// and perform this in the order of dependencies to avoid dead-ends
|
||||
$aDeps = array();
|
||||
foreach($aDetailsList as $sAttCode)
|
||||
{
|
||||
$aDeps[$sAttCode] = MetaModel::GetPrequisiteAttributes($sClass, $sAttCode);
|
||||
}
|
||||
$aList =$this->OrderDependentFields($aDeps);
|
||||
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
// Consider only the "expected" fields for the target state
|
||||
if (array_key_exists($sAttCode, $aExpectedAttributes))
|
||||
{
|
||||
$iExpectCode = $aExpectedAttributes[$sAttCode];
|
||||
// Prompt for an attribute if
|
||||
// - the attribute must be changed or must be displayed to the user for confirmation
|
||||
// - or the field is mandatory and currently empty
|
||||
if ( ($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
|
||||
(($iExpectCode & OPT_ATT_MANDATORY) && ($this->Get($sAttCode) == '')) )
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$aArgs = array('this' => $this);
|
||||
// If the field is mandatory, set it to the only possible value
|
||||
if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY))
|
||||
{
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
|
||||
if ($oAllowedValues->Count() == 1)
|
||||
{
|
||||
$oRemoteObj = $oAllowedValues->Fetch();
|
||||
$this->Set($sAttCode, $oRemoteObj->GetKey());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
|
||||
if (count($aAllowedValues) == 1)
|
||||
{
|
||||
$aValues = array_keys($aAllowedValues);
|
||||
$this->Set($sAttCode, $aValues[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,$this->Get($sAttCode),$this->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, $aArgs);
|
||||
$aDetails[] = array('label' => '<span>'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_att_$iFieldIndex\">$sHTMLValue</span>");
|
||||
$aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex;
|
||||
$iFieldIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oPage->add('<table><tr><td>');
|
||||
$oPage->details($aDetails);
|
||||
$oPage->add('</td></tr></table>');
|
||||
$oPage->add("<input type=\"hidden\" name=\"id\" value=\"".$this->GetKey()."\" id=\"id\">\n");
|
||||
$aFieldsMap['id'] = 'id';
|
||||
$oPage->add("<input type=\"hidden\" name=\"class\" value=\"$sClass\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"operation\" value=\"apply_stimulus\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"stimulus\" value=\"$sStimulus\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\">\n");
|
||||
$oAppContext = new ApplicationContext();
|
||||
$oPage->add($oAppContext->GetForForm());
|
||||
$oPage->add("<button type=\"button\" class=\"action\" onClick=\"BackToDetails('$sClass', ".$this->GetKey().")\"><span>".Dict::S('UI:Button:Cancel')."</span></button> \n");
|
||||
$oPage->add("<button type=\"submit\" class=\"action\"><span>$sActionLabel</span></button>\n");
|
||||
$oPage->add("</form>\n");
|
||||
$oPage->add("</div>\n");
|
||||
if ($sButtonsPosition != 'top')
|
||||
{
|
||||
// bottom or both: Displays the ticket details AFTER the actions
|
||||
$oPage->add('<div class="ui-widget-content">');
|
||||
$this->DisplayBareProperties($oPage);
|
||||
$oPage->add('</div>');
|
||||
}
|
||||
|
||||
$iFieldsCount = count($aFieldsMap);
|
||||
$sJsonFieldsMap = json_encode($aFieldsMap);
|
||||
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
// Initializes the object once at the beginning of the page...
|
||||
var oWizardHelper = new WizardHelper('$sClass', '', '$sTargetState');
|
||||
oWizardHelper.SetFieldsMap($sJsonFieldsMap);
|
||||
oWizardHelper.SetFieldsCount($iFieldsCount);
|
||||
EOF
|
||||
);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
// Starts the validation when the page is ready
|
||||
CheckFields('apply_stimulus', false);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
public static function ProcessZlist($aList, $aDetails, $sCurrentTab, $sCurrentCol, $sCurrentSet)
|
||||
{
|
||||
@@ -2356,6 +2494,12 @@ EOF
|
||||
// Dependency is resolved, remove it
|
||||
unset($aFields[$sFieldCode][$key]);
|
||||
}
|
||||
else if (!array_key_exists($sDependency, $aFields))
|
||||
{
|
||||
// The current fields depends on a field not present in the form
|
||||
// let's ignore it (since it cannot change)
|
||||
unset($aFields[$sFieldCode][$key]);
|
||||
}
|
||||
}
|
||||
if (count($aFields[$sFieldCode]) == 0)
|
||||
{
|
||||
@@ -2370,7 +2514,7 @@ EOF
|
||||
|
||||
if (count($aFields) > 0)
|
||||
{
|
||||
$sMessage = "Error: Circular dependencies between the fields (or field missing in ZList) ! <pre>".print_r($aFields, true)."</pre>";
|
||||
$sMessage = "Error: Circular dependencies between the fields! <pre>".print_r($aFields, true)."</pre>";
|
||||
throw(new Exception($sMessage));
|
||||
}
|
||||
return $aResult;
|
||||
@@ -2709,7 +2853,7 @@ EOF
|
||||
$aFinalValues[$sAttCode] = $aValues[$sAttCode];
|
||||
}
|
||||
$this->UpdateObjectFromArray($aFinalValues);
|
||||
|
||||
|
||||
// Invoke extensions after the update of the object from the form
|
||||
foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
@@ -2962,7 +3106,7 @@ EOF
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
// Invalid stimulus
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel()));
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus,$this->GetName(),$this->GetStateLabel()));
|
||||
}
|
||||
$aTransition = $aTransitions[$sStimulus];
|
||||
$sTargetState = $aTransition['target_state'];
|
||||
@@ -3222,9 +3366,10 @@ EOF
|
||||
utils::RemoveTransaction($sTransactionId);
|
||||
}
|
||||
$iPreviousTimeLimit = ini_get('max_execution_time');
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
foreach($aSelectedObj as $iId)
|
||||
{
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$oObj = MetaModel::GetObject($sClass, $iId);
|
||||
$aErrors = $oObj->UpdateObjectFromPostedForm('');
|
||||
$bResult = (count($aErrors) == 0);
|
||||
@@ -3284,12 +3429,12 @@ EOF
|
||||
{
|
||||
foreach($value as $vKey => $vValue)
|
||||
{
|
||||
$oP->add("<input type=\"hidden\" name=\"{$sKey}[$vKey]\" value=\"$vValue\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"{$sKey}[$vKey]\" value=\"".htmlentities($vValue, ENT_QUOTES, 'UTF-8')."\">\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oP->add("<input type=\"hidden\" name=\"$sKey\" value=\"$value\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"$sKey\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\">\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ class CSVPage extends WebPage
|
||||
{
|
||||
MetaModel::RecordQueryTrace();
|
||||
}
|
||||
if (class_exists('ExecutionKPI'))
|
||||
{
|
||||
ExecutionKPI::ReportStats();
|
||||
}
|
||||
}
|
||||
|
||||
public function small_p($sText)
|
||||
|
||||
@@ -784,6 +784,7 @@ class DisplayBlock
|
||||
$sChecked = '';
|
||||
}
|
||||
|
||||
/*
|
||||
$sCSVData = cmdbAbstractObject::GetSetAsCSV($this->m_oSet, array('fields_advanced' => $bAdvancedMode));
|
||||
$sCharset = MetaModel::GetConfig()->Get('csv_file_default_charset');
|
||||
if ($sCharset == 'UTF-8')
|
||||
@@ -812,6 +813,8 @@ class DisplayBlock
|
||||
$sCharsetNotice = '';
|
||||
}
|
||||
|
||||
*/
|
||||
$sCharsetNotice = false;
|
||||
$sHtml .= "<div>";
|
||||
$sHtml .= '<table style="width:100%" class="transparent">';
|
||||
$sHtml .= '<tr>';
|
||||
@@ -827,9 +830,10 @@ class DisplayBlock
|
||||
}
|
||||
$sHtml .= "</div>";
|
||||
|
||||
$sHtml .= "<textarea style=\"width:95%;height:98%\">\n";
|
||||
$sHtml .= htmlentities($sCSVData, ENT_QUOTES, 'UTF-8');
|
||||
$sHtml .= "<div id=\"csv_content_loading\"><div style=\"width: 250px; height: 20px; background: url(../setup/orange-progress.gif); border: 1px #999 solid; margin-left:auto; margin-right: auto; text-align: center;\">".Dict::S('UI:Loading')."</div></div><textarea id=\"csv_content\" style=\"display:none;\">\n";
|
||||
//$sHtml .= htmlentities($sCSVData, ENT_QUOTES, 'UTF-8');
|
||||
$sHtml .= "</textarea>\n";
|
||||
$oPage->add_ready_script("$.post('$sDownloadLink', {}, function(data) { $('#csv_content').html(data); $('#csv_content_loading').hide(); $('#csv_content').show();} );");
|
||||
break;
|
||||
|
||||
case 'modify':
|
||||
@@ -1206,10 +1210,35 @@ EOF
|
||||
*/
|
||||
class HistoryBlock extends DisplayBlock
|
||||
{
|
||||
protected $iLimitCount;
|
||||
protected $iLimitStart;
|
||||
|
||||
public function __construct(DBObjectSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||
{
|
||||
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, $aExtraParams = array(), $sId)
|
||||
{
|
||||
$sHtml = '';
|
||||
$bTruncated = false;
|
||||
$oSet = new CMDBObjectSet($this->m_oFilter, array('date'=>false));
|
||||
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)
|
||||
{
|
||||
@@ -1235,7 +1264,21 @@ class HistoryBlock extends DisplayBlock
|
||||
|
||||
case 'table':
|
||||
default:
|
||||
$sHtml .= $this->GetHistoryTable($oPage, $oSet);
|
||||
if ($bTruncated)
|
||||
{
|
||||
$sFilter = $this->m_oFilter->serialize();
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
||||
return $sHtml;
|
||||
@@ -1307,6 +1350,7 @@ class MenuBlock extends DisplayBlock
|
||||
$sContext = '&'.$sContext;
|
||||
}
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
$oReflectionClass = new ReflectionClass($sClass);
|
||||
$oSet = new CMDBObjectSet($this->m_oFilter);
|
||||
$sFilter = $this->m_oFilter->serialize();
|
||||
$sFilterDesc = $this->m_oFilter->ToOql(true);
|
||||
@@ -1326,7 +1370,7 @@ class MenuBlock extends DisplayBlock
|
||||
$sDefault.= "&default[$sKey]=$sValue";
|
||||
}
|
||||
}
|
||||
$bIsCreationAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) == UR_ALLOWED_YES);
|
||||
$bIsCreationAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
switch($oSet->Count())
|
||||
{
|
||||
case 0:
|
||||
@@ -1337,10 +1381,8 @@ class MenuBlock extends DisplayBlock
|
||||
case 1:
|
||||
$oObj = $oSet->Fetch();
|
||||
$id = $oObj->GetKey();
|
||||
$bIsModifyAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES);
|
||||
$bIsModifyAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
|
||||
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sClass)) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet);
|
||||
$bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet);
|
||||
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
||||
if (!isset($aExtraParams['link_attr']))
|
||||
{
|
||||
@@ -1406,8 +1448,8 @@ class MenuBlock extends DisplayBlock
|
||||
default:
|
||||
// Check rights
|
||||
// New / Modify
|
||||
$bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet);
|
||||
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sClass)) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet);
|
||||
$bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sClass)) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet);
|
||||
if (isset($aExtraParams['link_attr']))
|
||||
{
|
||||
|
||||
@@ -36,7 +36,8 @@ class DesignerForm
|
||||
protected $aSubmitParams;
|
||||
protected $sSubmitTo;
|
||||
protected $bReadOnly;
|
||||
protected $sSelectorClass;
|
||||
protected $sHierarchyPath; // Needed to manage the visibility of nested subform
|
||||
protected $sHierarchyParent; // Needed to manage the visibility of nested subform
|
||||
protected $bDisplayed;
|
||||
|
||||
public function __construct()
|
||||
@@ -50,7 +51,8 @@ class DesignerForm
|
||||
$this->sFormId = 'form_'.rand();
|
||||
$this->oParentForm = null;
|
||||
$this->bReadOnly = false;
|
||||
$this->sSelectorClass = '';
|
||||
$this->sHierarchyPath = '';
|
||||
$this->sHierarchyParent = '';
|
||||
$this->StartFieldSet($this->sCurrentFieldSet);
|
||||
$this->bDisplayed = true;
|
||||
}
|
||||
@@ -151,14 +153,36 @@ class DesignerForm
|
||||
$this->aSubmitParams = $oParentForm->aSubmitParams;
|
||||
}
|
||||
|
||||
public function SetSelectorClass($sSelectorClass)
|
||||
/**
|
||||
* Helper to handle subforms hide/show
|
||||
*/
|
||||
public function SetHierarchyPath($sHierarchy)
|
||||
{
|
||||
$this->sSelectorClass = $sSelectorClass;
|
||||
$this->sHierarchyPath = $sHierarchy;
|
||||
}
|
||||
|
||||
public function GetSelectorClass()
|
||||
/**
|
||||
* Helper to handle subforms hide/show
|
||||
*/
|
||||
public function GetHierarchyPath()
|
||||
{
|
||||
return $this->sSelectorClass;
|
||||
return $this->sHierarchyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle subforms hide/show
|
||||
*/
|
||||
public function SetHierarchyParent($sHierarchy)
|
||||
{
|
||||
$this->sHierarchyParent = $sHierarchy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle subforms hide/show
|
||||
*/
|
||||
public function GetHierarchyParent()
|
||||
{
|
||||
return $this->sHierarchyParent;
|
||||
}
|
||||
|
||||
|
||||
@@ -1219,22 +1243,39 @@ class DesignerFormSelectorField extends DesignerFormField
|
||||
$oSubForm->SetParentForm($this->oForm);
|
||||
$oSubForm->CopySubmitParams($this->oForm);
|
||||
$oSubForm->SetPrefix($this->oForm->GetPrefix().$sKey.'_');
|
||||
$oSubForm->SetSelectorClass("subform_{$sId} {$sId}_{$sKey}");
|
||||
|
||||
if ($sRenderMode == 'property')
|
||||
{
|
||||
// Note: Managing the visibility of nested subforms had several implications
|
||||
// 1) Attributes are displayed in a table and we have to group them in as many tbodys as necessary to hide/show the various options depending on the current selection
|
||||
// 2) It is not possible to nest tbody tags. Therefore, it is not possible to manage the visibility the same way as it is done for the dialog mode (using nested divs).
|
||||
// The div hierarchy has been emulated by adding attributes to the tbody tags:
|
||||
// - data-selector : uniquely identifies the DesignerFormSelectorField that has an impact on the visibility of the node
|
||||
// - data-path : uniquely identifies the combination of users choices that must be made to show the node
|
||||
// - data-state : records the state, depending on the user choice on the FormSelectorField just above the node, but indepentantly from the visibility in the page (can be visible in the form itself being in a hidden form)
|
||||
// Then a series of actions are performed to hide and show the relevant nodes, depending on the user choice
|
||||
$sSelector = $this->oForm->GetHierarchyPath().'/'.$this->sCode;
|
||||
$oSubForm->SetHierarchyParent($sSelector);
|
||||
$sPath = $this->oForm->GetHierarchyPath().'/'.$this->sCode.':'.$sKey;
|
||||
$oSubForm->SetHierarchyPath($sPath);
|
||||
|
||||
$oSubForm->SetDisplayed($sKey == $this->defaultValue);
|
||||
$sHtml .= "</tbody><tbody class=\"subform_{$sId} {$sId}_{$sKey}\" $sStyle>";
|
||||
$sHtml .= $oSubForm->RenderAsPropertySheet($oP, true);
|
||||
$oParentForm = $this->oForm->GetParentForm();
|
||||
if($oParentForm)
|
||||
$sState = ($sKey == $this->defaultValue) ? 'visible' : 'hidden';
|
||||
$sHtml .= "</tbody><tbody data-selector=\"$sSelector\" data-path=\"$sPath\" data-state=\"$sState\" $sStyle>";
|
||||
$sHtml .= $oSubForm->RenderAsPropertySheet($oP, true);
|
||||
|
||||
$sState = $this->oForm->IsDisplayed() ? 'visible' : 'hidden';
|
||||
if ($oParent = $this->oForm->GetParentForm())
|
||||
{
|
||||
$sHtml .= "</tbody><tbody class=\"".$oParentForm->GetSelectorClass()."\">";
|
||||
$sParentSelector = $oParent->GetHierarchyParent();
|
||||
$sParentPath = $oParent->GetHierarchyPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= "</tbody><tbody>";
|
||||
$sParentSelector = '';
|
||||
$sParentPath = '';
|
||||
}
|
||||
$sHtml .= "</tbody><tbody data-selector=\"$sParentSelector\" data-path=\"$sParentPath\" data-state=\"$sState\" $sStyle>";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1244,11 +1285,38 @@ class DesignerFormSelectorField extends DesignerFormField
|
||||
}
|
||||
}
|
||||
|
||||
$oP->add_ready_script(
|
||||
if ($sRenderMode == 'property')
|
||||
{
|
||||
$sSelector = $this->oForm->GetHierarchyPath().'/'.$this->sCode;
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change reverted', function() {
|
||||
// Mark all the direct children as hidden
|
||||
$('tbody[data-selector="$sSelector"]').attr('data-state', 'hidden');
|
||||
// Mark the selected one as visible
|
||||
var sSelectedHierarchy = '$sSelector:'+this.value;
|
||||
$('tbody[data-path="'+sSelectedHierarchy+'"]').attr('data-state', 'visible');
|
||||
|
||||
// Show all items behind the current one
|
||||
$('tbody[data-path^="$sSelector"]').show();
|
||||
// Hide items behind the current one as soon as it is behind a hidden node (or itself is marked as hidden)
|
||||
$('tbody[data-path^="$sSelector"][data-state="hidden"]').each(function(){
|
||||
$(this).hide();
|
||||
var sPath = $(this).attr('data-path');
|
||||
$('tbody[data-path^="'+sPath+'/"]').hide();
|
||||
});
|
||||
});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$sId').bind('change reverted', function() { $('.subform_{$sId}').hide(); $('.{$sId}_'+this.value).show(); } );
|
||||
EOF
|
||||
);
|
||||
);
|
||||
}
|
||||
return array('label' => $this->sLabel, 'value' => $sHtml);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2013 Combodo SARL
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -30,25 +30,21 @@ require_once(APPROOT."/application/user.preferences.class.inc.php");
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
*/
|
||||
class iTopWebPage extends NiceWebPage
|
||||
class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
{
|
||||
private $m_sMenu;
|
||||
// private $m_currentOrganization;
|
||||
private $m_aTabs;
|
||||
private $m_sCurrentTabContainer;
|
||||
private $m_sCurrentTab;
|
||||
private $m_sMessage;
|
||||
private $m_sInitScript;
|
||||
protected $m_oTabs;
|
||||
|
||||
public function __construct($sTitle)
|
||||
{
|
||||
parent::__construct($sTitle);
|
||||
$this->m_oTabs = new TabManager();
|
||||
|
||||
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
|
||||
|
||||
$this->m_sCurrentTabContainer = '';
|
||||
$this->m_sCurrentTab = '';
|
||||
$this->m_aTabs = array();
|
||||
$this->m_sMenu = "";
|
||||
$this->m_sMessage = '';
|
||||
$this->SetRootUrl(utils::GetAbsoluteUrlAppRoot());
|
||||
@@ -111,6 +107,23 @@ function ShowAboutBox()
|
||||
}
|
||||
EOF
|
||||
);
|
||||
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
// Leave the pane opened
|
||||
$sConfigureWestPane = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sConfigureWestPane =
|
||||
<<<EOF
|
||||
if (GetUserPreference('menu_pane', 'open') == 'closed')
|
||||
{
|
||||
myLayout.close('west');
|
||||
}
|
||||
myLayout.addPinBtn( "#tPinMenu", "west" );
|
||||
EOF;
|
||||
}
|
||||
|
||||
$this->m_sInitScript =
|
||||
<<< EOF
|
||||
@@ -163,13 +176,9 @@ EOF
|
||||
}
|
||||
});
|
||||
window.clearTimeout(iPaneVisWatchDog);
|
||||
myLayout.addPinBtn( "#tPinMenu", "west" );
|
||||
//myLayout.open( "west" );
|
||||
$('.ui-layout-resizer-west .ui-layout-toggler').css({background: 'transparent'});
|
||||
if (GetUserPreference('menu_pane', 'open') == 'closed')
|
||||
{
|
||||
myLayout.close('west');
|
||||
}
|
||||
$sConfigureWestPane
|
||||
|
||||
$('#left-pane').layout({ resizable: false, spacing_open: 0, south: { size: 94 }, enableCursorHotkey: false });
|
||||
|
||||
@@ -190,16 +199,31 @@ EOF
|
||||
// unless their URL is equal to the URL of the page...
|
||||
$('div[id^=tabbedContent] > ul > li > a').each(function() {
|
||||
var sHash = location.hash;
|
||||
var sCleanLocation = location.href.toString().replace(sHash, '').replace(/#$/, '');
|
||||
$(this).attr("href", sCleanLocation+$(this).attr("href"));
|
||||
var sHref = $(this).attr("href");
|
||||
if (sHref.match(/^#/))
|
||||
{
|
||||
var sCleanLocation = location.href.toString().replace(sHash, '').replace(/#$/, '');
|
||||
$(this).attr("href", sCleanLocation+$(this).attr("href"));
|
||||
}
|
||||
});
|
||||
|
||||
// Enable tabs on all tab widgets. The `event` property must be overridden so
|
||||
// that the tabs aren't changed on click, and any custom event name can be
|
||||
// specified. Note that if you define a callback for the 'select' event, it
|
||||
// will be executed for the selected tab whenever the hash changes.
|
||||
tabs.tabs({ event: 'change', 'show': function(event, ui) {
|
||||
tabs.tabs({
|
||||
event: 'change', 'show': function(event, ui) {
|
||||
$('.resizable', ui.panel).resizable(); // Make resizable everything that claims to be resizable !
|
||||
},
|
||||
beforeLoad: function( event, ui ) {
|
||||
if ( ui.tab.data('loaded') && (ui.tab.attr('data-cache') == 'true')) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
ui.panel.html('<div><img src="../images/indicator.gif"></div>');
|
||||
ui.jqXHR.success(function() {
|
||||
ui.tab.data( "loaded", true );
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -214,6 +238,7 @@ EOF
|
||||
}
|
||||
EOF
|
||||
;
|
||||
|
||||
$this->add_ready_script(
|
||||
<<< EOF
|
||||
|
||||
@@ -537,6 +562,7 @@ EOF
|
||||
$sNorthPane .= '<div id="admin-banner"><span style="padding:5px;">'.ExecutionKPI::GetDescription().'<span></div>';
|
||||
}
|
||||
|
||||
//$sSouthPane = '<p>Peak memory Usage: '.sprintf('%.3f MB', memory_get_peak_usage(true) / (1024*1024)).'</p>';
|
||||
$sSouthPane = '';
|
||||
foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
@@ -660,34 +686,7 @@ EOF
|
||||
$sOnClick = " onclick=\"this.value='';this.onclick=null;\"";
|
||||
}
|
||||
// Render the tabs in the page (if any)
|
||||
foreach($this->m_aTabs as $sTabContainerName => $m_aTabs)
|
||||
{
|
||||
$sTabs = '';
|
||||
$container_index = 0;
|
||||
if (count($m_aTabs) > 0)
|
||||
{
|
||||
$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$container_index}\" class=\"light\">\n";
|
||||
$sTabs .= "<ul>\n";
|
||||
// Display the unordered list that will be rendered as the tabs
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<li><a href=\"#tab_{$container_index}$i\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</ul>\n";
|
||||
// Now add the content of the tabs themselves
|
||||
$i = 0;
|
||||
foreach($m_aTabs as $sTabName => $sTabContent)
|
||||
{
|
||||
$sTabs .= "<div id=\"tab_{$container_index}$i\">".$sTabContent."</div>\n";
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</div>\n<!-- end of tabs-->\n";
|
||||
}
|
||||
$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
|
||||
$container_index++;
|
||||
}
|
||||
$this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content);
|
||||
|
||||
if ($this->GetOutputFormat() == 'html')
|
||||
{
|
||||
@@ -790,7 +789,10 @@ EOF
|
||||
$sHtml .= ' <div id="top-left"></div><div id="logo"><a href="'.htmlentities($sIconUrl, ENT_QUOTES, 'UTF-8').'"><img src="'.$sDisplayIcon.'" title="'.htmlentities($sVersionString, ENT_QUOTES, 'UTF-8').'" style="border:0; margin-top:16px; margin-right:40px;"/></a></div>';
|
||||
$sHtml .= ' </div>';
|
||||
$sHtml .= ' <div class="header-menu">';
|
||||
$sHtml .= ' <div class="icon ui-state-default ui-corner-all"><span id="tPinMenu" class="ui-icon ui-icon-pin-w">pin</span></div>';
|
||||
if (!MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
$sHtml .= ' <div class="icon ui-state-default ui-corner-all"><span id="tPinMenu" class="ui-icon ui-icon-pin-w">pin</span></div>';
|
||||
}
|
||||
$sHtml .= ' <div style="text-align:center;">'.self::FilterXSS($sForm).'</div>';
|
||||
$sHtml .= ' </div>';
|
||||
$sHtml .= ' </div>';
|
||||
@@ -875,62 +877,51 @@ EOF
|
||||
ExecutionKPI::ReportStats();
|
||||
}
|
||||
|
||||
public function AddTabContainer($sTabContainer)
|
||||
public function AddTabContainer($sTabContainer, $sPrefix = '')
|
||||
{
|
||||
$this->m_aTabs[$sTabContainer] = array();
|
||||
$this->add("\$Tabs:$sTabContainer\$");
|
||||
$this->add($this->m_oTabs->AddTabContainer($sTabContainer, $sPrefix));
|
||||
}
|
||||
|
||||
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
|
||||
{
|
||||
if (!isset($this->m_aTabs[$sTabContainer][$sTabLabel]))
|
||||
{
|
||||
// Set the content of the tab
|
||||
$this->m_aTabs[$sTabContainer][$sTabLabel] = $sHtml;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append to the content of the tab
|
||||
$this->m_aTabs[$sTabContainer][$sTabLabel] .= $sHtml;
|
||||
}
|
||||
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabLabel, $sHtml));
|
||||
}
|
||||
|
||||
public function SetCurrentTabContainer($sTabContainer = '')
|
||||
{
|
||||
$sPreviousTabContainer = $this->m_sCurrentTabContainer;
|
||||
$this->m_sCurrentTabContainer = $sTabContainer;
|
||||
return $sPreviousTabContainer;
|
||||
return $this->m_oTabs->SetCurrentTabContainer($sTabContainer);
|
||||
}
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '')
|
||||
{
|
||||
$sPreviousTab = $this->m_sCurrentTab;
|
||||
$this->m_sCurrentTab = $sTabLabel;
|
||||
return $sPreviousTab;
|
||||
return $this->m_oTabs->SetCurrentTab($sTabLabel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a tab which content will be loaded asynchronously via the supplied URL
|
||||
*
|
||||
* Limitations:
|
||||
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to pull content from another server.
|
||||
* Static content cannot be added inside such tabs.
|
||||
*
|
||||
* @param string $sTabLabel The (localised) label of the tab
|
||||
* @param string $sUrl The URL to load (on the same server)
|
||||
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause the tab to be reloaded upon each activation.
|
||||
* @since 2.0.3
|
||||
*/
|
||||
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true)
|
||||
{
|
||||
$this->add($this->m_oTabs->AddAjaxTab($sTabLabel, $sUrl, $bCache));
|
||||
}
|
||||
|
||||
public function GetCurrentTab()
|
||||
{
|
||||
return $this->m_sCurrentTab;
|
||||
return $this->m_oTabs->GetCurrentTab();
|
||||
}
|
||||
|
||||
public function RemoveTab($sTabLabel, $sTabContainer = null)
|
||||
{
|
||||
if ($sTabContainer == null)
|
||||
{
|
||||
$sTabContainer = $this->m_sCurrentTabContainer;
|
||||
}
|
||||
if (isset($this->m_aTabs[$sTabContainer][$sTabLabel]))
|
||||
{
|
||||
// Delete the content of the tab
|
||||
unset($this->m_aTabs[$sTabContainer][$sTabLabel]);
|
||||
|
||||
// If we just removed the active tab, let's reset the active tab
|
||||
if (($this->m_sCurrentTabContainer == $sTabContainer) && ($this->m_sCurrentTab == $sTabLabel))
|
||||
{
|
||||
$this->m_sCurrentTab = '';
|
||||
}
|
||||
}
|
||||
$this->m_oTabs->RemoveTab($sTabLabel, $sTabContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -939,20 +930,7 @@ EOF
|
||||
*/
|
||||
public function FindTab($sPattern, $sTabContainer = null)
|
||||
{
|
||||
$return = false;
|
||||
if ($sTabContainer == null)
|
||||
{
|
||||
$sTabContainer = $this->m_sCurrentTabContainer;
|
||||
}
|
||||
foreach($this->m_aTabs[$sTabContainer] as $sTabLabel => $void)
|
||||
{
|
||||
if (preg_match($sPattern, $sTabLabel))
|
||||
{
|
||||
$result = $sTabLabel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
return $this->m_oTabs->FindTab($sPattern, $sTabContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -963,26 +941,7 @@ EOF
|
||||
*/
|
||||
public function SelectTab($sTabContainer, $sTabLabel)
|
||||
{
|
||||
$container_index = 0;
|
||||
$tab_index = 0;
|
||||
foreach($this->m_aTabs as $sCurrentTabContainerName => $aTabs)
|
||||
{
|
||||
if ($sTabContainer == $sCurrentTabContainerName)
|
||||
{
|
||||
foreach($aTabs as $sCurrentTabLabel => $void)
|
||||
{
|
||||
if ($sCurrentTabLabel == $sTabLabel)
|
||||
{
|
||||
break;
|
||||
}
|
||||
$tab_index++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
$container_index++;
|
||||
}
|
||||
$sSelector = '#tabbedContent_'.$container_index.' > ul';
|
||||
$this->add_ready_script("window.setTimeout(\"$('$sSelector').tabs('select', $tab_index);\", 100);"); // Let the time to the tabs widget to initialize
|
||||
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabLabel));
|
||||
}
|
||||
|
||||
public function StartCollapsibleSection($sSectionLabel, $bOpen = false)
|
||||
@@ -1016,9 +975,9 @@ EOF
|
||||
|
||||
public function add($sHtml)
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
if (($this->m_oTabs->GetCurrentTabContainer() != '') && ($this->m_oTabs->GetCurrentTab() != ''))
|
||||
{
|
||||
$this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
|
||||
$this->m_oTabs->AddToCurrentTab($sHtml);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1032,10 +991,13 @@ EOF
|
||||
*/
|
||||
public function start_capture()
|
||||
{
|
||||
if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
|
||||
$sCurrentTabContainer = $this->m_oTabs->GetCurrentTabContainer();
|
||||
$sCurrentTab = $this->m_oTabs->GetCurrentTab();
|
||||
|
||||
if (!empty($sCurrentTabContainer) && !empty($sCurrentTab))
|
||||
{
|
||||
$iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]): 0;
|
||||
return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset);
|
||||
$iOffset = $this->m_oTabs->GetCurrentTabLength();
|
||||
return array('tc' => $sCurrentTabContainer, 'tab' => $sCurrentTab, 'offset' => $iOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1053,10 +1015,9 @@ EOF
|
||||
{
|
||||
if (is_array($offset))
|
||||
{
|
||||
if (isset($this->m_aTabs[$offset['tc']][$offset['tab']]))
|
||||
if ($this->m_oTabs->TabExists($offset['tc'], $offset['tab']))
|
||||
{
|
||||
$sCaptured = substr($this->m_aTabs[$offset['tc']][$offset['tab']], $offset['offset']);
|
||||
$this->m_aTabs[$offset['tc']][$offset['tab']] = substr($this->m_aTabs[$offset['tc']][$offset['tab']], 0, $offset['offset']);
|
||||
$sCaptured = $this->m_oTabs->TruncateTab($offset['tc'], $offset['tab'], $offset['offset']);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -33,7 +33,15 @@ class LoginWebPage extends NiceWebPage
|
||||
{
|
||||
const EXIT_PROMPT = 0;
|
||||
const EXIT_HTTP_401 = 1;
|
||||
|
||||
const EXIT_RETURN = 2;
|
||||
|
||||
const EXIT_CODE_OK = 0;
|
||||
const EXIT_CODE_MISSINGLOGIN = 1;
|
||||
const EXIT_CODE_MISSINGPASSWORD = 2;
|
||||
const EXIT_CODE_WRONGCREDENTIALS = 3;
|
||||
const EXIT_CODE_MUSTBEADMIN = 4;
|
||||
const EXIT_CODE_PORTALUSERNOTAUTHORIZED = 5;
|
||||
|
||||
protected static $sHandlerClass = __class__;
|
||||
public static function RegisterHandler($sClass)
|
||||
{
|
||||
@@ -105,6 +113,7 @@ class LoginWebPage extends NiceWebPage
|
||||
case 'url':
|
||||
$this->add_header('WWW-Authenticate: Basic realm="'.Dict::Format('UI:iTopVersion:Short', ITOP_VERSION));
|
||||
$this->add_header('HTTP/1.0 401 Unauthorized');
|
||||
$this->add_header('Content-type: text/html; charset=iso-8859-1');
|
||||
// Note: displayed when the user will click on Cancel
|
||||
$this->add('<p><strong>'.Dict::S('UI:Login:Error:AccessRestricted').'</strong></p>');
|
||||
break;
|
||||
@@ -145,6 +154,8 @@ class LoginWebPage extends NiceWebPage
|
||||
}
|
||||
$this->add("</table>\n");
|
||||
$this->add("<input type=\"hidden\" name=\"loginop\" value=\"login\" />\n");
|
||||
|
||||
$this->add_ready_script('$("#user").focus();');
|
||||
|
||||
// Keep the OTHER parameters posted
|
||||
foreach($_POST as $sPostedKey => $postedValue)
|
||||
@@ -190,7 +201,7 @@ class LoginWebPage extends NiceWebPage
|
||||
$this->add("<p>".Dict::S('UI:Login:ForgotPwdForm+')."</p>\n");
|
||||
if ($bFailedToReset)
|
||||
{
|
||||
$this->add("<p class=\"hilite\">".Dict::Format('UI:Login:ResetPwdFailed', $sFailureReason)."</p>\n");
|
||||
$this->add("<p class=\"hilite\">".Dict::Format('UI:Login:ResetPwdFailed', htmlentities($sFailureReason, ENT_QUOTES, 'UTF-8'))."</p>\n");
|
||||
}
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', true, 'raw_data');
|
||||
$this->add("<form method=\"post\">\n");
|
||||
@@ -201,6 +212,8 @@ class LoginWebPage extends NiceWebPage
|
||||
$this->add("<input type=\"hidden\" name=\"loginop\" value=\"forgot_pwd_go\" />\n");
|
||||
$this->add("</form>\n");
|
||||
$this->add("</div>\n");
|
||||
|
||||
$this->add_ready_script('$("#user").focus();');
|
||||
}
|
||||
|
||||
protected function ForgotPwdGo()
|
||||
@@ -238,7 +251,12 @@ class LoginWebPage extends NiceWebPage
|
||||
|
||||
$oEmail = new Email();
|
||||
$oEmail->SetRecipientTO($sTo);
|
||||
$oEmail->SetRecipientFrom($sTo);
|
||||
$sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
|
||||
if ($sFrom == '')
|
||||
{
|
||||
$sFrom = $sTo;
|
||||
}
|
||||
$oEmail->SetRecipientFrom($sFrom);
|
||||
$oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject'));
|
||||
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
|
||||
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl));
|
||||
@@ -419,10 +437,29 @@ EOF
|
||||
return MetaModel::GetConfig()->GetSecureConnectionRequired();
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess if a string looks like an UTF-8 string based on some ranges of multi-bytes encoding
|
||||
* @param string $sString
|
||||
* @return bool True if the string contains some typical UTF-8 multi-byte sequences
|
||||
*/
|
||||
static function LooksLikeUTF8($sString)
|
||||
{
|
||||
return preg_match('%(?:
|
||||
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
|\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
|\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
|\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
|[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
||||
|\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)+%xs', $sString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt a login
|
||||
*
|
||||
* @param int iOnExit What action to take if the user is not logged on (one of the class constants EXIT_...)
|
||||
* @return int One of the class constants EXIT_CODE_...
|
||||
*/
|
||||
protected static function Login($iOnExit)
|
||||
{
|
||||
@@ -439,7 +476,7 @@ EOF
|
||||
//echo "User: ".$_SESSION['auth_user']."\n";
|
||||
// Already authentified
|
||||
UserRights::Login($_SESSION['auth_user']); // Login & set the user's language
|
||||
return true;
|
||||
return self::EXIT_CODE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -466,8 +503,8 @@ EOF
|
||||
case 'form':
|
||||
// iTop standard mode: form based authentication
|
||||
$sAuthUser = utils::ReadPostedParam('auth_user', '', false, 'raw_data');
|
||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', '', false, 'raw_data');
|
||||
if ($sAuthUser != '')
|
||||
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, false, 'raw_data');
|
||||
if (($sAuthUser != '') && ($sAuthPwd !== null))
|
||||
{
|
||||
$sLoginMode = 'form';
|
||||
}
|
||||
@@ -484,7 +521,22 @@ EOF
|
||||
else if (isset($_SERVER['PHP_AUTH_USER']))
|
||||
{
|
||||
$sAuthUser = $_SERVER['PHP_AUTH_USER'];
|
||||
// Unfortunately, the RFC is not clear about the encoding...
|
||||
// IE and FF supply the user and password encoded in ISO-8859-1 whereas Chrome provides them encoded in UTF-8
|
||||
// So let's try to guess if it's an UTF-8 string or not... fortunately all encodings share the same ASCII base
|
||||
if (!self::LooksLikeUTF8($sAuthUser))
|
||||
{
|
||||
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
||||
// Supposed to be harmless in case of a plain ASCII string...
|
||||
$sAuthUser = iconv('iso-8859-1', 'utf-8', $sAuthUser);
|
||||
}
|
||||
$sAuthPwd = $_SERVER['PHP_AUTH_PW'];
|
||||
if (!self::LooksLikeUTF8($sAuthPwd))
|
||||
{
|
||||
// Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8
|
||||
// Supposed to be harmless in case of a plain ASCII string...
|
||||
$sAuthPwd = iconv('iso-8859-1', 'utf-8', $sAuthPwd);
|
||||
}
|
||||
$sLoginMode = 'basic';
|
||||
}
|
||||
break;
|
||||
@@ -506,7 +558,7 @@ EOF
|
||||
// Credentials passed directly in the url
|
||||
$sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data');
|
||||
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
|
||||
if (($sAuthUser != '') && ($sAuthPwd != null))
|
||||
if (($sAuthUser != '') && ($sAuthPwd !== null))
|
||||
{
|
||||
$sLoginMode = 'url';
|
||||
}
|
||||
@@ -527,11 +579,24 @@ EOF
|
||||
{
|
||||
$sLoginMode = $aAllowedLoginTypes[0]; // First in the list...
|
||||
}
|
||||
if ($iOnExit == self::EXIT_HTTP_401)
|
||||
if (($iOnExit == self::EXIT_HTTP_401) || ($sLoginMode == 'basic'))
|
||||
{
|
||||
header("HTTP/1.0 401 Unauthorized");
|
||||
header('WWW-Authenticate: Basic realm="'.Dict::Format('UI:iTopVersion:Short', ITOP_VERSION));
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
header('Content-type: text/html; charset=iso-8859-1');
|
||||
exit;
|
||||
}
|
||||
else if($iOnExit == self::EXIT_RETURN)
|
||||
{
|
||||
if (($sAuthUser !== '') && ($sAuthPwd === null))
|
||||
{
|
||||
return self::EXIT_CODE_MISSINGPASSWORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::EXIT_CODE_MISSINGLOGIN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage = self::NewLoginWebPage();
|
||||
@@ -546,11 +611,17 @@ EOF
|
||||
{
|
||||
//echo "Check Credentials returned false for user $sAuthUser!";
|
||||
self::ResetSession();
|
||||
if ($iOnExit == self::EXIT_HTTP_401)
|
||||
if (($iOnExit == self::EXIT_HTTP_401) || ($sLoginMode == 'basic'))
|
||||
{
|
||||
header("HTTP/1.0 401 Unauthorized");
|
||||
header('WWW-Authenticate: Basic realm="'.Dict::Format('UI:iTopVersion:Short', ITOP_VERSION));
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
header('Content-type: text/html; charset=iso-8859-1');
|
||||
exit;
|
||||
}
|
||||
else if($iOnExit == self::EXIT_RETURN)
|
||||
{
|
||||
return self::EXIT_CODE_WRONGCREDENTIALS;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage = self::NewLoginWebPage();
|
||||
@@ -578,18 +649,31 @@ EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
return self::EXIT_CODE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridable: depending on the user, head toward a dedicated portal
|
||||
* @param bool $bIsAllowedToPortalUsers Whether or not the current page is considered as part of the portal
|
||||
* @param int $iOnExit How to complete the call: redirect or return a code
|
||||
*/
|
||||
protected static function ChangeLocation($bIsAllowedToPortalUsers)
|
||||
protected static function ChangeLocation($bIsAllowedToPortalUsers, $iOnExit = self::EXIT_PROMPT)
|
||||
{
|
||||
if ( (!$bIsAllowedToPortalUsers) && (UserRights::IsPortalUser()))
|
||||
{
|
||||
// No rights to be here, redirect to the portal
|
||||
header('Location: '.utils::GetAbsoluteUrlAppRoot().'portal/index.php');
|
||||
if ($iOnExit == self::EXIT_RETURN)
|
||||
{
|
||||
return self::EXIT_CODE_PORTALUSERNOTAUTHORIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No rights to be here, redirect to the portal
|
||||
header('Location: '.utils::GetAbsoluteUrlAppRoot().'portal/index.php');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::EXIT_CODE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,18 +768,35 @@ EOF
|
||||
$sMessage = Dict::S('UI:Login:PasswordChanged');
|
||||
}
|
||||
|
||||
self::Login($iOnExit);
|
||||
$iRet = self::Login($iOnExit);
|
||||
|
||||
if ($bMustBeAdmin && !UserRights::IsAdministrator())
|
||||
{
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new SetupPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
||||
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a>");
|
||||
$oP->output();
|
||||
exit;
|
||||
if ($iRet == self::EXIT_CODE_OK)
|
||||
{
|
||||
if ($bMustBeAdmin && !UserRights::IsAdministrator())
|
||||
{
|
||||
if ($iOnExit == self::EXIT_RETURN)
|
||||
{
|
||||
return self::EXIT_CODE_MUSTBEADMIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
$oP = new SetupPage(Dict::S('UI:PageTitle:FatalError'));
|
||||
$oP->add("<h1>".Dict::S('UI:Login:Error:AccessAdmin')."</h1>\n");
|
||||
$oP->p("<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a>");
|
||||
$oP->output();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$iRet = call_user_func(array(self::$sHandlerClass, 'ChangeLocation'), $bIsAllowedToPortalUsers, $iOnExit);
|
||||
}
|
||||
if ($iOnExit == self::EXIT_RETURN)
|
||||
{
|
||||
return $iRet;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $sMessage;
|
||||
}
|
||||
call_user_func(array(self::$sHandlerClass, 'ChangeLocation'), $bIsAllowedToPortalUsers);
|
||||
return $sMessage;
|
||||
}
|
||||
} // End of class
|
||||
|
||||
@@ -324,7 +324,7 @@ EOF
|
||||
|
||||
$sUniqueId = $sClass.$this->GetUniqueId();
|
||||
$this->add("<div id=\"$sUniqueId\">\n"); // The id here MUST be the same as currentId, otherwise the pagination will be broken
|
||||
cmdbAbstractObject::DisplaySet($this, $oSet, array('currentId' => $sUniqueId, 'menu' => false, 'zlist' => false, 'extra_fields' => implode(',', $aZList)));
|
||||
cmdbAbstractObject::DisplaySet($this, $oSet, array('currentId' => $sUniqueId, 'menu' => false, 'toolkit_menu' => false, 'zlist' => false, 'extra_fields' => implode(',', $aZList)));
|
||||
$this->add("</div>\n");
|
||||
}
|
||||
else
|
||||
@@ -420,7 +420,7 @@ EOF
|
||||
}
|
||||
$oObjSearch->AddCondition_ReferencedBy($oLinkSet->GetFilter(), $sRemoteAttCode);
|
||||
|
||||
$aExtraParams = array('menu' => false, 'zlist' => false, 'extra_fields' => implode(',', $aZList));
|
||||
$aExtraParams = array('menu' => false, 'toolkit_menu' => false, 'zlist' => false, 'extra_fields' => implode(',', $aZList));
|
||||
$oBlock = new DisplayBlock($oObjSearch, 'list', false);
|
||||
$oBlock->Display($this, 1, $aExtraParams);
|
||||
}
|
||||
@@ -480,7 +480,9 @@ EOF
|
||||
{
|
||||
try
|
||||
{
|
||||
$oAllowedValues = new DBObjectSet(DBObjectSearch::FromOQL(constant($sFilterDefName)), array(), $aFilterParams);
|
||||
$oFitlerWithParams = DBObjectSearch::FromOQL(constant($sFilterDefName));
|
||||
$sFilterOQL = $oFitlerWithParams->ToOQL(true, $aFilterParams);
|
||||
$oAllowedValues = new DBObjectSet(DBObjectSearch::FromOQL($sFilterOQL), array(), $aFilterParams);
|
||||
}
|
||||
catch(OQLException $e)
|
||||
{
|
||||
@@ -510,7 +512,8 @@ EOF
|
||||
if (is_null($aAllowedValues))
|
||||
{
|
||||
// Any value is possible, display an input box
|
||||
$this->add("<label>".MetaModel::GetFilterLabel($sClass, $sAttSpec).":</label> <input class=\"textSearch\" name=\"$sPrefix$sFieldName\" value=\"$sFilterValue\"/>\n");
|
||||
$sSanitizedValue = htmlentities($sFilterValue, ENT_QUOTES, 'UTF-8');
|
||||
$this->add("<label>".MetaModel::GetFilterLabel($sClass, $sAttSpec).":</label> <input class=\"textSearch\" name=\"$sPrefix$sFieldName\" value=\"$sSanitizedValue\"/>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -793,24 +796,7 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
$sOQL = "SELECT $sClass WHERE org_id = :org_id";
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
$iUser = UserRights::GetContactId();
|
||||
if ($iUser > 0 && !IsPowerUser())
|
||||
{
|
||||
$oSearch->AddCondition('caller_id', $iUser);
|
||||
}
|
||||
$oSearch->AddCondition('id', $iId);
|
||||
|
||||
$oContact = MetaModel::GetObject('Contact', $iUser, false); // false => Can fail
|
||||
if (!is_object($oContact))
|
||||
{
|
||||
throw new Exception(Dict::S('Portal:ErrorNoContactForThisUser'));
|
||||
}
|
||||
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('org_id' => $oContact->Get('org_id')));
|
||||
|
||||
$oObj = $oSet->Fetch();
|
||||
$oObj = MetaModel::GetObject($sClass, $iId, false);
|
||||
if (!is_object($oObj))
|
||||
{
|
||||
throw new Exception("Could not find the object $sClass/$iId");
|
||||
|
||||
@@ -53,7 +53,7 @@ abstract class Query extends cmdbAbstractObject
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'fields')); // 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')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'fields')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class QueryOQL extends Query
|
||||
MetaModel::Init_SetZListItems('details', array('name', 'description', 'oql', 'fields')); // 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')); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems('standard_search', array('name', 'description', 'fields', 'oql')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
@@ -453,7 +453,7 @@ EOF
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true));
|
||||
$oPage->add('</div></div></div>');
|
||||
// $oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: $(window).width()*0.8, height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').removeAttr('onsubmit');");
|
||||
$oPage->add_ready_script("$('#dcr_{$this->iId} form').bind('submit.uilinksWizard', oACWidget_{$this->iId}.DoCreateObject);");
|
||||
}
|
||||
@@ -557,6 +557,7 @@ EOF
|
||||
$aSortedRoots = $aTree[$iRootId];
|
||||
asort($aSortedRoots);
|
||||
$oP->add("<ul>\n");
|
||||
$fUniqueId = microtime(true);
|
||||
foreach($aSortedRoots as $id => $sName)
|
||||
{
|
||||
if ($bSelect)
|
||||
@@ -564,14 +565,14 @@ EOF
|
||||
$sChecked = ($aNodes[$id]->GetKey() == $currValue) ? 'checked' : '';
|
||||
if ($bMultiple)
|
||||
{
|
||||
$sSelect = '<input type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="checkbox" value="'.$aNodes[$id]->GetKey().'" name="selectObject[]" '.$sChecked.'> ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSelect = '<input type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
||||
$sSelect = '<input id="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'" type="radio" value="'.$aNodes[$id]->GetKey().'" name="selectObject" '.$sChecked.'> ';
|
||||
}
|
||||
}
|
||||
$oP->add('<li>'.$sSelect.$aNodes[$id]->GetHyperlink());
|
||||
$oP->add('<li>'.$sSelect.'<label for="input_'.$fUniqueId.'_'.$aNodes[$id]->GetKey().'">'.$aNodes[$id]->GetName().'</label>');
|
||||
$this->DumpNodes($oP, $id, $aTree, $aNodes, $currValue);
|
||||
$oP->add("</li>\n");
|
||||
}
|
||||
|
||||
@@ -318,12 +318,11 @@ class UILinksWidgetDirect
|
||||
{
|
||||
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||
}
|
||||
$aArgs = array();
|
||||
if ($oCurrentObj != null)
|
||||
{
|
||||
$aArgs = $oCurrentObj->ToArgs('this');
|
||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||
$oFilter->SetInternalParams($aArgs);
|
||||
}
|
||||
$oFilter->SetInternalParams($aArgs);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", array('menu' => false, 'cssCount'=> '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
@@ -492,6 +492,10 @@ class WebPage implements Page
|
||||
{
|
||||
MetaModel::RecordQueryTrace();
|
||||
}
|
||||
if (class_exists('ExecutionKPI'))
|
||||
{
|
||||
ExecutionKPI::ReportStats();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,7 +657,7 @@ class WebPage implements Page
|
||||
foreach ($aActions as $aAction)
|
||||
{
|
||||
$sClass = isset($aAction['class']) ? " class=\"{$aAction['class']}\"" : "";
|
||||
$sOnClick = isset($aAction['onclick']) ? " onclick=\"{$aAction['onclick']}\"" : "";
|
||||
$sOnClick = isset($aAction['onclick']) ? ' onclick="'.htmlspecialchars($aAction['onclick'], ENT_QUOTES, "UTF-8").'"' : '';
|
||||
$sTarget = isset($aAction['target']) ? " target=\"{$aAction['target']}\"" : "";
|
||||
if (empty($aAction['url']))
|
||||
{
|
||||
@@ -714,4 +718,291 @@ class WebPage implements Page
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
interface iTabbedPage
|
||||
{
|
||||
public function AddTabContainer($sTabContainer, $sPrefix = '');
|
||||
|
||||
public function AddToTab($sTabContainer, $sTabLabel, $sHtml);
|
||||
|
||||
public function SetCurrentTabContainer($sTabContainer = '');
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '');
|
||||
|
||||
/**
|
||||
* Add a tab which content will be loaded asynchronously via the supplied URL
|
||||
*
|
||||
* Limitations:
|
||||
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to pull content from another server.
|
||||
* Static content cannot be added inside such tabs.
|
||||
*
|
||||
* @param string $sTabLabel The (localised) label of the tab
|
||||
* @param string $sUrl The URL to load (on the same server)
|
||||
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause the tab to be reloaded upon each activation.
|
||||
* @since 2.0.3
|
||||
*/
|
||||
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true);
|
||||
|
||||
public function GetCurrentTab();
|
||||
|
||||
public function RemoveTab($sTabLabel, $sTabContainer = null);
|
||||
|
||||
/**
|
||||
* Finds the tab whose title matches a given pattern
|
||||
* @return mixed The name of the tab as a string or false if not found
|
||||
*/
|
||||
public function FindTab($sPattern, $sTabContainer = null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to implement JQueryUI tabs inside a page
|
||||
*/
|
||||
class TabManager
|
||||
{
|
||||
protected $m_aTabs;
|
||||
protected $m_sCurrentTabContainer;
|
||||
protected $m_sCurrentTab;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->m_aTabs = array();
|
||||
$this->m_sCurrentTabContainer = '';
|
||||
$this->m_sCurrentTab = '';
|
||||
}
|
||||
|
||||
public function AddTabContainer($sTabContainer, $sPrefix = '')
|
||||
{
|
||||
$this->m_aTabs[$sTabContainer] = array('prefix' => $sPrefix, 'tabs' => array());
|
||||
return "\$Tabs:$sTabContainer\$";
|
||||
}
|
||||
|
||||
public function AddToCurrentTab($sHtml)
|
||||
{
|
||||
$this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
|
||||
}
|
||||
|
||||
public function GetCurrentTabLength($sHtml)
|
||||
{
|
||||
$iLength = isset($this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$this->m_sCurrentTab]['html']) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$this->m_sCurrentTab]['html']): 0;
|
||||
return $iLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the given tab to the specifed length and returns the truncated part
|
||||
* @param string $sTabContainer The tab container in which to truncate the tab
|
||||
* @param string $sTab The name/identifier of the tab to truncate
|
||||
* @param integer $iLength The length/offset at which to truncate the tab
|
||||
* @return string The truncated part
|
||||
*/
|
||||
public function TruncateTab($sTabContainer, $sTab, $iLength)
|
||||
{
|
||||
$sResult = substr($this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$this->m_sCurrentTab]['html'], $iLength);
|
||||
$this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$this->m_sCurrentTab]['html'] = substr($this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$this->m_sCurrentTab]['html'], 0, $iLength);
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
public function TabExists($sTabContainer, $sTab)
|
||||
{
|
||||
return isset($this->m_aTabs[$sTabContainer]['tabs'][$sTab]);
|
||||
}
|
||||
|
||||
public function TabsContainerCount()
|
||||
{
|
||||
return count($this->m_aTabs);
|
||||
}
|
||||
|
||||
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
|
||||
{
|
||||
if (!isset($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]))
|
||||
{
|
||||
// Set the content of the tab
|
||||
$this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel] = array(
|
||||
'type' => 'html',
|
||||
'html' => $sHtml,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]['type'] != 'html')
|
||||
{
|
||||
throw new Exception("Cannot add HTML content to the tab '$sTabLabel' of type '{$this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]['type']}'");
|
||||
}
|
||||
// Append to the content of the tab
|
||||
$this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]['html'] .= $sHtml;
|
||||
}
|
||||
return ''; // Nothing to add to the page for now
|
||||
}
|
||||
|
||||
public function SetCurrentTabContainer($sTabContainer = '')
|
||||
{
|
||||
$sPreviousTabContainer = $this->m_sCurrentTabContainer;
|
||||
$this->m_sCurrentTabContainer = $sTabContainer;
|
||||
return $sPreviousTabContainer;
|
||||
}
|
||||
|
||||
public function SetCurrentTab($sTabLabel = '')
|
||||
{
|
||||
$sPreviousTab = $this->m_sCurrentTab;
|
||||
$this->m_sCurrentTab = $sTabLabel;
|
||||
return $sPreviousTab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a tab which content will be loaded asynchronously via the supplied URL
|
||||
*
|
||||
* Limitations:
|
||||
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to pull content from another server.
|
||||
* Static content cannot be added inside such tabs.
|
||||
*
|
||||
* @param string $sTabLabel The (localised) label of the tab
|
||||
* @param string $sUrl The URL to load (on the same server)
|
||||
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause the tab to be reloaded upon each activation.
|
||||
* @since 2.0.3
|
||||
*/
|
||||
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true)
|
||||
{
|
||||
// Set the content of the tab
|
||||
$this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$sTabLabel] = array(
|
||||
'type' => 'ajax',
|
||||
'url' => $sUrl,
|
||||
'cache' => $bCache,
|
||||
);
|
||||
return ''; // Nothing to add to the page for now
|
||||
}
|
||||
|
||||
|
||||
public function GetCurrentTabContainer()
|
||||
{
|
||||
return $this->m_sCurrentTabContainer;
|
||||
}
|
||||
|
||||
public function GetCurrentTab()
|
||||
{
|
||||
return $this->m_sCurrentTab;
|
||||
}
|
||||
|
||||
public function RemoveTab($sTabLabel, $sTabContainer = null)
|
||||
{
|
||||
if ($sTabContainer == null)
|
||||
{
|
||||
$sTabContainer = $this->m_sCurrentTabContainer;
|
||||
}
|
||||
if (isset($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]))
|
||||
{
|
||||
// Delete the content of the tab
|
||||
unset($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]);
|
||||
|
||||
// If we just removed the active tab, let's reset the active tab
|
||||
if (($this->m_sCurrentTabContainer == $sTabContainer) && ($this->m_sCurrentTab == $sTabLabel))
|
||||
{
|
||||
$this->m_sCurrentTab = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the tab whose title matches a given pattern
|
||||
* @return mixed The name of the tab as a string or false if not found
|
||||
*/
|
||||
public function FindTab($sPattern, $sTabContainer = null)
|
||||
{
|
||||
$return = false;
|
||||
if ($sTabContainer == null)
|
||||
{
|
||||
$sTabContainer = $this->m_sCurrentTabContainer;
|
||||
}
|
||||
foreach($this->m_aTabs[$sTabContainer]['tabs'] as $sTabLabel => $void)
|
||||
{
|
||||
if (preg_match($sPattern, $sTabLabel))
|
||||
{
|
||||
$result = $sTabLabel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the given tab the active one, as if it were clicked
|
||||
* DOES NOT WORK: apparently in the *old* version of jquery
|
||||
* that we are using this is not supported... TO DO upgrade
|
||||
* the whole jquery bundle...
|
||||
*/
|
||||
public function SelectTab($sTabContainer, $sTabLabel)
|
||||
{
|
||||
$container_index = 0;
|
||||
$tab_index = 0;
|
||||
foreach($this->m_aTabs as $sCurrentTabContainerName => $aTabs)
|
||||
{
|
||||
if ($sTabContainer == $sCurrentTabContainerName)
|
||||
{
|
||||
foreach($aTabs['tabs'] as $sCurrentTabLabel => $void)
|
||||
{
|
||||
if ($sCurrentTabLabel == $sTabLabel)
|
||||
{
|
||||
break;
|
||||
}
|
||||
$tab_index++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
$container_index++;
|
||||
}
|
||||
$sSelector = '#tabbedContent_'.$container_index.' > ul';
|
||||
return "window.setTimeout(\"$('$sSelector').tabs('select', $tab_index);\", 100);"; // Let the time to the tabs widget to initialize
|
||||
}
|
||||
|
||||
public function RenderIntoContent($sContent)
|
||||
{
|
||||
// Render the tabs in the page (if any)
|
||||
foreach($this->m_aTabs as $sTabContainerName => $aTabs)
|
||||
{
|
||||
$sTabs = '';
|
||||
$sPrefix = $aTabs['prefix'];
|
||||
$container_index = 0;
|
||||
if (count($aTabs['tabs']) > 0)
|
||||
{
|
||||
$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$sPrefix}{$container_index}\" class=\"light\">\n";
|
||||
$sTabs .= "<ul>\n";
|
||||
// Display the unordered list that will be rendered as the tabs
|
||||
$i = 0;
|
||||
foreach($aTabs['tabs'] as $sTabName => $aTabData)
|
||||
{
|
||||
switch($aTabData['type'])
|
||||
{
|
||||
case 'ajax':
|
||||
$sTabs .= "<li data-cache=\"".($aTabData['cache'] ? 'true' : 'false')."\"><a href=\"{$aTabData['url']}\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
|
||||
break;
|
||||
|
||||
case 'html':
|
||||
default:
|
||||
$sTabs .= "<li><a href=\"#tab_{$sPrefix}{$container_index}$i\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</ul>\n";
|
||||
// Now add the content of the tabs themselves
|
||||
$i = 0;
|
||||
foreach($aTabs['tabs'] as $sTabName => $aTabData)
|
||||
{
|
||||
switch($aTabData['type'])
|
||||
{
|
||||
case 'ajax':
|
||||
// Nothing to add
|
||||
break;
|
||||
|
||||
case 'html':
|
||||
default:
|
||||
$sTabs .= "<div id=\"tab_{$sPrefix}{$container_index}$i\">".$aTabData['html']."</div>\n";
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
$sTabs .= "</div>\n<!-- end of tabs-->\n";
|
||||
}
|
||||
$sContent = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $sContent);
|
||||
$container_index++;
|
||||
}
|
||||
return $sContent;
|
||||
}
|
||||
}
|
||||
@@ -34,27 +34,27 @@ class ExecAsyncTask implements iBackgroundProcess
|
||||
|
||||
public function Process($iTimeLimit)
|
||||
{
|
||||
$sOQL = "SELECT AsyncTask WHERE ISNULL(started) AND (ISNULL(planned) OR (planned < NOW()))";
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array());
|
||||
$sNow = date('Y-m-d H:i:s');
|
||||
// Criteria: planned, and expected to occur... ASAP or in the past
|
||||
$sOQL = "SELECT AsyncTask WHERE (status = 'planned') AND (ISNULL(planned) OR (planned < '$sNow'))";
|
||||
$iProcessed = 0;
|
||||
while ((time() < $iTimeLimit) && ($oTask = $oSet->Fetch()))
|
||||
while (time() < $iTimeLimit)
|
||||
{
|
||||
$oTask->Set('started', time());
|
||||
$oTask->DBUpdate();
|
||||
|
||||
$oTask->Process();
|
||||
// Next one ?
|
||||
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array(), null, 1 /* limit count */);
|
||||
$oTask = $oSet->Fetch();
|
||||
if (is_null($oTask))
|
||||
{
|
||||
// Nothing to be done
|
||||
break;
|
||||
}
|
||||
$iProcessed++;
|
||||
|
||||
$oTask->DBDelete();
|
||||
}
|
||||
if ($iProcessed == $oSet->Count())
|
||||
{
|
||||
return "processed $iProcessed tasks";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "processed $iProcessed tasks (remaining: ".($oSet->Count() - $iProcessed).")";
|
||||
if ($oTask->Process())
|
||||
{
|
||||
$oTask->DBDelete();
|
||||
}
|
||||
}
|
||||
return "processed $iProcessed tasks";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,36 +80,141 @@ abstract class AsyncTask extends DBObject
|
||||
"display_template" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
// MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Null is allowed to ease the migration from iTop 2.0.2 and earlier, when the status did not exist, and because the default value is not taken into account in the SQL definition
|
||||
// The value is set from null to planned in the setup program
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('planned,running,idle,error'), "sql"=>"status", "default_value"=>"planned", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("started", array("allowed_values"=>null, "sql"=>"started", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
// planned... still not used - reserved for timer management
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("planned", array("allowed_values"=>null, "sql"=>"planned", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("event_id", array("targetclass"=>"Event", "jointype"=> "", "allowed_values"=>null, "sql"=>"event_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
// MetaModel::Init_SetZListItems('details', array()); // Attributes to be displayed for the complete details
|
||||
// MetaModel::Init_SetZListItems('list', array()); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("remaining_retries", array("allowed_values"=>null, "sql"=>"remaining_retries", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Every is fine
|
||||
*/
|
||||
const OK = 0;
|
||||
/**
|
||||
* The task no longer exists
|
||||
*/
|
||||
const DELETED = 1;
|
||||
/**
|
||||
* The task is already being executed
|
||||
*/
|
||||
const ALREADY_RUNNING = 2;
|
||||
|
||||
/**
|
||||
* The current process requests the ownership on the task.
|
||||
* In case the task can be accessed concurrently, this function can be overloaded to add a critical section.
|
||||
* The function must not block the caller if another process is already owning the task
|
||||
*
|
||||
* @return integer A code among OK/DELETED/ALREADY_RUNNING.
|
||||
*/
|
||||
public function MarkAsRunning()
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->Set('status', 'running');
|
||||
$this->Set('started', time());
|
||||
$this->DBUpdate();
|
||||
return self::OK;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
// Corrupted task !! (for example: "Failed to reload object")
|
||||
IssueLog::Error('Failed to process async task #'.$this->GetKey().' - reason: '.$e->getMessage().' - fatal error, deleting the task.');
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', 'Failed, corrupted data: '.$e->getMessage());
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
$this->DBDelete();
|
||||
return self::DELETED;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetRetryDelay()
|
||||
{
|
||||
$iRetryDelay = 600;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries', array());
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
$iRetryDelay = $aConfig['retry_delay'];
|
||||
}
|
||||
return $iRetryDelay;
|
||||
}
|
||||
|
||||
public function GetMaxRetries()
|
||||
{
|
||||
$iMaxRetries = 0;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries', array());
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
$iMaxRetries = $aConfig['max_retries'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function OnInsert()
|
||||
{
|
||||
$this->Set('created', time());
|
||||
$this->Set('remaining_retries', $this->GetMaxRetries());
|
||||
}
|
||||
|
||||
public function Process()
|
||||
/**
|
||||
* @return boolean True if the task record can be deleted
|
||||
*/
|
||||
public function Process()
|
||||
{
|
||||
$sStatus = $this->DoProcess();
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', $sStatus);
|
||||
$oEventLog->DBUpdate();
|
||||
// By default: consider that the task is not completed
|
||||
$bRet = false;
|
||||
|
||||
// Attempt to take the ownership
|
||||
$iStatus = $this->MarkAsRunning();
|
||||
if ($iStatus == self::OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
$sStatus = $this->DoProcess();
|
||||
if ($this->Get('event_id') != 0)
|
||||
{
|
||||
$oEventLog = MetaModel::GetObject('Event', $this->Get('event_id'));
|
||||
$oEventLog->Set('message', $sStatus);
|
||||
$oEventLog->DBUpdate();
|
||||
}
|
||||
$bRet = true;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$iRemaining = $this->Get('remaining_retries');
|
||||
if ($iRemaining > 0)
|
||||
{
|
||||
$iRetryDelay = $this->GetRetryDelay();
|
||||
IssueLog::Info('Failed to process async task #'.$this->GetKey().' - reason: '.$e->getMessage().' - remaining retries: '.$iRemaining.' - next retry in '.$iRetryDelay.'s');
|
||||
|
||||
$this->Set('remaining_retries', $iRemaining - 1);
|
||||
$this->Set('status', 'planned');
|
||||
$this->Set('started', null);
|
||||
$this->Set('planned', time() + $iRetryDelay);
|
||||
$this->DBUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
IssueLog::Error('Failed to process async task #'.$this->GetKey().' - reason: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Already done or being handled by another process... skip...
|
||||
$bRet = false;
|
||||
}
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
abstract public function DoProcess();
|
||||
@@ -140,7 +245,7 @@ class AsyncSendEmail extends AsyncTask
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeInteger("version", array("allowed_values"=>null, "sql"=>"version", "default_value"=>Email::ORIGINAL_FORMAT, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLongText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
|
||||
@@ -621,7 +621,7 @@ class AttributeLinkedSet extends AttributeDefinition
|
||||
|
||||
public function GetTrackingLevel()
|
||||
{
|
||||
return $this->GetOptional('tracking_level', LINKSET_TRACKING_LIST);
|
||||
return $this->GetOptional('tracking_level', MetaModel::GetConfig()->Get('tracking_level_linked_set_default'));
|
||||
}
|
||||
|
||||
public function GetEditMode()
|
||||
@@ -919,7 +919,7 @@ class AttributeLinkedSetIndirect extends AttributeLinkedSet
|
||||
|
||||
public function GetTrackingLevel()
|
||||
{
|
||||
return $this->GetOptional('tracking_level', LINKSET_TRACKING_ALL);
|
||||
return $this->GetOptional('tracking_level', MetaModel::GetConfig()->Get('tracking_level_linked_set_indirect_default'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1293,6 +1293,14 @@ class AttributeBoolean extends AttributeInteger
|
||||
{
|
||||
return $sValue ? '1' : '0';
|
||||
}
|
||||
/**
|
||||
* Helper to get a value that will be JSON encoded
|
||||
* The operation is the opposite to FromJSONToValue
|
||||
*/
|
||||
public function GetForJSON($value)
|
||||
{
|
||||
return $value ? '1' : '0';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1915,7 +1923,12 @@ class AttributeCaseLog extends AttributeLongText
|
||||
// Facilitate things: allow the user to Set the value from a string
|
||||
public function MakeRealValue($proposedValue, $oHostObj)
|
||||
{
|
||||
if (!($proposedValue instanceof ormCaseLog))
|
||||
if ($proposedValue instanceof ormCaseLog)
|
||||
{
|
||||
// Passthrough
|
||||
$ret = $proposedValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append the new value if an instance of the object is supplied
|
||||
//
|
||||
@@ -1937,13 +1950,21 @@ class AttributeCaseLog extends AttributeLongText
|
||||
{
|
||||
$oCaseLog = new ormCaseLog();
|
||||
}
|
||||
if (strlen($proposedValue) > 0)
|
||||
|
||||
if ($proposedValue instanceof stdClass)
|
||||
{
|
||||
$oCaseLog->AddLogEntry(parent::MakeRealValue($proposedValue, $oHostObj));
|
||||
$oCaseLog->AddLogEntryFromJSON($proposedValue);
|
||||
}
|
||||
return $oCaseLog;
|
||||
else
|
||||
{
|
||||
if (strlen($proposedValue) > 0)
|
||||
{
|
||||
$oCaseLog->AddLogEntry(parent::MakeRealValue($proposedValue, $oHostObj));
|
||||
}
|
||||
}
|
||||
$ret = $oCaseLog;
|
||||
}
|
||||
return $proposedValue;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function GetSQLExpressions($sPrefix = '')
|
||||
@@ -2061,6 +2082,45 @@ class AttributeCaseLog extends AttributeLongText
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get a value that will be JSON encoded
|
||||
* The operation is the opposite to FromJSONToValue
|
||||
*/
|
||||
public function GetForJSON($value)
|
||||
{
|
||||
return $value->GetForJSON();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to form a value, given JSON decoded data
|
||||
* The operation is the opposite to GetForJSON
|
||||
*/
|
||||
public function FromJSONToValue($json)
|
||||
{
|
||||
if (is_string($json))
|
||||
{
|
||||
// Will be correctly handled in MakeRealValue
|
||||
$ret = $json;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($json->add_item))
|
||||
{
|
||||
// Will be correctly handled in MakeRealValue
|
||||
$ret = $json->add_item;
|
||||
if (!isset($ret->message))
|
||||
{
|
||||
throw new Exception("Missing mandatory entry: 'message'");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = ormCaseLog::FromJSON($json);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2087,8 +2147,7 @@ class AttributeEmailAddress extends AttributeString
|
||||
{
|
||||
public function GetValidationPattern()
|
||||
{
|
||||
// return "^([0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$";
|
||||
return "^[a-zA-Z0-9._&-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,}$";
|
||||
return $this->GetOptional('validation_pattern', '^'.utils::GetConfig()->Get('email_validation_pattern').'$');
|
||||
}
|
||||
|
||||
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
|
||||
@@ -2347,6 +2406,15 @@ class AttributeEnum extends AttributeString
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get a value that will be JSON encoded
|
||||
* The operation is the opposite to FromJSONToValue
|
||||
*/
|
||||
public function GetForJSON($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function GetAllowedValues($aArgs = array(), $sContains = '')
|
||||
{
|
||||
$aRawValues = parent::GetAllowedValues($aArgs, $sContains);
|
||||
@@ -3185,6 +3253,12 @@ class AttributeExternalField extends AttributeDefinition
|
||||
throw new CoreException("Unexpected value for argument iType: '$iType'");
|
||||
}
|
||||
}
|
||||
|
||||
public function GetPrerequisiteAttributes()
|
||||
{
|
||||
return array($this->Get("extkey_attcode"));
|
||||
}
|
||||
|
||||
|
||||
public function GetExtAttDef()
|
||||
{
|
||||
|
||||
@@ -260,6 +260,7 @@ class BulkChange
|
||||
protected $m_aOnDisappear; // array of attcode => value, values to be set when an object gets out of scope (ignored if no scope has been defined)
|
||||
protected $m_sDateFormat; // Date format specification, see utils::StringToTime()
|
||||
protected $m_bLocalizedValues; // Values in the data set are localized (see AttributeEnum)
|
||||
protected $m_aExtKeysMappingCache; // Cache for resolving external keys based on the given search criterias
|
||||
|
||||
public function __construct($sClass, $aData, $aAttList, $aExtKeys, $aReconcilKeys, $sSynchroScope = null, $aOnDisappear = null, $sDateFormat = null, $bLocalize = false)
|
||||
{
|
||||
@@ -272,6 +273,7 @@ class BulkChange
|
||||
$this->m_aOnDisappear = $aOnDisappear;
|
||||
$this->m_sDateFormat = $sDateFormat;
|
||||
$this->m_bLocalizedValues = $bLocalize;
|
||||
$this->m_aExtKeysMappingCache = array();
|
||||
}
|
||||
|
||||
protected $m_bReportHtml = false;
|
||||
@@ -365,6 +367,7 @@ class BulkChange
|
||||
else
|
||||
{
|
||||
$oReconFilter = new CMDBSearchFilter($oExtKey->GetTargetClass());
|
||||
$aCacheKeys = array();
|
||||
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
|
||||
{
|
||||
// The foreign attribute is one of our reconciliation key
|
||||
@@ -377,24 +380,60 @@ class BulkChange
|
||||
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sForeignAttCode);
|
||||
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
|
||||
}
|
||||
$aCacheKeys[] = $value;
|
||||
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
|
||||
$aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]);
|
||||
}
|
||||
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
||||
switch($oExtObjects->Count())
|
||||
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
|
||||
$iCount = 0;
|
||||
$iForeignKey = null;
|
||||
$sOQL = '';
|
||||
// TODO: check if *too long* keys can lead to collisions... and skip the cache in such a case...
|
||||
if (!array_key_exists($sAttCode, $this->m_aExtKeysMappingCache))
|
||||
{
|
||||
case 0:
|
||||
$this->m_aExtKeysMappingCache[$sAttCode] = array();
|
||||
}
|
||||
if (array_key_exists($sCacheKey, $this->m_aExtKeysMappingCache[$sAttCode]))
|
||||
{
|
||||
// Cache hit
|
||||
$iCount = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['c'];
|
||||
$iForeignKey = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['k'];
|
||||
$sOQL = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['oql'];
|
||||
// Record the hit
|
||||
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['h']++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cache miss, let's initialize it
|
||||
$oExtObjects = new CMDBObjectSet($oReconFilter);
|
||||
$iCount = $oExtObjects->Count();
|
||||
if ($iCount == 1)
|
||||
{
|
||||
$oForeignObj = $oExtObjects->Fetch();
|
||||
$iForeignKey = $oForeignObj->GetKey();
|
||||
}
|
||||
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
|
||||
'c' => $iCount,
|
||||
'k' => $iForeignKey,
|
||||
'oql' => $oReconFilter->ToOql(),
|
||||
'h' => 0, // number of hits on this cache entry
|
||||
);
|
||||
}
|
||||
switch($iCount)
|
||||
{
|
||||
case 0:
|
||||
$aErrors[$sAttCode] = Dict::S('UI:CSVReport-Value-Issue-NotFound');
|
||||
$aResults[$sAttCode]= new CellStatus_SearchIssue();
|
||||
break;
|
||||
case 1:
|
||||
|
||||
case 1:
|
||||
// Do change the external key attribute
|
||||
$oForeignObj = $oExtObjects->Fetch();
|
||||
$oTargetObj->Set($sAttCode, $oForeignObj->GetKey());
|
||||
$oTargetObj->Set($sAttCode, $iForeignKey);
|
||||
break;
|
||||
default:
|
||||
|
||||
default:
|
||||
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-FoundMany', $oExtObjects->Count());
|
||||
$aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $oExtObjects->Count(), $oReconFilter->ToOql());
|
||||
$aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $iCount, $sOQL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,9 +828,10 @@ class BulkChange
|
||||
$aVisited = array();
|
||||
}
|
||||
$iPreviousTimeLimit = ini_get('max_execution_time');
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
foreach($this->m_aData as $iRow => $aRowData)
|
||||
{
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
if (isset($aResult[$iRow]["__STATUS__"]))
|
||||
{
|
||||
// An issue at the earlier steps - skip the rest
|
||||
@@ -910,7 +950,7 @@ class BulkChange
|
||||
$iObj = $oObj->GetKey();
|
||||
if (!in_array($iObj, $aVisited))
|
||||
{
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$iRow++;
|
||||
$this->UpdateMissingObject($aResult, $iRow, $oObj, $oChange);
|
||||
}
|
||||
@@ -960,17 +1000,17 @@ class BulkChange
|
||||
$oPage->add('<div id="'.$sAjaxDivId.'">');
|
||||
}
|
||||
|
||||
$oPage->p(Dict::S('UI:History:BulkImports+'));
|
||||
$oPage->p(Dict::S('UI:History:BulkImports+').' <span id="csv_history_reload"></span>');
|
||||
|
||||
$oBulkChangeSearch = DBObjectSearch::FromOQL("SELECT CMDBChange WHERE userinfo LIKE '%(CSV)'");
|
||||
$oBulkChangeSearch = DBObjectSearch::FromOQL("SELECT CMDBChange WHERE origin IN ('csv-interactive', 'csv-import.php')");
|
||||
|
||||
$iQueryLimit = $bShowAll ? 0 : MetaModel::GetConfig()->GetMaxDisplayLimit() + 1;
|
||||
$iQueryLimit = $bShowAll ? 0 : appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
|
||||
$oBulkChanges = new DBObjectSet($oBulkChangeSearch, array('date' => false), array(), null, $iQueryLimit);
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
$bLimitExceeded = false;
|
||||
if ($oBulkChanges->Count() > MetaModel::GetConfig()->GetMaxDisplayLimit())
|
||||
if ($oBulkChanges->Count() > (appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit())))
|
||||
{
|
||||
$bLimitExceeded = true;
|
||||
if (!$bShowAll)
|
||||
@@ -1028,7 +1068,6 @@ class BulkChange
|
||||
{
|
||||
$aDetails[] = array('date' => $sDate, 'user' => $sUser, 'class' => $sClass, 'created' => $iCreated, 'modified' => $iModified);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$aConfig = array( 'date' => array('label' => Dict::S('UI:History:Date'), 'description' => Dict::S('UI:History:Date+')),
|
||||
@@ -1048,7 +1087,7 @@ class BulkChange
|
||||
else
|
||||
{
|
||||
// Truncated list
|
||||
$iMinDisplayLimit = MetaModel::GetConfig()->GetMinDisplayLimit();
|
||||
$iMinDisplayLimit = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
|
||||
$sCollapsedLabel = Dict::Format('UI:TruncatedResults', $iMinDisplayLimit, $oBulkChanges->Count());
|
||||
$sLinkLabel = Dict::S('UI:DisplayAll');
|
||||
$oPage->add('<p>'.$sCollapsedLabel.' <a class="truncated" onclick="OnTruncatedHistoryToggle(true);">'.$sLinkLabel.'</p>');
|
||||
@@ -1066,6 +1105,7 @@ EOF
|
||||
<<<EOF
|
||||
function OnTruncatedHistoryToggle(bShowAll)
|
||||
{
|
||||
$('#csv_history_reload').html('<img src="../images/indicator.gif"/>');
|
||||
$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sAppContext}', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
|
||||
{
|
||||
$('#$sAjaxDivId').html(data);
|
||||
|
||||
@@ -44,11 +44,15 @@ class CMDBChange extends DBObject
|
||||
"db_table" => "priv_change",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
'indexes' => array(
|
||||
array('origin'),
|
||||
)
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("origin", array("allowed_values"=>new ValueSetEnum('interactive,csv-interactive,csv-import.php,webservice-soap,webservice-rest,synchro-data-source,email-processing,custom-extension'), "sql"=>"origin", "default_value"=>"interactive", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
}
|
||||
|
||||
// Helper to keep track of the author of a given change,
|
||||
|
||||
@@ -93,7 +93,8 @@ abstract class CMDBObject extends DBObject
|
||||
// Note: this value is static, but that could be changed because it is sometimes a real issue (see update of interfaces / connected_to
|
||||
protected static $m_oCurrChange = null;
|
||||
protected static $m_sInfo = null; // null => the information is built in a standard way
|
||||
|
||||
protected static $m_sOrigin = null; // null => the origin is 'interactive'
|
||||
|
||||
/**
|
||||
* Specify another change (this is mainly for backward compatibility)
|
||||
*/
|
||||
@@ -134,6 +135,15 @@ abstract class CMDBObject extends DBObject
|
||||
self::$m_sInfo = $sInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides information about the origin of the change
|
||||
* @param $sOrigin String: one of: interactive, csv-interactive, csv-import.php, webservice-soap, webservice-rest, syncho-data-source, email-processing, custom-extension
|
||||
*/
|
||||
public static function SetTrackOrigin($sOrigin)
|
||||
{
|
||||
self::$m_sOrigin = $sOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the additional information (defaulting to user name)
|
||||
*/
|
||||
@@ -148,7 +158,22 @@ abstract class CMDBObject extends DBObject
|
||||
return self::$m_sInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the 'origin' information (defaulting to 'interactive')
|
||||
*/
|
||||
protected static function GetTrackOrigin()
|
||||
{
|
||||
if (is_null(self::$m_sOrigin))
|
||||
{
|
||||
return 'interactive';
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_sOrigin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a standard change record (done here 99% of the time, and nearly once per page)
|
||||
*/
|
||||
@@ -157,11 +182,27 @@ abstract class CMDBObject extends DBObject
|
||||
self::$m_oCurrChange = MetaModel::NewObject("CMDBChange");
|
||||
self::$m_oCurrChange->Set("date", time());
|
||||
self::$m_oCurrChange->Set("userinfo", self::GetTrackInfo());
|
||||
self::$m_oCurrChange->Set("origin", self::GetTrackOrigin());
|
||||
self::$m_oCurrChange->DBInsert();
|
||||
}
|
||||
|
||||
protected function RecordObjCreation()
|
||||
{
|
||||
// Delete any existing change tracking about the current object (IDs can be reused due to InnoDb bug; see TRAC #886)
|
||||
//
|
||||
// 1 - remove the deletion record(s)
|
||||
// Note that objclass contain the ROOT class
|
||||
$oFilter = new DBObjectSearch('CMDBChangeOpDelete');
|
||||
$oFilter->AddCondition('objclass', MetaModel::GetRootClass(get_class($this)), '=');
|
||||
$oFilter->AddCondition('objkey', $this->GetKey(), '=');
|
||||
MetaModel::PurgeData($oFilter);
|
||||
// 2 - any other change tracking information left prior to 2.0.3 (when the purge of the history has been implemented in RecordObjDeletion
|
||||
// In that case, objclass is the final class of the object
|
||||
$oFilter = new DBObjectSearch('CMDBChangeOp');
|
||||
$oFilter->AddCondition('objclass', get_class($this), '=');
|
||||
$oFilter->AddCondition('objkey', $this->GetKey(), '=');
|
||||
MetaModel::PurgeData($oFilter);
|
||||
|
||||
parent::RecordObjCreation();
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpCreate");
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
@@ -171,6 +212,14 @@ abstract class CMDBObject extends DBObject
|
||||
|
||||
protected function RecordObjDeletion($objkey)
|
||||
{
|
||||
$sRootClass = MetaModel::GetRootClass(get_class($this));
|
||||
|
||||
// Delete any existing change tracking about the current object
|
||||
$oFilter = new DBObjectSearch('CMDBChangeOp');
|
||||
$oFilter->AddCondition('objclass', get_class($this), '=');
|
||||
$oFilter->AddCondition('objkey', $objkey, '=');
|
||||
MetaModel::PurgeData($oFilter);
|
||||
|
||||
parent::RecordObjDeletion($objkey);
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpDelete");
|
||||
$oMyChangeOp->Set("objclass", MetaModel::GetRootClass(get_class($this)));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2013 Combodo SARL
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -29,10 +29,18 @@ require_once(APPROOT.'core/kpi.class.inc.php');
|
||||
|
||||
class MySQLException extends CoreException
|
||||
{
|
||||
public function __construct($sIssue, $aContext)
|
||||
public function __construct($sIssue, $aContext, $oException = null)
|
||||
{
|
||||
$aContext['mysql_error'] = CMDBSource::GetError();
|
||||
$aContext['mysql_errno'] = CMDBSource::GetErrNo();;
|
||||
if ($oException != null)
|
||||
{
|
||||
$aContext['mysql_error'] = $oException->getCode();
|
||||
$aContext['mysql_errno'] = $oException->getMessage();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aContext['mysql_error'] = CMDBSource::GetError();
|
||||
$aContext['mysql_errno'] = CMDBSource::GetErrNo();
|
||||
}
|
||||
parent::__construct($sIssue, $aContext);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +58,7 @@ class CMDBSource
|
||||
protected static $m_sDBUser;
|
||||
protected static $m_sDBPwd;
|
||||
protected static $m_sDBName;
|
||||
protected static $m_resDBLink;
|
||||
protected static $m_oMysqli;
|
||||
|
||||
public static function Init($sServer, $sUser, $sPwd, $sSource = '')
|
||||
{
|
||||
@@ -58,29 +66,41 @@ class CMDBSource
|
||||
self::$m_sDBUser = $sUser;
|
||||
self::$m_sDBPwd = $sPwd;
|
||||
self::$m_sDBName = $sSource;
|
||||
self::$m_oMysqli = null;
|
||||
|
||||
$aConnectInfo = explode(':', self::$m_sDBHost);
|
||||
if (count($aConnectInfo) > 1)
|
||||
mysqli_report(MYSQLI_REPORT_STRICT); // *some* errors (like connection errors) will throw mysqli_sql_exception instead
|
||||
// of generating warnings printed to the output but some other errors will still
|
||||
// cause the query() method to return false !!!
|
||||
try
|
||||
{
|
||||
// Override the default port
|
||||
$sServer = $aConnectInfo[0];
|
||||
$iPort = $aConnectInfo[1];
|
||||
self::$m_resDBLink = @mysqli_connect($sServer, self::$m_sDBUser, self::$m_sDBPwd, '', $iPort);
|
||||
$aConnectInfo = explode(':', self::$m_sDBHost);
|
||||
if (count($aConnectInfo) > 1)
|
||||
{
|
||||
// Override the default port
|
||||
$sServer = $aConnectInfo[0];
|
||||
$iPort = (int)$aConnectInfo[1];
|
||||
self::$m_oMysqli = new mysqli(self::$m_sDBHost, self::$m_sDBUser, self::$m_sDBPwd, '', $iPort);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$m_oMysqli = new mysqli(self::$m_sDBHost, self::$m_sDBUser, self::$m_sDBPwd);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
self::$m_resDBLink = @mysqli_connect(self::$m_sDBHost, self::$m_sDBUser, self::$m_sDBPwd);
|
||||
throw new MySQLException('Could not connect to the DB server', array('host'=>self::$m_sDBHost, 'user'=>self::$m_sDBUser), $e);
|
||||
}
|
||||
|
||||
if (!self::$m_resDBLink)
|
||||
{
|
||||
throw new MySQLException('Could not connect to the DB server', array('host'=>self::$m_sDBHost, 'user'=>self::$m_sDBUser));
|
||||
}
|
||||
if (!empty($sSource))
|
||||
{
|
||||
if (!((bool)mysqli_query(self::$m_resDBLink, "USE `$sSource`")))
|
||||
try
|
||||
{
|
||||
throw new MySQLException('Could not select DB', array('host'=>self::$m_sDBHost, 'user'=>self::$m_sDBUser, 'db_name'=>self::$m_sDBName));
|
||||
mysqli_report(MYSQLI_REPORT_STRICT); // Errors, in the next query, will throw mysqli_sql_exception
|
||||
self::$m_oMysqli->query("USE `$sSource`");
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
throw new MySQLException('Could not select DB', array('host'=>self::$m_sDBHost, 'user'=>self::$m_sDBUser, 'db_name'=>self::$m_sDBName), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +154,7 @@ class CMDBSource
|
||||
{
|
||||
// In case we don't have rights to enumerate the databases
|
||||
// Let's try to connect directly
|
||||
return @((bool)mysqli_query(self::$m_resDBLink, "USE `$sSource`"));
|
||||
return @((bool)self::$m_oMysqli->query("USE `$sSource`"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -147,7 +167,7 @@ class CMDBSource
|
||||
|
||||
public static function SelectDB($sSource)
|
||||
{
|
||||
if (!((bool)mysqli_query(self::$m_resDBLink, "USE `$sSource`")))
|
||||
if (!((bool)self::$m_oMysqli->query("USE `$sSource`")))
|
||||
{
|
||||
throw new MySQLException('Could not select DB', array('db_name'=>$sSource));
|
||||
}
|
||||
@@ -189,25 +209,25 @@ class CMDBSource
|
||||
|
||||
public static function GetErrNo()
|
||||
{
|
||||
if (self::$m_resDBLink)
|
||||
if (self::$m_oMysqli->errno != 0)
|
||||
{
|
||||
return mysqli_errno(self::$m_resDBLink);
|
||||
return self::$m_oMysqli->errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysqli_connect_errno();
|
||||
return self::$m_oMysqli->connect_errno;
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetError()
|
||||
{
|
||||
if (self::$m_resDBLink)
|
||||
if (self::$m_oMysqli->error != '')
|
||||
{
|
||||
return mysqli_error(self::$m_resDBLink);
|
||||
return self::$m_oMysqli->error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mysqli_connect_error();
|
||||
return self::$m_oMysqli->connect_error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +268,7 @@ class CMDBSource
|
||||
// Quote if not a number or a numeric string
|
||||
if ($bAlways || is_string($value))
|
||||
{
|
||||
$value = $cQuoteStyle . mysqli_real_escape_string(self::$m_resDBLink, $value) . $cQuoteStyle;
|
||||
$value = $cQuoteStyle . self::$m_oMysqli->real_escape_string($value) . $cQuoteStyle;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
@@ -256,28 +276,35 @@ class CMDBSource
|
||||
public static function Query($sSQLQuery)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$result = mysqli_query(self::$m_resDBLink, $sSQLQuery);
|
||||
if (!$result)
|
||||
try
|
||||
{
|
||||
$oResult = self::$m_oMysqli->query($sSQLQuery);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSQLQuery, $e));
|
||||
}
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSQLQuery);
|
||||
if ($oResult === false)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSQLQuery));
|
||||
}
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSQLQuery);
|
||||
|
||||
return $result;
|
||||
return $oResult;
|
||||
}
|
||||
|
||||
public static function GetNextInsertId($sTable)
|
||||
{
|
||||
$sSQL = "SHOW TABLE STATUS LIKE '$sTable'";
|
||||
$result = self::Query($sSQL);
|
||||
$aRow = mysqli_fetch_assoc($result);
|
||||
$oResult = self::Query($sSQL);
|
||||
$aRow = $oResult->fetch_assoc();
|
||||
$iNextInsertId = $aRow['Auto_increment'];
|
||||
return $iNextInsertId;
|
||||
}
|
||||
|
||||
public static function GetInsertId()
|
||||
{
|
||||
$iRes = mysqli_insert_id(self::$m_resDBLink);
|
||||
$iRes = self::$m_oMysqli->insert_id;
|
||||
if (is_null($iRes))
|
||||
{
|
||||
return 0;
|
||||
@@ -302,22 +329,31 @@ class CMDBSource
|
||||
public static function QueryToScalar($sSql)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$result = mysqli_query(self::$m_resDBLink, $sSql);
|
||||
try
|
||||
{
|
||||
$oResult = self::$m_oMysqli->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||
}
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
if (!$result)
|
||||
if ($oResult === false)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
if ($aRow = mysqli_fetch_array($result, MYSQLI_BOTH))
|
||||
|
||||
if ($aRow = $oResult->fetch_array(MYSQLI_BOTH))
|
||||
{
|
||||
$res = $aRow[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
mysqli_free_result($result);
|
||||
$oResult->free();
|
||||
throw new MySQLException('Found no result for query', array('query' => $sSql));
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
$oResult->free();
|
||||
return $res;
|
||||
}
|
||||
|
||||
@@ -325,17 +361,26 @@ class CMDBSource
|
||||
{
|
||||
$aData = array();
|
||||
$oKPI = new ExecutionKPI();
|
||||
$result = mysqli_query(self::$m_resDBLink, $sSql);
|
||||
try
|
||||
{
|
||||
$oResult = self::$m_oMysqli->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||
}
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
if (!$result)
|
||||
if ($oResult === false)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
while ($aRow = mysqli_fetch_array($result, MYSQLI_BOTH))
|
||||
|
||||
while ($aRow = $oResult->fetch_array(MYSQLI_BOTH))
|
||||
{
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
$oResult->free();
|
||||
return $aData;
|
||||
}
|
||||
|
||||
@@ -353,56 +398,73 @@ class CMDBSource
|
||||
public static function ExplainQuery($sSql)
|
||||
{
|
||||
$aData = array();
|
||||
$result = mysqli_query(self::$m_resDBLink, "EXPLAIN $sSql");
|
||||
if (!$result)
|
||||
try
|
||||
{
|
||||
$oResult = self::$m_oMysqli->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||
}
|
||||
if ($oResult === false)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
|
||||
$aNames = self::GetColumns($result);
|
||||
|
||||
$aNames = self::GetColumns($oResult);
|
||||
|
||||
$aData[] = $aNames;
|
||||
while ($aRow = mysqli_fetch_array($result, MYSQLI_ASSOC))
|
||||
while ($aRow = $oResult->fetch_array(MYSQLI_ASSOC))
|
||||
{
|
||||
$aData[] = $aRow;
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
$oResult->free();
|
||||
return $aData;
|
||||
}
|
||||
|
||||
public static function TestQuery($sSql)
|
||||
{
|
||||
$result = mysqli_query(self::$m_resDBLink, "EXPLAIN $sSql");
|
||||
if (!$result)
|
||||
try
|
||||
{
|
||||
return self::GetError();
|
||||
$oResult = self::$m_oMysqli->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||
}
|
||||
if ($oResult === false)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
|
||||
mysqli_free_result($result);
|
||||
if (is_object($oResult))
|
||||
{
|
||||
$oResult->free();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function NbRows($result)
|
||||
public static function NbRows($oResult)
|
||||
{
|
||||
return mysqli_num_rows($result);
|
||||
return $oResult->num_rows;
|
||||
}
|
||||
|
||||
public static function AffectedRows()
|
||||
{
|
||||
return mysqli_affected_rows(self::$m_resDBLink);
|
||||
return self::$m_oMysqli->affected_rows;
|
||||
}
|
||||
|
||||
public static function FetchArray($result)
|
||||
public static function FetchArray($oResult)
|
||||
{
|
||||
return mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||
return $oResult->fetch_array(MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
public static function GetColumns($result)
|
||||
public static function GetColumns($oResult)
|
||||
{
|
||||
$aNames = array();
|
||||
for ($i = 0; $i < (($___mysqli_tmp = mysqli_num_fields($result)) ? $___mysqli_tmp : 0) ; $i++)
|
||||
for ($i = 0; $i < (($___mysqli_tmp = $oResult->field_count) ? $___mysqli_tmp : 0) ; $i++)
|
||||
{
|
||||
$meta = mysqli_fetch_field_direct($result, $i);
|
||||
$meta = $oResult->fetch_field_direct($i);
|
||||
if (!$meta)
|
||||
{
|
||||
throw new MySQLException('mysql_fetch_field: No information available', array('query'=>$sSql, 'i'=>$i));
|
||||
@@ -415,14 +477,15 @@ class CMDBSource
|
||||
return $aNames;
|
||||
}
|
||||
|
||||
public static function Seek($result, $iRow)
|
||||
public static function Seek($oResult, $iRow)
|
||||
{
|
||||
return mysqli_data_seek($result, $iRow);
|
||||
return $oResult->data_seek($iRow);
|
||||
}
|
||||
|
||||
public static function FreeResult($result)
|
||||
public static function FreeResult($oResult)
|
||||
{
|
||||
return ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false);
|
||||
$oResult->free(); /* returns void */
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function IsTable($sTable)
|
||||
@@ -580,18 +643,25 @@ class CMDBSource
|
||||
public static function DumpTable($sTable)
|
||||
{
|
||||
$sSql = "SELECT * FROM `$sTable`";
|
||||
$result = mysqli_query(self::$m_resDBLink, $sSql);
|
||||
if (!$result)
|
||||
try
|
||||
{
|
||||
$oResult = self::$m_oMysqli->query($sSql);
|
||||
}
|
||||
catch(mysqli_sql_exception $e)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql), $e);
|
||||
}
|
||||
if ($oResult === false)
|
||||
{
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
|
||||
}
|
||||
|
||||
|
||||
$aRows = array();
|
||||
while ($aRow = mysqli_fetch_array($result, MYSQLI_ASSOC))
|
||||
while ($aRow = $oResult->fetch_array(MYSQLI_ASSOC))
|
||||
{
|
||||
$aRows[] = $aRow;
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
$oResult->free();
|
||||
return $aRows;
|
||||
}
|
||||
|
||||
@@ -621,7 +691,7 @@ class CMDBSource
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = self::Query('SHOW GRANTS'); // [ FOR CURRENT_USER()]
|
||||
$oResult = self::Query('SHOW GRANTS'); // [ FOR CURRENT_USER()]
|
||||
}
|
||||
catch(MySQLException $e)
|
||||
{
|
||||
@@ -629,12 +699,12 @@ class CMDBSource
|
||||
}
|
||||
|
||||
$aRes = array();
|
||||
while ($aRow = mysqli_fetch_array($result, MYSQLI_NUM))
|
||||
while ($aRow = $oResult->fetch_array(MYSQLI_NUM))
|
||||
{
|
||||
// so far, only one column...
|
||||
$aRes[] = implode('/', $aRow);
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
$oResult->free();
|
||||
// so far, only one line...
|
||||
return implode(', ', $aRes);
|
||||
}
|
||||
@@ -647,21 +717,21 @@ class CMDBSource
|
||||
{
|
||||
try
|
||||
{
|
||||
$result = self::Query('SHOW SLAVE STATUS');
|
||||
$oResult = self::Query('SHOW SLAVE STATUS');
|
||||
}
|
||||
catch(MySQLException $e)
|
||||
{
|
||||
throw new CoreException("Current user not allowed to check the status", array('mysql_error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
if (mysqli_num_rows($result) == 0)
|
||||
if ($oResult->num_rows == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns one single row anytime
|
||||
$aRow = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||
mysqli_free_result($result);
|
||||
$aRow = $oResult->fetch_array(MYSQLI_ASSOC);
|
||||
$oResult->free();
|
||||
|
||||
if (!isset($aRow['Slave_IO_Running']))
|
||||
{
|
||||
@@ -683,7 +753,4 @@ class CMDBSource
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
}
|
||||
@@ -35,6 +35,7 @@ define('ACCESS_READONLY', 0);
|
||||
*/
|
||||
|
||||
require_once('coreexception.class.inc.php');
|
||||
require_once('attributedef.class.inc.php'); // For the defines
|
||||
|
||||
class ConfigException extends CoreException
|
||||
{
|
||||
@@ -332,6 +333,14 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'async_task_retries' => array(
|
||||
'type' => 'array',
|
||||
'description' => 'Automatic retries of asynchronous tasks in case of failure (per class)',
|
||||
'default' => array('AsyncSendEmail' => array('max_retries' => 0, 'retry_delay' => 600)),
|
||||
'value' => false,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'email_asynchronous' => array(
|
||||
'type' => 'bool',
|
||||
'description' => 'If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode',
|
||||
@@ -540,6 +549,15 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'forgot_password_from' => array(
|
||||
'type' => 'string',
|
||||
'description' => 'Sender email address for the "forgot password" feature. If empty, defaults to the recipient\'s email address.',
|
||||
// examples... not used (nor 'description')
|
||||
'default' => '',
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'deadline_format' => array(
|
||||
'type' => 'string',
|
||||
'description' => 'The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$',
|
||||
@@ -624,14 +642,22 @@ class Config
|
||||
'url_validation_pattern' => array(
|
||||
'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' => '(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............................
|
||||
// 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
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
),
|
||||
'email_validation_pattern' => array(
|
||||
'type' => 'string',
|
||||
'description' => 'Regular expression to validate/detect the format of an eMail address',
|
||||
'default' => "[a-zA-Z0-9._&'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,}",
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
),
|
||||
'log_kpi_duration' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Level of logging for troubleshooting performance issues (1 to enable, 2 +blame callers)',
|
||||
@@ -684,6 +710,65 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
),
|
||||
'max_execution_time_per_loop' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Maximum execution time requested, per loop, during bulk operations. Zero means no limit.',
|
||||
// examples... not used
|
||||
'default' => 30,
|
||||
'value' => 30,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'max_history_length' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Maximum length of the history table (in the "History" tab on each object) before it gets truncated. Latest modifications are displayed first.',
|
||||
// examples... not used
|
||||
'default' => 50,
|
||||
'value' => 50,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'full_text_chunk_duration' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Delay after which the results are displayed.',
|
||||
// examples... not used
|
||||
'default' => 2,
|
||||
'value' => 2,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'full_text_accelerators' => array(
|
||||
'type' => 'array',
|
||||
'description' => 'Specifies classes to be searched at first (and the subset of data) when running the full text search.',
|
||||
'default' => array(),
|
||||
'value' => false,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'full_text_needle_min' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Minimum size of the full text needle.',
|
||||
'default' => 3,
|
||||
'value' => 3,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'tracking_level_linked_set_default' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)',
|
||||
'default' => LINKSET_TRACKING_LIST,
|
||||
'value' => LINKSET_TRACKING_LIST,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'tracking_level_linked_set_indirect_default' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSetIndirect',
|
||||
'default' => LINKSET_TRACKING_ALL,
|
||||
'value' => LINKSET_TRACKING_ALL,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
);
|
||||
|
||||
public function IsProperty($sPropCode)
|
||||
@@ -712,6 +797,8 @@ class Config
|
||||
case 'float':
|
||||
$value = (float) $value;
|
||||
break;
|
||||
case 'array':
|
||||
break;
|
||||
default:
|
||||
throw new CoreException('Unknown type for setting', array('property' => $sPropCode, 'type' => $sType));
|
||||
}
|
||||
@@ -968,7 +1055,14 @@ class Config
|
||||
{
|
||||
if ($this->IsProperty($sPropCode))
|
||||
{
|
||||
$value = trim($rawvalue);
|
||||
if (is_string($rawvalue))
|
||||
{
|
||||
$value = trim($rawvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $rawvalue;
|
||||
}
|
||||
$this->Set($sPropCode, $value, $sConfigFile);
|
||||
}
|
||||
}
|
||||
@@ -1711,14 +1805,14 @@ class Config
|
||||
/**
|
||||
* Pretty format a var_export'ed value so that (if possible) the identation is preserved on every line
|
||||
* @param mixed $value The value to export
|
||||
* @param string $sIdentation The string to use to indent the text
|
||||
* @param string $sIndentation The string to use to indent the text
|
||||
* @param bool $bForceIndentation Forces the identation (enven if it breaks/changes an eval, for example to ouput a value inside a comment)
|
||||
* @return string The indented export string
|
||||
*/
|
||||
protected static function PrettyVarExport($value, $sIdentation, $bForceIndentation = false)
|
||||
protected static function PrettyVarExport($value, $sIndentation, $bForceIndentation = false)
|
||||
{
|
||||
$sExport = var_export($value, true);
|
||||
$sNiceExport = trim(preg_replace("/^/m", "\t\t\t", $sExport));
|
||||
$sNiceExport = str_replace(array("\r\n", "\n", "\r"), "\n".$sIndentation, trim($sExport));
|
||||
if (!$bForceIndentation)
|
||||
{
|
||||
eval('$aImported='.$sNiceExport.';');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2013 Combodo SARL
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -16,6 +16,38 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* All objects to be displayed in the application (either as a list or as details)
|
||||
* must implement this interface.
|
||||
*/
|
||||
interface iDisplay
|
||||
{
|
||||
|
||||
/**
|
||||
* Maps the given context parameter name to the appropriate filter/search code for this class
|
||||
* @param string $sContextParam Name of the context parameter, i.e. 'org_id'
|
||||
* @return string Filter code, i.e. 'customer_id'
|
||||
*/
|
||||
public static function MapContextParam($sContextParam);
|
||||
/**
|
||||
* This function returns a 'hilight' CSS class, used to hilight a given row in a table
|
||||
* There are currently (i.e defined in the CSS) 4 possible values HILIGHT_CLASS_CRITICAL,
|
||||
* HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
|
||||
* To Be overridden by derived classes
|
||||
* @param void
|
||||
* @return String The desired higlight class for the object/row
|
||||
*/
|
||||
public function GetHilightClass();
|
||||
/**
|
||||
* Returns the relative path to the page that handles the display of the object
|
||||
* @return string
|
||||
*/
|
||||
public static function GetUIPage();
|
||||
/**
|
||||
* Displays the details of the object
|
||||
*/
|
||||
public function DisplayDetails(WebPage $oPage, $bEditMode = false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class dbObject: the root of persistent classes
|
||||
@@ -34,7 +66,7 @@ require_once('mutex.class.inc.php');
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class DBObject
|
||||
abstract class DBObject implements iDisplay
|
||||
{
|
||||
private static $m_aMemoryObjectsByClass = array();
|
||||
|
||||
@@ -61,6 +93,7 @@ abstract class DBObject
|
||||
|
||||
private $m_bFullyLoaded = false; // Compound objects can be partially loaded
|
||||
private $m_aLoadedAtt = array(); // Compound objects can be partially loaded, array of sAttCode
|
||||
protected $m_aModifiedAtt = array(); // list of (potentially) modified sAttCodes
|
||||
protected $m_oMasterReplicaSet = null; // Set of SynchroReplica related to this object
|
||||
|
||||
// Use the MetaModel::NewObject to build an object (do we have to force it?)
|
||||
@@ -70,6 +103,7 @@ abstract class DBObject
|
||||
{
|
||||
$this->FromRow($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
|
||||
$this->m_bFullyLoaded = $this->IsFullyLoaded();
|
||||
$this->m_aModifiedAtt = array();
|
||||
return;
|
||||
}
|
||||
// Creation of a brand new object
|
||||
@@ -194,6 +228,7 @@ abstract class DBObject
|
||||
}
|
||||
|
||||
$this->m_bFullyLoaded = true;
|
||||
$this->m_aModifiedAtt = array();
|
||||
}
|
||||
|
||||
protected function FromRow($aRow, $sClassAlias = '', $aAttToLoad = null, $aExtendedDataSpec = null)
|
||||
@@ -304,6 +339,7 @@ abstract class DBObject
|
||||
// Ignore it - this attribute is set upon object creation and that's it
|
||||
return;
|
||||
}
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
if ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty)
|
||||
{
|
||||
@@ -371,6 +407,7 @@ abstract class DBObject
|
||||
$realvalue = $oAttDef->MakeRealValue($value, $this);
|
||||
|
||||
$this->m_aCurrValues[$sAttCode] = $realvalue;
|
||||
$this->m_aModifiedAtt[$sAttCode] = true;
|
||||
|
||||
// The object has changed, reset caches
|
||||
$this->m_bCheckStatus = null;
|
||||
@@ -400,16 +437,25 @@ abstract class DBObject
|
||||
{
|
||||
throw new CoreException("Unknown external key '$sExtKeyAttCode' for the class ".get_class($this));
|
||||
}
|
||||
$oKeyAttDef = MetaModel::GetAttributeDef(get_class($this), $sExtKeyAttCode);
|
||||
$sRemoteClass = $oKeyAttDef->GetTargetClass();
|
||||
$oRemoteObj = MetaModel::GetObject($sRemoteClass, $this->GetStrict($sExtKeyAttCode), false);
|
||||
if (is_null($oRemoteObj))
|
||||
|
||||
$oExtFieldAtt = MetaModel::FindExternalField(get_class($this), $sExtKeyAttCode, $sRemoteAttCode);
|
||||
if (!is_null($oExtFieldAtt))
|
||||
{
|
||||
return '';
|
||||
return $this->GetStrict($oExtFieldAtt->GetCode());
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oRemoteObj->Get($sRemoteAttCode);
|
||||
$oKeyAttDef = MetaModel::GetAttributeDef(get_class($this), $sExtKeyAttCode);
|
||||
$sRemoteClass = $oKeyAttDef->GetTargetClass();
|
||||
$oRemoteObj = MetaModel::GetObject($sRemoteClass, $this->GetStrict($sExtKeyAttCode), false);
|
||||
if (is_null($oRemoteObj))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oRemoteObj->Get($sRemoteAttCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -864,7 +910,11 @@ abstract class DBObject
|
||||
}
|
||||
}
|
||||
$aReasons = array();
|
||||
$iSynchroFlags = $this->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
||||
$iSynchroFlags = 0;
|
||||
if ($this->InSyncScope())
|
||||
{
|
||||
$iSynchroFlags = $this->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
||||
}
|
||||
return $iFlags | $iSynchroFlags; // Combine both sets of flags
|
||||
}
|
||||
|
||||
@@ -1116,6 +1166,11 @@ abstract class DBObject
|
||||
// The value was not set
|
||||
$aDelta[$sAtt] = $proposedValue;
|
||||
}
|
||||
elseif(!array_key_exists($sAtt, $this->m_aModifiedAtt))
|
||||
{
|
||||
// This attCode was never set, canno tbe modified
|
||||
continue;
|
||||
}
|
||||
elseif(is_object($proposedValue))
|
||||
{
|
||||
$oLinkAttDef = MetaModel::GetAttributeDef(get_class($this), $sAtt);
|
||||
@@ -1597,142 +1652,161 @@ abstract class DBObject
|
||||
throw new CoreException("DBUpdate: could not update a newly created object, please call DBInsert instead");
|
||||
}
|
||||
|
||||
// Stop watches
|
||||
$sState = $this->GetState();
|
||||
if ($sState != '')
|
||||
// Protect against reentrance (e.g. cascading the update of ticket logs)
|
||||
static $aUpdateReentrance = array();
|
||||
$sKey = get_class($this).'::'.$this->GetKey();
|
||||
if (array_key_exists($sKey, $aUpdateReentrance))
|
||||
{
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode => $oAttDef)
|
||||
return;
|
||||
}
|
||||
$aUpdateReentrance[$sKey] = true;
|
||||
|
||||
try
|
||||
{
|
||||
// Stop watches
|
||||
$sState = $this->GetState();
|
||||
if ($sState != '')
|
||||
{
|
||||
if ($oAttDef instanceof AttributeStopWatch)
|
||||
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (in_array($sState, $oAttDef->GetStates()))
|
||||
if ($oAttDef instanceof AttributeStopWatch)
|
||||
{
|
||||
// Compute or recompute the deadlines
|
||||
$oSW = $this->Get($sAttCode);
|
||||
$oSW->ComputeDeadlines($this, $oAttDef);
|
||||
$this->Set($sAttCode, $oSW);
|
||||
if (in_array($sState, $oAttDef->GetStates()))
|
||||
{
|
||||
// Compute or recompute the deadlines
|
||||
$oSW = $this->Get($sAttCode);
|
||||
$oSW->ComputeDeadlines($this, $oAttDef);
|
||||
$this->Set($sAttCode, $oSW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->DoComputeValues();
|
||||
$this->OnUpdate();
|
||||
$this->DoComputeValues();
|
||||
$this->OnUpdate();
|
||||
|
||||
$aChanges = $this->ListChanges();
|
||||
if (count($aChanges) == 0)
|
||||
{
|
||||
// Attempting to update an unchanged object
|
||||
return;
|
||||
}
|
||||
|
||||
// Ultimate check - ensure DB integrity
|
||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
||||
if (!$bRes)
|
||||
{
|
||||
$sIssues = implode(', ', $aIssues);
|
||||
throw new CoreException("Object not following integrity rules", array('issues' => $sIssues, 'class' => get_class($this), 'id' => $this->GetKey()));
|
||||
}
|
||||
|
||||
// Save the original values (will be reset to the new values when the object get written to the DB)
|
||||
$aOriginalValues = $this->m_aOrigValues;
|
||||
|
||||
$bHasANewExternalKeyValue = false;
|
||||
$aHierarchicalKeys = array();
|
||||
foreach($aChanges as $sAttCode => $valuecurr)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
if ($oAttDef->IsExternalKey()) $bHasANewExternalKeyValue = true;
|
||||
if (!$oAttDef->IsDirectField()) unset($aChanges[$sAttCode]);
|
||||
if ($oAttDef->IsHierarchicalKey())
|
||||
$aChanges = $this->ListChanges();
|
||||
if (count($aChanges) == 0)
|
||||
{
|
||||
$aHierarchicalKeys[$sAttCode] = $oAttDef;
|
||||
// Attempting to update an unchanged object
|
||||
unset($aUpdateReentrance[$sKey]);
|
||||
return $this->m_iKey;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MetaModel::DBIsReadOnly())
|
||||
{
|
||||
// Update the left & right indexes for each hierarchical key
|
||||
foreach($aHierarchicalKeys as $sAttCode => $oAttDef)
|
||||
// Ultimate check - ensure DB integrity
|
||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
||||
if (!$bRes)
|
||||
{
|
||||
$sTable = $sTable = MetaModel::DBGetTable(get_class($this), $sAttCode);
|
||||
$sSQL = "SELECT `".$oAttDef->GetSQLRight()."` AS `right`, `".$oAttDef->GetSQLLeft()."` AS `left` FROM `$sTable` WHERE id=".$this->GetKey();
|
||||
$aRes = CMDBSource::QueryToArray($sSQL);
|
||||
$iMyLeft = $aRes[0]['left'];
|
||||
$iMyRight = $aRes[0]['right'];
|
||||
$iDelta =$iMyRight - $iMyLeft + 1;
|
||||
MetaModel::HKTemporaryCutBranch($iMyLeft, $iMyRight, $oAttDef, $sTable);
|
||||
|
||||
if ($aChanges[$sAttCode] == 0)
|
||||
$sIssues = implode(', ', $aIssues);
|
||||
throw new CoreException("Object not following integrity rules", array('issues' => $sIssues, 'class' => get_class($this), 'id' => $this->GetKey()));
|
||||
}
|
||||
|
||||
// Save the original values (will be reset to the new values when the object get written to the DB)
|
||||
$aOriginalValues = $this->m_aOrigValues;
|
||||
|
||||
$bHasANewExternalKeyValue = false;
|
||||
$aHierarchicalKeys = array();
|
||||
foreach($aChanges as $sAttCode => $valuecurr)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
if ($oAttDef->IsExternalKey()) $bHasANewExternalKeyValue = true;
|
||||
if (!$oAttDef->IsDirectField()) unset($aChanges[$sAttCode]);
|
||||
if ($oAttDef->IsHierarchicalKey())
|
||||
{
|
||||
// No new parent, insert completely at the right of the tree
|
||||
$sSQL = "SELECT max(`".$oAttDef->GetSQLRight()."`) AS max FROM `$sTable`";
|
||||
$aHierarchicalKeys[$sAttCode] = $oAttDef;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MetaModel::DBIsReadOnly())
|
||||
{
|
||||
// Update the left & right indexes for each hierarchical key
|
||||
foreach($aHierarchicalKeys as $sAttCode => $oAttDef)
|
||||
{
|
||||
$sTable = $sTable = MetaModel::DBGetTable(get_class($this), $sAttCode);
|
||||
$sSQL = "SELECT `".$oAttDef->GetSQLRight()."` AS `right`, `".$oAttDef->GetSQLLeft()."` AS `left` FROM `$sTable` WHERE id=".$this->GetKey();
|
||||
$aRes = CMDBSource::QueryToArray($sSQL);
|
||||
if (count($aRes) == 0)
|
||||
$iMyLeft = $aRes[0]['left'];
|
||||
$iMyRight = $aRes[0]['right'];
|
||||
$iDelta =$iMyRight - $iMyLeft + 1;
|
||||
MetaModel::HKTemporaryCutBranch($iMyLeft, $iMyRight, $oAttDef, $sTable);
|
||||
|
||||
if ($aChanges[$sAttCode] == 0)
|
||||
{
|
||||
$iNewLeft = 1;
|
||||
// No new parent, insert completely at the right of the tree
|
||||
$sSQL = "SELECT max(`".$oAttDef->GetSQLRight()."`) AS max FROM `$sTable`";
|
||||
$aRes = CMDBSource::QueryToArray($sSQL);
|
||||
if (count($aRes) == 0)
|
||||
{
|
||||
$iNewLeft = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iNewLeft = $aRes[0]['max']+1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iNewLeft = $aRes[0]['max']+1;
|
||||
// Insert at the right of the specified parent
|
||||
$sSQL = "SELECT `".$oAttDef->GetSQLRight()."` FROM `$sTable` WHERE id=".((int)$aChanges[$sAttCode]);
|
||||
$iNewLeft = CMDBSource::QueryToScalar($sSQL);
|
||||
}
|
||||
|
||||
MetaModel::HKReplugBranch($iNewLeft, $iNewLeft + $iDelta - 1, $oAttDef, $sTable);
|
||||
|
||||
$aHKChanges = array();
|
||||
$aHKChanges[$sAttCode] = $aChanges[$sAttCode];
|
||||
$aHKChanges[$oAttDef->GetSQLLeft()] = $iNewLeft;
|
||||
$aHKChanges[$oAttDef->GetSQLRight()] = $iNewLeft + $iDelta - 1;
|
||||
$aChanges[$sAttCode] = $aHKChanges; // the 3 values will be stored by MakeUpdateQuery below
|
||||
}
|
||||
|
||||
// Update scalar attributes
|
||||
if (count($aChanges) != 0)
|
||||
{
|
||||
$oFilter = new DBObjectSearch(get_class($this));
|
||||
$oFilter->AddCondition('id', $this->m_iKey, '=');
|
||||
|
||||
$sSQL = MetaModel::MakeUpdateQuery($oFilter, $aChanges);
|
||||
CMDBSource::Query($sSQL);
|
||||
}
|
||||
}
|
||||
|
||||
$this->DBWriteLinks();
|
||||
$this->m_bDirty = false;
|
||||
|
||||
$this->AfterUpdate();
|
||||
|
||||
// Reload to get the external attributes
|
||||
if ($bHasANewExternalKeyValue)
|
||||
{
|
||||
$this->Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset original values although the object has not been reloaded
|
||||
foreach ($this->m_aLoadedAtt as $sAttCode => $bLoaded)
|
||||
{
|
||||
if ($bLoaded)
|
||||
{
|
||||
$value = $this->m_aCurrValues[$sAttCode];
|
||||
$this->m_aOrigValues[$sAttCode] = is_object($value) ? clone $value : $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert at the right of the specified parent
|
||||
$sSQL = "SELECT `".$oAttDef->GetSQLRight()."` FROM `$sTable` WHERE id=".((int)$aChanges[$sAttCode]);
|
||||
$iNewLeft = CMDBSource::QueryToScalar($sSQL);
|
||||
}
|
||||
|
||||
MetaModel::HKReplugBranch($iNewLeft, $iNewLeft + $iDelta - 1, $oAttDef, $sTable);
|
||||
|
||||
$aHKChanges = array();
|
||||
$aHKChanges[$sAttCode] = $aChanges[$sAttCode];
|
||||
$aHKChanges[$oAttDef->GetSQLLeft()] = $iNewLeft;
|
||||
$aHKChanges[$oAttDef->GetSQLRight()] = $iNewLeft + $iDelta - 1;
|
||||
$aChanges[$sAttCode] = $aHKChanges; // the 3 values will be stored by MakeUpdateQuery below
|
||||
}
|
||||
|
||||
// Update scalar attributes
|
||||
}
|
||||
|
||||
if (count($aChanges) != 0)
|
||||
{
|
||||
$oFilter = new DBObjectSearch(get_class($this));
|
||||
$oFilter->AddCondition('id', $this->m_iKey, '=');
|
||||
|
||||
$sSQL = MetaModel::MakeUpdateQuery($oFilter, $aChanges);
|
||||
CMDBSource::Query($sSQL);
|
||||
$this->RecordAttChanges($aChanges, $aOriginalValues);
|
||||
}
|
||||
}
|
||||
|
||||
$this->DBWriteLinks();
|
||||
$this->m_bDirty = false;
|
||||
|
||||
$this->AfterUpdate();
|
||||
|
||||
// Reload to get the external attributes
|
||||
if ($bHasANewExternalKeyValue)
|
||||
catch (Exception $e)
|
||||
{
|
||||
$this->Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset original values although the object has not been reloaded
|
||||
foreach ($this->m_aLoadedAtt as $sAttCode => $bLoaded)
|
||||
{
|
||||
if ($bLoaded)
|
||||
{
|
||||
$value = $this->m_aCurrValues[$sAttCode];
|
||||
$this->m_aOrigValues[$sAttCode] = is_object($value) ? clone $value : $value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (count($aChanges) != 0)
|
||||
{
|
||||
$this->RecordAttChanges($aChanges, $aOriginalValues);
|
||||
unset($aUpdateReentrance[$sKey]);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
unset($aUpdateReentrance[$sKey]);
|
||||
return $this->m_iKey;
|
||||
}
|
||||
|
||||
@@ -1811,7 +1885,8 @@ abstract class DBObject
|
||||
$this->AfterDelete();
|
||||
|
||||
$this->m_bIsInDB = false;
|
||||
$this->m_iKey = null;
|
||||
// Fix for #926: do NOT reset m_iKey as it can be used to have it for reporting purposes (see the REST service to delete objects, reported as bug #926)
|
||||
// Thought the key is not reset, using DBInsert or DBWrite will create an object having the same characteristics and a new ID. DBUpdate is protected
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,6 +1894,11 @@ abstract class DBObject
|
||||
//
|
||||
public function DBDelete(&$oDeletionPlan = null)
|
||||
{
|
||||
static $iLoopTimeLimit = null;
|
||||
if ($iLoopTimeLimit == null)
|
||||
{
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
}
|
||||
if (is_null($oDeletionPlan))
|
||||
{
|
||||
$oDeletionPlan = new DeletionPlan();
|
||||
@@ -1848,7 +1928,7 @@ abstract class DBObject
|
||||
// As a temporary fix: delete only the objects that are still to be deleted...
|
||||
if ($oToDelete->m_bIsInDB)
|
||||
{
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$oToDelete->DBDeleteSingleObject();
|
||||
}
|
||||
}
|
||||
@@ -1862,7 +1942,7 @@ abstract class DBObject
|
||||
foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef)
|
||||
{
|
||||
$oToUpdate->Set($sRemoteExtKey, $aData['values'][$sRemoteExtKey]);
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$oToUpdate->DBUpdate();
|
||||
}
|
||||
}
|
||||
@@ -2028,7 +2108,10 @@ abstract class DBObject
|
||||
{
|
||||
$oCaseLog = $this->Get($sAttCode);
|
||||
$aScalarArgs[$sArgName.'->'.$sAttCode] = $oCaseLog->GetText();
|
||||
$aScalarArgs[$sArgName.'->head('.$sAttCode.')'] = $oCaseLog->GetLatestEntry();
|
||||
$sHead = $oCaseLog->GetLatestEntry();
|
||||
$aScalarArgs[$sArgName.'->head('.$sAttCode.')'] = $sHead;
|
||||
$aScalarArgs[$sArgName.'->head_html('.$sAttCode.')'] = '<div class="caselog_entry">'.str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sHead, ENT_QUOTES, 'UTF-8')).'</div>';
|
||||
$aScalarArgs[$sArgName.'->html('.$sAttCode.')'] = $oCaseLog->GetAsEmailHtml();
|
||||
}
|
||||
elseif ($oAttDef->IsScalar())
|
||||
{
|
||||
@@ -2042,7 +2125,7 @@ abstract class DBObject
|
||||
{
|
||||
$sRemoteName = $oAttDef->IsIndirect() ? $oAttDef->GetExtKeyToRemote().'_friendlyname' : 'friendlyname';
|
||||
|
||||
$oLinkSet = $this->Get($sAttCode);
|
||||
$oLinkSet = clone $this->Get($sAttCode); // Workaround/Safety net for Trac #887
|
||||
$iLimit = MetaModel::GetConfig()->Get('max_linkset_output');
|
||||
if ($iLimit > 0)
|
||||
{
|
||||
@@ -2059,6 +2142,7 @@ abstract class DBObject
|
||||
}
|
||||
$sNames = implode("\n", $aNames);
|
||||
$aScalarArgs[$sArgName.'->'.$sAttCode] = $sNames;
|
||||
$aScalarArgs[$sArgName.'->html('.$sAttCode.')'] = '<ul><li>'.implode("</li><li>", $aNames).'</li></ul>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2317,6 +2401,11 @@ abstract class DBObject
|
||||
|
||||
private function MakeDeletionPlan(&$oDeletionPlan, $aVisited = array(), $iDeleteOption = null)
|
||||
{
|
||||
static $iLoopTimeLimit = null;
|
||||
if ($iLoopTimeLimit == null)
|
||||
{
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
}
|
||||
$sClass = get_class($this);
|
||||
$iThisId = $this->GetKey();
|
||||
|
||||
@@ -2350,7 +2439,7 @@ abstract class DBObject
|
||||
{
|
||||
foreach ($aPotentialDeletes as $sRemoteExtKey => $aData)
|
||||
{
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
|
||||
$oAttDef = $aData['attribute'];
|
||||
$iDeletePropagationOption = $oAttDef->GetDeletionPropagationOption();
|
||||
@@ -2436,9 +2525,6 @@ abstract class DBObject
|
||||
|
||||
public function InSyncScope()
|
||||
{
|
||||
return true;
|
||||
|
||||
// TODO - FINALIZE THIS OPTIMIZATION
|
||||
//
|
||||
// Optimization: cache the list of Data Sources and classes candidates for synchro
|
||||
//
|
||||
@@ -2451,12 +2537,50 @@ abstract class DBObject
|
||||
while($oSource = $oSourceSet->Fetch())
|
||||
{
|
||||
$sTarget = $oSource->Get('scope_class');
|
||||
$aSynchroClasses[] = $oSource;
|
||||
$aSynchroClasses[] = $sTarget;
|
||||
}
|
||||
}
|
||||
// to be continued...
|
||||
|
||||
foreach($aSynchroClasses as $sClass)
|
||||
{
|
||||
if ($this instanceof $sClass)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Experimental iDisplay implementation
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static function MapContextParam($sContextParam)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetHilightClass()
|
||||
{
|
||||
return HILIGHT_CLASS_NONE;
|
||||
}
|
||||
|
||||
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
$oPage->add('<h1>'.MetaModel::GetName(get_class($this)).': '.$this->GetName().'</h1>');
|
||||
$aValues = array();
|
||||
$aList = MetaModel::FlattenZList(MetaModel::GetZListItems(get_class($this), 'details'));
|
||||
if (empty($aList))
|
||||
{
|
||||
$aList = array_keys(MetaModel::ListAttributeDefs(get_class($this)));
|
||||
}
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
$aValues[$sAttCode] = array('label' => MetaModel::GetLabel(get_class($this), $sAttCode), 'value' => $this->GetAsHTML($sAttCode));
|
||||
}
|
||||
$oPage->details($aValues);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -72,11 +72,11 @@ class DBObjectSearch
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a deep clone (as opposed to "clone" which does copy a reference to the underlying objects
|
||||
* Perform a deep clone (as opposed to "clone" which does copy a reference to the underlying objects)
|
||||
**/
|
||||
public function DeepClone()
|
||||
{
|
||||
return unserialize(serialize($this));
|
||||
return unserialize(serialize($this)); // Beware this serializes/unserializes the search and its parameters as well
|
||||
}
|
||||
|
||||
public function AllowAllData() {$this->m_bAllowAllData = true;}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2013 Combodo SARL
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -26,20 +26,34 @@
|
||||
|
||||
|
||||
/**
|
||||
* A set of persistent objects, could be heterogeneous
|
||||
* A set of persistent objects, could be heterogeneous as long as the objects in the set have a common ancestor class
|
||||
*
|
||||
* @package iTopORM
|
||||
*/
|
||||
class DBObjectSet
|
||||
{
|
||||
private $m_oFilter;
|
||||
private $m_aAddedIds; // Ids of objects added (discrete lists)
|
||||
private $m_aOrderBy;
|
||||
protected $m_aAddedIds; // Ids of objects added (discrete lists)
|
||||
protected $m_aAddedObjects;
|
||||
protected $m_aArgs;
|
||||
protected $m_aAttToLoad;
|
||||
protected $m_aOrderBy;
|
||||
public $m_bLoaded;
|
||||
private $m_aData;
|
||||
private $m_aId2Row;
|
||||
private $m_iCurrRow;
|
||||
protected $m_iNumTotalDBRows;
|
||||
protected $m_iNumLoadedDBRows;
|
||||
protected $m_iCurrRow;
|
||||
protected $m_oFilter;
|
||||
protected $m_oSQLResult;
|
||||
|
||||
/**
|
||||
* Create a new set based on a Search definition.
|
||||
*
|
||||
* @param DBObjectSearch $oFilter The search filter defining the objects which are part of the set (multiple columns/objects per row are supported)
|
||||
* @param hash $aOrderBy
|
||||
* @param hash $aArgs Values to substitute for the search/query parameters (if any). Format: param_name => value
|
||||
* @param hash $aExtendedDataSpec
|
||||
* @param int $iLimitCount Maximum number of rows to load (i.e. equivalent to MySQL's LIMIT start, count)
|
||||
* @param int $iLimitStart Index of the first row to load (i.e. equivalent to MySQL's LIMIT start, count)
|
||||
*/
|
||||
public function __construct(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array(), $aExtendedDataSpec = null, $iLimitCount = 0, $iLimitStart = 0)
|
||||
{
|
||||
$this->m_oFilter = $oFilter->DeepClone();
|
||||
@@ -51,15 +65,20 @@ class DBObjectSet
|
||||
$this->m_iLimitCount = $iLimitCount;
|
||||
$this->m_iLimitStart = $iLimitStart;
|
||||
|
||||
$this->m_iCount = null; // null if unknown yet
|
||||
$this->m_iNumTotalDBRows = null; // Total number of rows for the query without LIMIT. null if unknown yet
|
||||
$this->m_iNumLoadedDBRows = 0; // Total number of rows LOADED in $this->m_oSQLResult via a SQL query. 0 by default
|
||||
$this->m_bLoaded = false; // true when the filter has been used OR the set is built step by step (AddObject...)
|
||||
$this->m_aData = array(); // array of (row => array of (classalias) => object/null)
|
||||
$this->m_aId2Row = array(); // array of (pkey => index in m_aData)
|
||||
$this->m_aAddedObjects = array(); // array of (row => array of (classalias) => object/null) storing the objects added "in memory"
|
||||
$this->m_iCurrRow = 0;
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_object($this->m_oSQLResult))
|
||||
{
|
||||
$this->m_oSQLResult->free();
|
||||
}
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
@@ -82,6 +101,35 @@ class DBObjectSet
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
$this->m_oFilter = $this->m_oFilter->DeepClone();
|
||||
|
||||
$this->m_iNumTotalDBRows = null; // Total number of rows for the query without LIMIT. null if unknown yet
|
||||
$this->m_iNumLoadedDBRows = 0; // Total number of rows LOADED in $this->m_oSQLResult via a SQL query. 0 by default
|
||||
$this->m_bLoaded = false; // true when the filter has been used OR the set is built step by step (AddObject...)
|
||||
$this->m_iCurrRow = 0;
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when unserializing a DBObjectSet
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->m_iNumTotalDBRows = null; // Total number of rows for the query without LIMIT. null if unknown yet
|
||||
$this->m_iNumLoadedDBRows = 0; // Total number of rows LOADED in $this->m_oSQLResult via a SQL query. 0 by default
|
||||
$this->m_bLoaded = false; // true when the filter has been used OR the set is built step by step (AddObject...)
|
||||
$this->m_iCurrRow = 0;
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
/**
|
||||
* Specify the subset of attributes to load (for each class of objects) before performing the SQL query for retrieving the rows from the DB
|
||||
*
|
||||
* @param hash $aAttToLoad Format: alias => array of attribute_codes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function OptimizeColumnLoad($aAttToLoad)
|
||||
{
|
||||
if (is_null($aAttToLoad))
|
||||
@@ -125,6 +173,13 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a set (in-memory) containing just the given object
|
||||
*
|
||||
* @param DBobject $oObject
|
||||
*
|
||||
* @return DBObjectSet The singleton set
|
||||
*/
|
||||
static public function FromObject($oObject)
|
||||
{
|
||||
$oRetSet = self::FromScratch(get_class($oObject));
|
||||
@@ -132,17 +187,31 @@ class DBObjectSet
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty set (in-memory), for the given class (and its subclasses) of objects
|
||||
*
|
||||
* @param string $sClass The class (or an ancestor) for the objects to be added in this set
|
||||
*
|
||||
* @return DBObject The empty set
|
||||
*/
|
||||
static public function FromScratch($sClass)
|
||||
{
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$oFilter->AddConditionExpression(new FalseExpression());
|
||||
$oRetSet = new self($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
$oRetSet->m_iNumTotalDBRows = 0; // Nothing from the DB
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
// create an object set ex nihilo
|
||||
// input = array of objects
|
||||
/**
|
||||
* Create a set (in-memory) with just one column (i.e. one object per row) and filled with the given array of objects
|
||||
*
|
||||
* @param string $sClass The class of the objects (must be a common ancestor to all objects in the set)
|
||||
* @param array $aObjects The list of objects to add into the set
|
||||
*
|
||||
* @return DBObjectSet
|
||||
*/
|
||||
static public function FromArray($sClass, $aObjects)
|
||||
{
|
||||
$oRetSet = self::FromScratch($sClass);
|
||||
@@ -150,21 +219,30 @@ class DBObjectSet
|
||||
return $oRetSet;
|
||||
}
|
||||
|
||||
// create an object set ex nihilo
|
||||
// aClasses = array of (alias => class)
|
||||
// input = array of (array of (classalias => object))
|
||||
/**
|
||||
* Create a set in-memory with several classes of objects per row (with one alias per "column")
|
||||
*
|
||||
* Limitation:
|
||||
* The filter/OQL query representing such a set can not be rebuilt (only the first column will be taken into account)
|
||||
*
|
||||
* @param hash $aClasses Format: array of (alias => class)
|
||||
* @param hash $aObjects Format: array of (array of (classalias => object))
|
||||
*
|
||||
* @return DBObjectSet
|
||||
*/
|
||||
static public function FromArrayAssoc($aClasses, $aObjects)
|
||||
{
|
||||
// In a perfect world, we should create a complete tree of DBObjectSearch,
|
||||
// but as we lack most of the information related to the objects,
|
||||
// let's create one search definition
|
||||
// let's create one search definition corresponding only to the first column
|
||||
$sClass = reset($aClasses);
|
||||
$sAlias = key($aClasses);
|
||||
$oFilter = new CMDBSearchFilter($sClass, $sAlias);
|
||||
|
||||
$oRetSet = new self($oFilter);
|
||||
$oRetSet->m_bLoaded = true; // no DB load
|
||||
|
||||
$oRetSet->m_iNumTotalDBRows = 0; // Nothing from the DB
|
||||
|
||||
foreach($aObjects as $rowIndex => $aObjectsByClassAlias)
|
||||
{
|
||||
$oRetSet->AddObjectExtended($aObjectsByClassAlias);
|
||||
@@ -209,11 +287,13 @@ class DBObjectSet
|
||||
public function ToArrayOfValues()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
$this->Rewind();
|
||||
|
||||
$aSelectedClasses = $this->m_oFilter->GetSelectedClasses();
|
||||
|
||||
$aRet = array();
|
||||
foreach($this->m_aData as $iRow => $aObjects)
|
||||
$iRow = 0;
|
||||
while($aObjects = $this->FetchAssoc())
|
||||
{
|
||||
foreach($aObjects as $sClassAlias => $oObject)
|
||||
{
|
||||
@@ -249,6 +329,7 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
}
|
||||
$iRow++;
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
@@ -271,6 +352,14 @@ class DBObjectSet
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the DBObjectSearch corresponding to the objects present in this set
|
||||
*
|
||||
* Limitation:
|
||||
* This method will NOT work for sets with several columns (i.e. several objects per row)
|
||||
*
|
||||
* @return DBObjectSearch
|
||||
*/
|
||||
public function GetFilter()
|
||||
{
|
||||
// Make sure that we carry on the parameters of the set with the filter
|
||||
@@ -293,37 +382,72 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The (common ancestor) class of the objects in the first column of this set
|
||||
*
|
||||
* @return string The class of the objects in the first column
|
||||
*/
|
||||
public function GetClass()
|
||||
{
|
||||
return $this->m_oFilter->GetClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* The alias for the class of the objects in the first column of this set
|
||||
*
|
||||
* @return string The alias of the class in the first column
|
||||
*/
|
||||
public function GetClassAlias()
|
||||
{
|
||||
return $this->m_oFilter->GetClassAlias();
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of all classes (one per column) which are part of this set
|
||||
*
|
||||
* @return hash Format: alias => class
|
||||
*/
|
||||
public function GetSelectedClasses()
|
||||
{
|
||||
return $this->m_oFilter->GetSelectedClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* The root class (i.e. highest ancestor in the MeaModel class hierarchy) for the first column on this set
|
||||
*
|
||||
* @return string The root class for the objects in the first column of the set
|
||||
*/
|
||||
public function GetRootClass()
|
||||
{
|
||||
return MetaModel::GetRootClass($this->GetClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* The arguments used for building this set
|
||||
*
|
||||
* @return hash Format: parameter_name => value
|
||||
*/
|
||||
public function GetArgs()
|
||||
{
|
||||
return $this->m_aArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the limits for loading the rows from the DB. Equivalent to MySQL's LIMIT start,count clause.
|
||||
* @param int $iLimitCount The number of rows to load
|
||||
* @param int $iLimitStart The index of the first row to load
|
||||
*/
|
||||
public function SetLimit($iLimitCount, $iLimitStart = 0)
|
||||
{
|
||||
$this->m_iLimitCount = $iLimitCount;
|
||||
$this->m_iLimitStart = $iLimitStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the sort order for loading the rows from the DB. Changing the order by causes a Reload.
|
||||
*
|
||||
* @param hash $aOrderBy Format: field_code => boolean (true = ascending, false = descending)
|
||||
*/
|
||||
public function SetOrderBy($aOrderBy)
|
||||
{
|
||||
if ($this->m_aOrderBy != $aOrderBy)
|
||||
@@ -337,16 +461,33 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 'count' limit for loading the rows from the DB
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetLimitCount()
|
||||
{
|
||||
return $this->m_iLimitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 'start' limit for loading the rows from the DB
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function GetLimitStart()
|
||||
{
|
||||
return $this->m_iLimitStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sort order used for loading this set from the database
|
||||
*
|
||||
* Limitation: the sort order has no effect on objects added in-memory
|
||||
*
|
||||
* @return hash Format: field_code => boolean (true = ascending, false = descending)
|
||||
*/
|
||||
public function GetRealSortOrder()
|
||||
{
|
||||
// Get the class default sort order if not specified with the API
|
||||
@@ -361,6 +502,9 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the set from the database. Actually performs the SQL query to retrieve the records from the DB.
|
||||
*/
|
||||
public function Load()
|
||||
{
|
||||
if ($this->m_bLoaded) return;
|
||||
@@ -375,87 +519,150 @@ class DBObjectSet
|
||||
{
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->GetRealSortOrder(), $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return;
|
||||
|
||||
$sClass = $this->m_oFilter->GetClass();
|
||||
while ($aRow = CMDBSource::FetchArray($resQuery))
|
||||
|
||||
if (is_object($this->m_oSQLResult))
|
||||
{
|
||||
$aObjects = array();
|
||||
foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
|
||||
{
|
||||
if (is_null($aRow[$sClassAlias.'id']))
|
||||
{
|
||||
$oObject = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObject = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
|
||||
$aObjects[$sClassAlias] = $oObject;
|
||||
}
|
||||
$this->AddObjectExtended($aObjects, true /* internal load */);
|
||||
// Free previous resultset if any
|
||||
$this->m_oSQLResult->free();
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
$this->m_iNumTotalDBRows = null;
|
||||
|
||||
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
||||
if ($this->m_oSQLResult === false) return;
|
||||
|
||||
if (($this->m_iLimitCount == 0) && ($this->m_iLimitStart == 0))
|
||||
{
|
||||
$this->m_iNumTotalDBRows = $this->m_oSQLResult->num_rows;
|
||||
}
|
||||
$this->m_iNumLoadedDBRows = $this->m_oSQLResult->num_rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of rows in this set. Independently of the SetLimit used for loading the set and taking into account the rows added in-memory.
|
||||
*
|
||||
* May actually perform the SQL query SELECT COUNT... if the set was not previously loaded, or loaded with a SetLimit
|
||||
*
|
||||
* @return int The total number of rows for this set.
|
||||
*/
|
||||
public function Count()
|
||||
{
|
||||
if ($this->m_bLoaded && ($this->m_iLimitCount == 0) && ($this->m_iLimitStart == 0))
|
||||
if (is_null($this->m_iNumTotalDBRows))
|
||||
{
|
||||
return count($this->m_aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_null($this->m_iCount))
|
||||
{
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, array(), $this->m_aArgs, null, null, 0, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return 0;
|
||||
|
||||
$aRow = CMDBSource::FetchArray($resQuery);
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
$this->m_iCount = $aRow['COUNT'];
|
||||
}
|
||||
return $this->m_iCount;
|
||||
$sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, array(), $this->m_aArgs, null, null, 0, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
if (!$resQuery) return 0;
|
||||
|
||||
$aRow = CMDBSource::FetchArray($resQuery);
|
||||
CMDBSource::FreeResult($resQuery);
|
||||
$this->m_iNumTotalDBRows = $aRow['COUNT'];
|
||||
}
|
||||
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of rows available in memory (loaded from DB + added in memory)
|
||||
*
|
||||
* @return number The number of rows available for Fetch'ing
|
||||
*/
|
||||
protected function CountLoaded()
|
||||
{
|
||||
return $this->m_iNumLoadedDBRows + count($this->m_aAddedObjects);
|
||||
}
|
||||
|
||||
public function Fetch($sClassAlias = '')
|
||||
/**
|
||||
* Fetch the object (with the given class alias) at the current position in the set and move the cursor to the next position.
|
||||
*
|
||||
* @param string $sRequestedClassAlias The class alias to fetch (if there are several objects/classes per row)
|
||||
* @return DBObject The fetched object or null when at the end
|
||||
*/
|
||||
public function Fetch($sRequestedClassAlias = '')
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
if ($this->m_iCurrRow >= count($this->m_aData))
|
||||
if ($this->m_iCurrRow >= $this->CountLoaded())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strlen($sClassAlias) == 0)
|
||||
if (strlen($sRequestedClassAlias) == 0)
|
||||
{
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
$sRequestedClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
}
|
||||
|
||||
if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows)
|
||||
{
|
||||
// Pick the row from the database
|
||||
$aRow = CMDBSource::FetchArray($this->m_oSQLResult);
|
||||
foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
|
||||
{
|
||||
if ($sRequestedClassAlias == $sClassAlias)
|
||||
{
|
||||
if (is_null($aRow[$sClassAlias.'id']))
|
||||
{
|
||||
$oRetObj = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oRetObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pick the row from the objects added *in memory*
|
||||
$oRetObj = $this->m_aAddedObjects[$this->m_iCurrRow - $this->m_iNumLoadedDBRows][$sRequestedClassAlias];
|
||||
}
|
||||
$oRetObj = $this->m_aData[$this->m_iCurrRow][$sClassAlias];
|
||||
$this->m_iCurrRow++;
|
||||
return $oRetObj;
|
||||
}
|
||||
|
||||
// Return the whole line if several classes have been specified in the query
|
||||
//
|
||||
/**
|
||||
* Fetch the whole row of objects (if several classes have been specified in the query) and move the cursor to the next position
|
||||
*
|
||||
* @return hash A hash with the format 'classAlias' => $oObj representing the current row of the set. Returns null when at the end.
|
||||
*/
|
||||
public function FetchAssoc()
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
if ($this->m_iCurrRow >= count($this->m_aData))
|
||||
if ($this->m_iCurrRow >= $this->CountLoaded())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$aRetObjects = $this->m_aData[$this->m_iCurrRow];
|
||||
if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows)
|
||||
{
|
||||
// Pick the row from the database
|
||||
$aRow = CMDBSource::FetchArray($this->m_oSQLResult);
|
||||
$aRetObjects = array();
|
||||
foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
|
||||
{
|
||||
if (is_null($aRow[$sClassAlias.'id']))
|
||||
{
|
||||
$oObj = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
$aRetObjects[$sClassAlias] = $oObj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pick the row from the objects added *in memory*
|
||||
$oRetObj = $this->m_aAddedObjects[$this->m_iCurrRow - $this->m_iNumLoadedDBRows][$sRequestedClassAlias];
|
||||
}
|
||||
$this->m_iCurrRow++;
|
||||
return $aRetObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Position the cursor (for iterating in the set) to the first position (equivalent to Seek(0))
|
||||
*/
|
||||
public function Rewind()
|
||||
{
|
||||
if ($this->m_bLoaded)
|
||||
@@ -464,14 +671,32 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Position the cursor (for iterating in the set) to the given position
|
||||
*
|
||||
* @param int $iRow
|
||||
*/
|
||||
public function Seek($iRow)
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$this->m_iCurrRow = min($iRow, count($this->m_aData));
|
||||
$this->m_iCurrRow = min($iRow, $this->Count());
|
||||
if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows)
|
||||
{
|
||||
$this->m_oSQLResult->data_seek($this->m_iCurrRow);
|
||||
}
|
||||
return $this->m_iCurrRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object to the current set (in-memory only, nothing is written to the database)
|
||||
*
|
||||
* Limitation:
|
||||
* Sets with several objects per row are NOT supported
|
||||
*
|
||||
* @param DBObject $oObject The object to add
|
||||
* @param string $sClassAlias The alias for the class of the object
|
||||
*/
|
||||
public function AddObject($oObject, $sClassAlias = '')
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
@@ -481,35 +706,52 @@ class DBObjectSet
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
}
|
||||
|
||||
$iNextPos = count($this->m_aData);
|
||||
$this->m_aData[$iNextPos][$sClassAlias] = $oObject;
|
||||
$iNextPos = count($this->m_aAddedObjects);
|
||||
$this->m_aAddedObjects[$iNextPos][$sClassAlias] = $oObject;
|
||||
if (!is_null($oObject))
|
||||
{
|
||||
$this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos;
|
||||
$this->m_aAddedIds[$oObject->GetKey()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function AddObjectExtended($aObjectArray, $bInternalLoad = false)
|
||||
/**
|
||||
* Add a hash containig objects into the current set.
|
||||
*
|
||||
* The expected format for the hash is: $aObjectArray[$idx][$sClassAlias] => $oObject
|
||||
* Limitation:
|
||||
* The aliases MUST match the ones used in the current set
|
||||
* Only the ID of the objects associated to the first alias (column) is remembered.. in case we have to rebuild a filter
|
||||
*
|
||||
* @param hash $aObjectArray
|
||||
*/
|
||||
protected function AddObjectExtended($aObjectArray)
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$iNextPos = count($this->m_aData);
|
||||
$iNextPos = count($this->m_aAddedObjects);
|
||||
|
||||
$sFirstAlias = $this->m_oFilter->GetClassAlias();
|
||||
|
||||
foreach ($aObjectArray as $sClassAlias => $oObject)
|
||||
{
|
||||
$this->m_aData[$iNextPos][$sClassAlias] = $oObject;
|
||||
if (!is_null($oObject))
|
||||
$this->m_aAddedObjects[$iNextPos][$sClassAlias] = $oObject;
|
||||
|
||||
if (!is_null($oObject) && ($sFirstAlias == $sClassAlias))
|
||||
{
|
||||
$this->m_aId2Row[$sClassAlias][$oObject->GetKey()] = $iNextPos;
|
||||
if (!$bInternalLoad)
|
||||
{
|
||||
$this->m_aAddedIds[$oObject->GetKey()] = true;
|
||||
}
|
||||
$this->m_aAddedIds[$oObject->GetKey()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an array of objects into the current set
|
||||
*
|
||||
* Limitation:
|
||||
* Sets with several classes per row are not supported (use AddObjectExtended instead)
|
||||
*
|
||||
* @param array $aObjects The array of objects to add
|
||||
* @param string $sClassAlias The Alias of the class for the added objects
|
||||
*/
|
||||
public function AddObjectArray($aObjects, $sClassAlias = '')
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
@@ -521,7 +763,16 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
public function Merge($oObjectSet)
|
||||
/**
|
||||
* Append a given set to the current object. (This method used to be named Merge)
|
||||
*
|
||||
* Limitation:
|
||||
* The added objects are not checked for duplicates (i.e. one cann add several times the same object, or add an object already present in the set).
|
||||
*
|
||||
* @param DBObjectSet $oObjectSet The set to append
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function Append(DBObjectSet $oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
@@ -536,7 +787,18 @@ class DBObjectSet
|
||||
}
|
||||
}
|
||||
|
||||
public function CreateIntersect($oObjectSet)
|
||||
/**
|
||||
* Create a set containing the objects present in both the current set and another specified set
|
||||
*
|
||||
* Limitations:
|
||||
* Will NOT work if only a subset of the sets was loaded with SetLimit.
|
||||
* Works only with sets made of objects loaded from the database since the comparison is based on the objects identifiers
|
||||
*
|
||||
* @param DBObjectSet $oObjectSet The set to intersect with. The current position inside the set will be lost (= at the end)
|
||||
* @throws CoreException
|
||||
* @return DBObjectSet A new set of objects, containing the objects present in both sets (based on their identifier)
|
||||
*/
|
||||
public function CreateIntersect(DBObjectSet $oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
@@ -544,58 +806,132 @@ class DBObjectSet
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$aId2Row = array();
|
||||
$iCurrPos = $this->m_iCurrRow; // Save the cursor
|
||||
$idx = 0;
|
||||
while($oObj = $this->Fetch())
|
||||
{
|
||||
$aId2Row[$oObj->GetKey()] = $idx;
|
||||
$idx++;
|
||||
}
|
||||
|
||||
$oNewSet = DBObjectSet::FromScratch($this->GetClass());
|
||||
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
if (array_key_exists($oObject->GetKey(), $this->m_aId2Row[$sClassAlias]))
|
||||
if (array_key_exists($oObject->GetKey(), $aId2Row))
|
||||
{
|
||||
$oNewSet->AddObject($oObject);
|
||||
}
|
||||
}
|
||||
$this->Seek($iCurrPos); // Restore the cursor
|
||||
return $oNewSet;
|
||||
}
|
||||
|
||||
// Note: This verb works only with objects existing in the database
|
||||
//
|
||||
public function HasSameContents($oObjectSet)
|
||||
/**
|
||||
* Compare two sets of objects to determine if their content is identical or not.
|
||||
*
|
||||
* Limitation:
|
||||
* Works only on objects written to the DB, since we rely on their identifiers
|
||||
*
|
||||
* @param DBObjectSet $oObjectSet
|
||||
* @return boolean True if the sets are identical, false otherwise
|
||||
*/
|
||||
public function HasSameContents(DBObjectSet $oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
if ($this->Count() != $oObjectSet->Count())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
|
||||
$aId2Row = array();
|
||||
$bRet = true;
|
||||
$iCurrPos = $this->m_iCurrRow; // Save the cursor
|
||||
$idx = 0;
|
||||
|
||||
// Optimization: we retain the first $iMaxObjects objects in memory
|
||||
// to speed up the comparison of small sets (see below: $oObject->Equals($oSibling))
|
||||
$iMaxObjects = 20;
|
||||
$aCachedObjects = array();
|
||||
while($oObj = $this->Fetch())
|
||||
{
|
||||
$aId2Row[$oObj->GetKey()] = $idx;
|
||||
if ($idx <= $iMaxObjects)
|
||||
{
|
||||
$aCachedObjects[$idx] = $oObj;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
|
||||
$oObjectSet->Rewind();
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
$iObjectKey = $oObject->GetKey();
|
||||
if ($iObjectKey < 0)
|
||||
{
|
||||
return false;
|
||||
$bRet = false;
|
||||
break;
|
||||
}
|
||||
if (!array_key_exists($iObjectKey, $this->m_aId2Row[$sClassAlias]))
|
||||
if (!array_key_exists($iObjectKey, $aId2Row))
|
||||
{
|
||||
return false;
|
||||
$bRet = false;
|
||||
break;
|
||||
}
|
||||
$iRow = $aId2Row[$iObjectKey];
|
||||
if (array_key_exists($iRow, $aCachedObjects))
|
||||
{
|
||||
// Cache hit
|
||||
$oSibling = $aCachedObjects[$iRow];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Go fetch it from the DB, unless it's an object added in-memory
|
||||
$oSibling = $this->GetObjectAt($iRow);
|
||||
}
|
||||
$iRow = $this->m_aId2Row[$sClassAlias][$iObjectKey];
|
||||
$oSibling = $this->m_aData[$iRow][$sClassAlias];
|
||||
if (!$oObject->Equals($oSibling))
|
||||
{
|
||||
return false;
|
||||
$bRet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
$this->Seek($iCurrPos); // Restore the cursor
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
public function CreateDelta($oObjectSet)
|
||||
protected function GetObjectAt($iIndex)
|
||||
{
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
// Save the current position for iteration
|
||||
$iCurrPos = $this->m_iCurrRow;
|
||||
|
||||
$this->Seek($iIndex);
|
||||
$oObject = $this->Fetch();
|
||||
|
||||
// Restore the current position for iteration
|
||||
$this->Seek($this->m_iCurrRow);
|
||||
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a new set (in memory) made of objects of the given set which are NOT present in the current set
|
||||
*
|
||||
* Limitations:
|
||||
* The objects inside the set must be written in the database since the comparison is based on their identifiers
|
||||
* Sets with several objects per row are NOT supported
|
||||
*
|
||||
* @param DBObjectSet $oObjectSet
|
||||
* @throws CoreException
|
||||
*
|
||||
* @return DBObjectSet The "delta" set.
|
||||
*/
|
||||
public function CreateDelta(DBObjectSet $oObjectSet)
|
||||
{
|
||||
if ($this->GetRootClass() != $oObjectSet->GetRootClass())
|
||||
{
|
||||
@@ -603,20 +939,37 @@ class DBObjectSet
|
||||
}
|
||||
if (!$this->m_bLoaded) $this->Load();
|
||||
|
||||
$aId2Row = array();
|
||||
$iCurrPos = $this->m_iCurrRow; // Save the cursor
|
||||
$idx = 0;
|
||||
while($oObj = $this->Fetch())
|
||||
{
|
||||
$aId2Row[$oObj->GetKey()] = $idx;
|
||||
$idx++;
|
||||
}
|
||||
|
||||
$oNewSet = DBObjectSet::FromScratch($this->GetClass());
|
||||
|
||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
$oObjectSet->Seek(0);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
if (!array_key_exists($oObject->GetKey(), $this->m_aId2Row[$sClassAlias]))
|
||||
if (!array_key_exists($oObject->GetKey(), $aId2Row))
|
||||
{
|
||||
$oNewSet->AddObject($oObject);
|
||||
}
|
||||
}
|
||||
$this->Seek($iCurrPos); // Restore the cursor
|
||||
return $oNewSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the "RelatedObjects" (for the given relation, as defined by MetaModel::GetRelatedObjects) for a whole set of DBObjects
|
||||
*
|
||||
* @param string $sRelCode The code of the relation to use for the computation
|
||||
* @param int $iMaxDepth Teh maximum recursion depth
|
||||
*
|
||||
* @return Array An array containg all the "related" objects
|
||||
*/
|
||||
public function GetRelatedObjects($sRelCode, $iMaxDepth = 99)
|
||||
{
|
||||
$aRelatedObjs = array();
|
||||
@@ -645,7 +998,7 @@ class DBObjectSet
|
||||
* in the set. If for a given attribute, objects in the set have various values
|
||||
* then the resulting object will contain null for this value.
|
||||
* @param $aValues Hash Output: the distribution of the values, in the set, for each attribute
|
||||
* @return Object
|
||||
* @return DBObject The object with the common values
|
||||
*/
|
||||
public function ComputeCommonObject(&$aValues)
|
||||
{
|
||||
@@ -768,7 +1121,10 @@ class DBObjectSet
|
||||
}
|
||||
else
|
||||
{
|
||||
$aScalarArgs[$sArgName] = (string) $value;
|
||||
if (!is_array($value)) // Sometimes ExtraParams contains a mix (like defaults[]) so non scalar parameters are ignored
|
||||
{
|
||||
$aScalarArgs[$sArgName] = (string) $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$aScalarArgs['current_contact_id'] = UserRights::GetContactId();
|
||||
|
||||
@@ -110,12 +110,12 @@ class DeletionPlan
|
||||
// Getting and setting time limit are not symetric:
|
||||
// www.php.net/manual/fr/function.set-time-limit.php#72305
|
||||
$iPreviousTimeLimit = ini_get('max_execution_time');
|
||||
|
||||
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
|
||||
foreach($this->m_aToUpdate as $sClass => $aToUpdate)
|
||||
{
|
||||
foreach($aToUpdate as $iId => $aData)
|
||||
{
|
||||
set_time_limit(5);
|
||||
set_time_limit($iLoopTimeLimit);
|
||||
$this->m_iToUpdate++;
|
||||
|
||||
$oObject = $aData['to_reset'];
|
||||
|
||||
@@ -184,10 +184,13 @@ class EMail
|
||||
|
||||
$oMailer = Swift_Mailer::newInstance($oTransport);
|
||||
|
||||
$iSent = $oMailer->send($this->m_oMessage);
|
||||
$aFailedRecipients = array();
|
||||
$iSent = $oMailer->send($this->m_oMessage, $aFailedRecipients);
|
||||
if ($iSent === 0)
|
||||
{
|
||||
$aIssues = array('No valid recipient for this message.');
|
||||
// Beware: it seems that $aFailedRecipients sometimes contains the recipients that actually received the message !!!
|
||||
IssueLog::Warning('Email sending failed: Some recipients were invalid, aFailedRecipients contains: '.implode(', ', $aFailedRecipients));
|
||||
$aIssues = array('Some recipients were invalid.');
|
||||
return EMAIL_SEND_ERROR;
|
||||
}
|
||||
else
|
||||
@@ -321,6 +324,11 @@ class EMail
|
||||
public function GetRecipientTO($bAsString = false)
|
||||
{
|
||||
$aRes = $this->m_oMessage->getTo();
|
||||
if ($aRes === null)
|
||||
{
|
||||
// There is no "To" header field
|
||||
$aRes = array();
|
||||
}
|
||||
if ($bAsString)
|
||||
{
|
||||
$aStrings = array();
|
||||
|
||||
@@ -1181,6 +1181,16 @@ class CharConcatWSExpression extends CharConcatExpression
|
||||
$sSep = CMDBSource::Quote($this->m_separator);
|
||||
return "CAST(CONCAT_WS($sSep, ".implode(', ', $aRes).") AS CHAR)";
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true, $bMarkFieldsAsResolved = true)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved);
|
||||
}
|
||||
return new CharConcatWSExpression($this->m_separator, $aRes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -593,15 +593,10 @@ abstract class MetaModel
|
||||
$oAtt = self::GetAttributeDef($sClass, $sAttCode);
|
||||
// Temporary implementation: later, we might be able to compute
|
||||
// the dependencies, based on the attributes definition
|
||||
// (allowed values and default values)
|
||||
if ($oAtt->IsWritable())
|
||||
{
|
||||
return $oAtt->GetPrerequisiteAttributes();
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
// (allowed values and default values)
|
||||
|
||||
// Even non-writable attributes (like ExternalFields) can now have Prerequisites
|
||||
return $oAtt->GetPrerequisiteAttributes();
|
||||
}
|
||||
/**
|
||||
* Find all attributes that depend on the specified one (reverse of GetPrequisiteAttributes)
|
||||
@@ -871,15 +866,32 @@ abstract class MetaModel
|
||||
|
||||
final static public function GetExternalFields($sClass, $sKeyAttCode)
|
||||
{
|
||||
$aExtFields = array();
|
||||
foreach (self::ListAttributeDefs($sClass) as $sAttCode => $oAtt)
|
||||
static $aExtFields = array();
|
||||
if (!isset($aExtFields[$sClass][$sKeyAttCode]))
|
||||
{
|
||||
if ($oAtt->IsExternalField() && ($oAtt->GetKeyAttCode() == $sKeyAttCode))
|
||||
$aExtFields[$sClass][$sKeyAttCode] = array();
|
||||
foreach (self::ListAttributeDefs($sClass) as $sAttCode => $oAtt)
|
||||
{
|
||||
$aExtFields[] = $oAtt;
|
||||
if ($oAtt->IsExternalField() && ($oAtt->GetKeyAttCode() == $sKeyAttCode))
|
||||
{
|
||||
$aExtFields[$sClass][$sKeyAttCode][$oAtt->GetExtAttCode()] = $oAtt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aExtFields;
|
||||
return $aExtFields[$sClass][$sKeyAttCode];
|
||||
}
|
||||
|
||||
final static public function FindExternalField($sClass, $sKeyAttCode, $sRemoteAttCode)
|
||||
{
|
||||
$aExtFields = self::GetExternalFields($sClass, $sKeyAttCode);
|
||||
if (isset($aExtFields[$sRemoteAttCode]))
|
||||
{
|
||||
return $aExtFields[$sRemoteAttCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final static public function GetExtKeyFriends($sClass, $sExtKeyAttCode)
|
||||
@@ -5070,6 +5082,41 @@ abstract class MetaModel
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to remove selected objects without calling any handler
|
||||
* Surpasses BulkDelete as it can handle abstract classes, but has the other limitation as it bypasses standard objects handlers
|
||||
*
|
||||
* @param string $oFilter Scope of objects to wipe out
|
||||
* @return The count of deleted objects
|
||||
*/
|
||||
public static function PurgeData($oFilter)
|
||||
{
|
||||
$sTargetClass = $oFilter->GetClass();
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
$oSet->OptimizeColumnLoad(array($sTargetClass => array('finalclass')));
|
||||
$aIdToClass = $oSet->GetColumnAsArray('finalclass', true);
|
||||
|
||||
$aIds = array_keys($aIdToClass);
|
||||
if (count($aIds) > 0)
|
||||
{
|
||||
$aQuotedIds = CMDBSource::Quote($aIds);
|
||||
$sIdList = implode(',', $aQuotedIds);
|
||||
$aTargetClasses = array_merge(
|
||||
self::EnumChildClasses($sTargetClass, ENUM_CHILD_CLASSES_ALL),
|
||||
self::EnumParentClasses($sTargetClass, ENUM_PARENT_CLASSES_EXCLUDELEAF)
|
||||
);
|
||||
foreach ($aTargetClasses as $sSomeClass)
|
||||
{
|
||||
$sTable = MetaModel::DBGetTable($sSomeClass);
|
||||
$sPKField = MetaModel::DBGetKey($sSomeClass);
|
||||
|
||||
$sDeleteSQL = "DELETE FROM `$sTable` WHERE `$sPKField` IN ($sIdList)";
|
||||
CMDBSource::DeleteFrom($sDeleteSQL);
|
||||
}
|
||||
}
|
||||
return count($aIds);
|
||||
}
|
||||
|
||||
// Links
|
||||
//
|
||||
//
|
||||
@@ -5121,6 +5168,12 @@ abstract class MetaModel
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* It is not recommended to use this function: call GetLinkClasses instead
|
||||
* Return classes having at least to external keys (thus too many classes as compared to GetLinkClasses)
|
||||
* The only difference with EnumLinkingClasses is the output format
|
||||
*/
|
||||
public static function EnumLinksClasses()
|
||||
{
|
||||
// Returns a flat array of classes having at least two external keys
|
||||
@@ -5143,6 +5196,11 @@ abstract class MetaModel
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
/**
|
||||
* It is not recommended to use this function: call GetLinkClasses instead
|
||||
* Return classes having at least to external keys (thus too many classes as compared to GetLinkClasses)
|
||||
* The only difference with EnumLinksClasses is the output format
|
||||
*/
|
||||
public static function EnumLinkingClasses($sClass = "")
|
||||
{
|
||||
// N-N links, array of sLinkClass => (array of sAttCode=>sClass)
|
||||
@@ -5179,6 +5237,38 @@ abstract class MetaModel
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function has two siblings that will be soon deprecated:
|
||||
* EnumLinkingClasses and EnumLinkClasses
|
||||
*
|
||||
* Using GetLinkClasses is the recommended way to determine if a class is
|
||||
* actually an N-N relation because it is based on the decision made by the
|
||||
* designer the data model
|
||||
*/
|
||||
public static function GetLinkClasses()
|
||||
{
|
||||
$aRet = array();
|
||||
foreach(self::GetClasses() as $sClass)
|
||||
{
|
||||
if (isset(self::$m_aClassParams[$sClass]["is_link"]))
|
||||
{
|
||||
if (self::$m_aClassParams[$sClass]["is_link"])
|
||||
{
|
||||
$aExtKeys = array();
|
||||
foreach (self::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$aExtKeys[$sAttCode] = $oAttDef->GetTargetClass();
|
||||
}
|
||||
}
|
||||
$aRet[$sClass] = $aExtKeys;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public static function GetLinkLabel($sLinkClass, $sAttCode)
|
||||
{
|
||||
self::_check_subclass($sLinkClass);
|
||||
@@ -5248,18 +5338,27 @@ abstract class MetaModel
|
||||
$sEnvironment = MetaModel::GetEnvironmentId();
|
||||
}
|
||||
$aEntries = array();
|
||||
$aCacheUserData = @apc_cache_info('user');
|
||||
if (extension_loaded('apcu'))
|
||||
{
|
||||
// Beware: APCu behaves slightly differently from APC !!
|
||||
$aCacheUserData = @apc_cache_info();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCacheUserData = @apc_cache_info('user');
|
||||
}
|
||||
if (is_array($aCacheUserData) && isset($aCacheUserData['cache_list']))
|
||||
{
|
||||
$sPrefix = 'itop-'.$sEnvironment.'-';
|
||||
|
||||
foreach($aCacheUserData['cache_list'] as $i => $aEntry)
|
||||
{
|
||||
$sEntryKey = $aEntry['info'];
|
||||
$sEntryKey = array_key_exists('info', $aEntry) ? $aEntry['info'] : $aEntry['key'];
|
||||
if (strpos($sEntryKey, $sPrefix) === 0)
|
||||
{
|
||||
$sCleanKey = substr($sEntryKey, strlen($sPrefix));
|
||||
$aEntries[$sCleanKey] = $aEntry;
|
||||
$aEntries[$sCleanKey]['info'] = $sEntryKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ class ModelReflectionRuntime extends ModelReflection
|
||||
$aClasses = MetaModel::GetClasses($sCategories);
|
||||
if ($bExcludeLinks)
|
||||
{
|
||||
$aExcluded = ProfilesConfig::GetLinkClasses(); // table computed at compile time
|
||||
$aExcluded = MetaModel::GetLinkClasses();
|
||||
$aRes = array();
|
||||
foreach ($aClasses as $sClass)
|
||||
{
|
||||
|
||||
@@ -31,22 +31,36 @@ class iTopMutex
|
||||
{
|
||||
protected $sName;
|
||||
protected $hDBLink;
|
||||
protected $bLocked; // Whether or not this instance of the Mutex is locked
|
||||
static protected $aAcquiredLocks = array(); // Number of instances of the Mutex, having the lock, in this page
|
||||
|
||||
public function __construct($sName)
|
||||
public function __construct($sName, $sDBHost = null, $sDBUser = null, $sDBPwd = null)
|
||||
{
|
||||
// Compute the name of a lock for mysql
|
||||
// Note: the name is server-wide!!!
|
||||
$this->sName = 'itop.'.$sName;
|
||||
$this->bLocked = false; // Not yet locked
|
||||
|
||||
if (!array_key_exists($this->sName, self::$aAcquiredLocks))
|
||||
{
|
||||
self::$aAcquiredLocks[$this->sName] = 0;
|
||||
}
|
||||
|
||||
// It is a MUST to create a dedicated session each time a lock is required, because
|
||||
// using GET_LOCK anytime on the same session will RELEASE the current and unique session lock (known issue)
|
||||
$oConfig = utils::GetConfig();
|
||||
$this->InitMySQLSession($oConfig->GetDBHost(), $oConfig->GetDBUser(), $oConfig->GetDBPwd());
|
||||
$sDBHost = is_null($sDBHost) ? $oConfig->GetDBHost() : $sDBHost;
|
||||
$sDBUser = is_null($sDBUser) ? $oConfig->GetDBUser() : $sDBUser;
|
||||
$sDBPwd = is_null($sDBPwd) ? $oConfig->GetDBPwd() : $sDBPwd;
|
||||
$this->InitMySQLSession($sDBHost, $sDBUser, $sDBPwd);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->Unlock();
|
||||
if ($this->bLocked)
|
||||
{
|
||||
$this->Unlock();
|
||||
}
|
||||
mysqli_close($this->hDBLink);
|
||||
}
|
||||
|
||||
@@ -55,17 +69,27 @@ class iTopMutex
|
||||
*/
|
||||
public function Lock()
|
||||
{
|
||||
do
|
||||
if ($this->bLocked)
|
||||
{
|
||||
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 3600)");
|
||||
if (is_null($res))
|
||||
{
|
||||
throw new Exception("Failed to acquire the lock '".$this->sName."'");
|
||||
}
|
||||
// $res === '1' means I hold the lock
|
||||
// $res === '0' means it timed out
|
||||
// Lock already acquired
|
||||
return;
|
||||
}
|
||||
while ($res !== '1');
|
||||
if (self::$aAcquiredLocks[$this->sName] == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 3600)");
|
||||
if (is_null($res))
|
||||
{
|
||||
throw new Exception("Failed to acquire the lock '".$this->sName."'");
|
||||
}
|
||||
// $res === '1' means I hold the lock
|
||||
// $res === '0' means it timed out
|
||||
}
|
||||
while ($res !== '1');
|
||||
}
|
||||
$this->bLocked = true;
|
||||
self::$aAcquiredLocks[$this->sName]++;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,6 +98,17 @@ class iTopMutex
|
||||
*/
|
||||
public function TryLock()
|
||||
{
|
||||
if ($this->bLocked)
|
||||
{
|
||||
return true; // Already acquired
|
||||
}
|
||||
if (self::$aAcquiredLocks[$this->sName] > 0)
|
||||
{
|
||||
self::$aAcquiredLocks[$this->sName]++;
|
||||
$this->bLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 0)");
|
||||
if (is_null($res))
|
||||
{
|
||||
@@ -81,6 +116,11 @@ class iTopMutex
|
||||
}
|
||||
// $res === '1' means I hold the lock
|
||||
// $res === '0' means it timed out
|
||||
if ($res === '1')
|
||||
{
|
||||
$this->bLocked = true;
|
||||
self::$aAcquiredLocks[$this->sName]++;
|
||||
}
|
||||
return ($res === '1');
|
||||
}
|
||||
|
||||
@@ -89,7 +129,22 @@ class iTopMutex
|
||||
*/
|
||||
public function Unlock()
|
||||
{
|
||||
$res = $this->QueryToScalar("SELECT RELEASE_LOCK('".$this->sName."')");
|
||||
if (!$this->bLocked)
|
||||
{
|
||||
// ??? the lock is not acquired, exit
|
||||
return;
|
||||
}
|
||||
if (self::$aAcquiredLocks[$this->sName] == 0)
|
||||
{
|
||||
return; // Safety net
|
||||
}
|
||||
|
||||
if (self::$aAcquiredLocks[$this->sName] == 1)
|
||||
{
|
||||
$res = $this->QueryToScalar("SELECT RELEASE_LOCK('".$this->sName."')");
|
||||
}
|
||||
$this->bLocked = false;
|
||||
self::$aAcquiredLocks[$this->sName]--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,80 @@ class ormCaseLog {
|
||||
return $this->m_sLog;
|
||||
}
|
||||
|
||||
public static function FromJSON($oJson)
|
||||
{
|
||||
if (!isset($oJson->items))
|
||||
{
|
||||
throw new Exception("Missing 'items' elements");
|
||||
}
|
||||
$oCaseLog = new ormCaseLog();
|
||||
foreach($oJson->items as $oItem)
|
||||
{
|
||||
$oCaseLog->AddLogEntryFromJSON($oItem);
|
||||
}
|
||||
return $oCaseLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a value that will be further JSON encoded
|
||||
*/
|
||||
public function GetForJSON()
|
||||
{
|
||||
$aEntries = array();
|
||||
$iPos = 0;
|
||||
for($index=count($this->m_aIndex)-1 ; $index >= 0 ; $index--)
|
||||
{
|
||||
$iPos += $this->m_aIndex[$index]['separator_length'];
|
||||
$sTextEntry = substr($this->m_sLog, $iPos, $this->m_aIndex[$index]['text_length']);
|
||||
$iPos += $this->m_aIndex[$index]['text_length'];
|
||||
|
||||
// Workaround: PHP < 5.3 cannot unserialize correctly DateTime objects,
|
||||
// therefore we have changed the format. To preserve the compatibility with existing
|
||||
// installations of iTop, both format are allowed:
|
||||
// the 'date' item is either a DateTime object, or a unix timestamp
|
||||
if (is_int($this->m_aIndex[$index]['date']))
|
||||
{
|
||||
// Unix timestamp
|
||||
$sDate = date(Dict::S('UI:CaseLog:DateFormat'),$this->m_aIndex[$index]['date']);
|
||||
}
|
||||
elseif (is_object($this->m_aIndex[$index]['date']))
|
||||
{
|
||||
if (version_compare(phpversion(), '5.3.0', '>='))
|
||||
{
|
||||
// DateTime
|
||||
$sDate = $this->m_aIndex[$index]['date']->format(Dict::S('UI:CaseLog:DateFormat'));
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Warning... but the date is unknown
|
||||
$sDate = '';
|
||||
}
|
||||
}
|
||||
$aEntries[] = array(
|
||||
'date' => $sDate,
|
||||
'user_login' => $this->m_aIndex[$index]['user_name'],
|
||||
'user_id' => $this->m_aIndex[$index]['user_id'],
|
||||
'message' => $sTextEntry
|
||||
);
|
||||
}
|
||||
|
||||
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
||||
if ($iPos < (strlen($this->m_sLog) - 1))
|
||||
{
|
||||
$sTextEntry = substr($this->m_sLog, $iPos);
|
||||
|
||||
$aEntries[] = array(
|
||||
'date' => '',
|
||||
'user_login' => '',
|
||||
'message' => $sTextEntry
|
||||
);
|
||||
}
|
||||
|
||||
// Order by ascending date
|
||||
$aRet = array('entries' => array_reverse($aEntries));
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function GetIndex()
|
||||
{
|
||||
return $this->m_aIndex;
|
||||
@@ -62,7 +136,85 @@ class ormCaseLog {
|
||||
{
|
||||
$this->m_bModified = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces an HTML representation, aimed at being used within an email
|
||||
*/
|
||||
public function GetAsEmailHtml()
|
||||
{
|
||||
$sStyleCaseLogHeader = '';
|
||||
$sStyleCaseLogEntry = '';
|
||||
|
||||
$sHtml = '<table style="width:100%;table-layout:fixed"><tr><td>'; // Use table-layout:fixed to force the with to be independent from the actual content
|
||||
$iPos = 0;
|
||||
$aIndex = $this->m_aIndex;
|
||||
for($index=count($aIndex)-1 ; $index >= 0 ; $index--)
|
||||
{
|
||||
$iPos += $aIndex[$index]['separator_length'];
|
||||
$sTextEntry = substr($this->m_sLog, $iPos, $aIndex[$index]['text_length']);
|
||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
||||
$iPos += $aIndex[$index]['text_length'];
|
||||
|
||||
$sEntry = '<div class="caselog_header" style="'.$sStyleCaseLogHeader.'">';
|
||||
// Workaround: PHP < 5.3 cannot unserialize correctly DateTime objects,
|
||||
// therefore we have changed the format. To preserve the compatibility with existing
|
||||
// installations of iTop, both format are allowed:
|
||||
// the 'date' item is either a DateTime object, or a unix timestamp
|
||||
if (is_int($aIndex[$index]['date']))
|
||||
{
|
||||
// Unix timestamp
|
||||
$sDate = date(Dict::S('UI:CaseLog:DateFormat'),$aIndex[$index]['date']);
|
||||
}
|
||||
elseif (is_object($aIndex[$index]['date']))
|
||||
{
|
||||
if (version_compare(phpversion(), '5.3.0', '>='))
|
||||
{
|
||||
// DateTime
|
||||
$sDate = $aIndex[$index]['date']->format(Dict::S('UI:CaseLog:DateFormat'));
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Warning... but the date is unknown
|
||||
$sDate = '';
|
||||
}
|
||||
}
|
||||
$sEntry .= sprintf(Dict::S('UI:CaseLog:Header_Date_UserName'), '<span class="caselog_header_date">'.$sDate.'</span>', '<span class="caselog_header_user">'.$aIndex[$index]['user_name'].'</span>');
|
||||
$sEntry .= '</div>';
|
||||
$sEntry .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'">';
|
||||
$sEntry .= $sTextEntry;
|
||||
$sEntry .= '</div>';
|
||||
$sHtml = $sHtml.$sEntry;
|
||||
}
|
||||
|
||||
// Process the case of an eventual remainder (quick migration of AttributeText fields)
|
||||
if ($iPos < (strlen($this->m_sLog) - 1))
|
||||
{
|
||||
$sTextEntry = substr($this->m_sLog, $iPos);
|
||||
$sTextEntry = str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sTextEntry, ENT_QUOTES, 'UTF-8'));
|
||||
|
||||
if (count($this->m_aIndex) == 0)
|
||||
{
|
||||
$sHtml .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'"">';
|
||||
$sHtml .= $sTextEntry;
|
||||
$sHtml .= '</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml .= '<div class="caselog_header" style="'.$sStyleCaseLogHeader.'">';
|
||||
$sHtml .= Dict::S('UI:CaseLog:InitialValue');
|
||||
$sHtml .= '</div>';
|
||||
$sHtml .= '<div class="caselog_entry" style="'.$sStyleCaseLogEntry.'">';
|
||||
$sHtml .= $sTextEntry;
|
||||
$sHtml .= '</div>';
|
||||
}
|
||||
}
|
||||
$sHtml .= '</td></tr></table>';
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces an HTML representation, aimed at being used within the iTop framework
|
||||
*/
|
||||
public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
|
||||
{
|
||||
$sHtml = '<table style="width:100%;table-layout:fixed"><tr><td>'; // Use table-layout:fixed to force the with to be independent from the actual content
|
||||
@@ -230,7 +382,62 @@ class ormCaseLog {
|
||||
}
|
||||
$this->m_bModified = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function AddLogEntryFromJSON($oJson)
|
||||
{
|
||||
$sText = isset($oJson->message) ? $oJson->message : '';
|
||||
|
||||
if (isset($oJson->user_id))
|
||||
{
|
||||
if (!UserRights::IsAdministrator())
|
||||
{
|
||||
throw new Exception("Only administrators can set the user id", RestResult::UNAUTHORIZED);
|
||||
}
|
||||
try
|
||||
{
|
||||
$oUser = RestUtils::FindObjectFromKey('User', $oJson->user_id);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new Exception('user_id: '.$e->getMessage(), $e->getCode());
|
||||
}
|
||||
$iUserId = $oUser->GetKey();
|
||||
$sOnBehalfOf = $oUser->GetFriendlyName();
|
||||
}
|
||||
else
|
||||
{
|
||||
$iUserId = UserRights::GetUserId();
|
||||
$sOnBehalfOf = UserRights::GetUserFriendlyName();
|
||||
}
|
||||
|
||||
if (isset($oJson->date))
|
||||
{
|
||||
$oDate = new DateTime($oJson->date);
|
||||
$iDate = (int) $oDate->format('U');
|
||||
}
|
||||
else
|
||||
{
|
||||
$iDate = time();
|
||||
}
|
||||
$sDate = date(Dict::S('UI:CaseLog:DateFormat'), $iDate);
|
||||
|
||||
$sSeparator = sprintf(CASELOG_SEPARATOR, $sDate, $sOnBehalfOf, $iUserId);
|
||||
$iSepLength = strlen($sSeparator);
|
||||
$iTextlength = strlen($sText);
|
||||
$this->m_sLog = $sSeparator.$sText.$this->m_sLog; // Latest entry printed first
|
||||
$this->m_aIndex[] = array(
|
||||
'user_name' => $sOnBehalfOf,
|
||||
'user_id' => $iUserId,
|
||||
'date' => $iDate,
|
||||
'text_length' => $iTextlength,
|
||||
'separator_length' => $iSepLength,
|
||||
);
|
||||
|
||||
$this->m_bModified = true;
|
||||
}
|
||||
|
||||
|
||||
public function GetModifiedEntry()
|
||||
{
|
||||
$sModifiedEntry = '';
|
||||
|
||||
@@ -117,7 +117,18 @@ class ormDocument
|
||||
{
|
||||
return "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode\">".$this->GetFileName()."</a>\n";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an URL to download a document like an image (uses HTTP caching)
|
||||
* @return string
|
||||
*/
|
||||
public function GetDownloadURL($sClass, $Id, $sAttCode)
|
||||
{
|
||||
// Compute a signature to reset the cache anytime the data changes (this is acceptable if used only with icon files)
|
||||
$sSignature = md5($this->GetData());
|
||||
return utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode&s=$sSignature&cache=86400";
|
||||
}
|
||||
|
||||
|
||||
public function IsPreviewAvailable()
|
||||
{
|
||||
|
||||
@@ -258,16 +258,22 @@ class ormStopWatch
|
||||
public function Reset($oObject, $oAttDef)
|
||||
{
|
||||
$this->iTimeSpent = 0;
|
||||
$this->iStarted = null;
|
||||
$this->iLastStart = null;
|
||||
$this->iStopped = null;
|
||||
$this->iStarted = null;
|
||||
|
||||
foreach ($this->aThresholds as $iPercent => &$aThresholdData)
|
||||
{
|
||||
$aThresholdData['triggered'] = false;
|
||||
$aThresholdData['deadline'] = null;
|
||||
$aThresholdData['overrun'] = null;
|
||||
}
|
||||
|
||||
if (!is_null($this->iLastStart))
|
||||
{
|
||||
// Currently running... starting again from now!
|
||||
$this->iStarted = time();
|
||||
$this->iLastStart = time();
|
||||
$this->ComputeDeadlines($oObject, $oAttDef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,9 +57,10 @@ class ObjectResult
|
||||
*
|
||||
* @param DBObject $oObject The object being reported
|
||||
* @param string $sAttCode The attribute code (must be valid)
|
||||
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
||||
* @return string A scalar representation of the value
|
||||
*/
|
||||
protected function MakeResultValue(DBObject $oObject, $sAttCode)
|
||||
protected function MakeResultValue(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
|
||||
{
|
||||
if ($sAttCode == 'id')
|
||||
{
|
||||
@@ -71,34 +72,32 @@ class ObjectResult
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeLinkedSet)
|
||||
{
|
||||
$value = array();
|
||||
|
||||
// Make the list of required attributes
|
||||
// - Skip attributes pointing to the current object (redundant data)
|
||||
// - Skip link sets refering to the current data (infinite recursion!)
|
||||
$aRelevantAttributes = array();
|
||||
$sLnkClass = $oAttDef->GetLinkedClass();
|
||||
foreach (MetaModel::ListAttributeDefs($sLnkClass) as $sLnkAttCode => $oLnkAttDef)
|
||||
{
|
||||
// Skip any attribute of the link that points to the current object
|
||||
//
|
||||
if ($sLnkAttCode == $oAttDef->GetExtKeyToMe()) continue;
|
||||
if (method_exists($oLnkAttDef, 'GetKeyAttCode'))
|
||||
{
|
||||
if ($oLnkAttDef->GetKeyAttCode() ==$oAttDef->GetExtKeyToMe()) continue;
|
||||
}
|
||||
|
||||
$aRelevantAttributes[] = $sLnkAttCode;
|
||||
}
|
||||
|
||||
// Iterate on the set and build an array of array of attcode=>value
|
||||
$oSet = $oObject->Get($sAttCode);
|
||||
$value = array();
|
||||
while ($oLnk = $oSet->Fetch())
|
||||
{
|
||||
$sLnkRefClass = $bExtendedOutput ? get_class($oLnk) : $oAttDef->GetLinkedClass();
|
||||
|
||||
$aLnkValues = array();
|
||||
foreach ($aRelevantAttributes as $sLnkAttCode)
|
||||
foreach (MetaModel::ListAttributeDefs($sLnkRefClass) as $sLnkAttCode => $oLnkAttDef)
|
||||
{
|
||||
$aLnkValues[$sLnkAttCode] = $this->MakeResultValue($oLnk, $sLnkAttCode);
|
||||
// Skip attributes pointing to the current object (redundant data)
|
||||
if ($sLnkAttCode == $oAttDef->GetExtKeyToMe())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Skip any attribute of the link that points to the current object
|
||||
$oLnkAttDef = MetaModel::GetAttributeDef($sLnkRefClass, $sLnkAttCode);
|
||||
if (method_exists($oLnkAttDef, 'GetKeyAttCode'))
|
||||
{
|
||||
if ($oLnkAttDef->GetKeyAttCode() == $oAttDef->GetExtKeyToMe())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$aLnkValues[$sLnkAttCode] = $this->MakeResultValue($oLnk, $sLnkAttCode, $bExtendedOutput);
|
||||
}
|
||||
$value[] = $aLnkValues;
|
||||
}
|
||||
@@ -116,11 +115,12 @@ class ObjectResult
|
||||
*
|
||||
* @param DBObject $oObject The object being reported
|
||||
* @param string $sAttCode The attribute code (must be valid)
|
||||
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
||||
* @return void
|
||||
*/
|
||||
public function AddField(DBObject $oObject, $sAttCode)
|
||||
public function AddField(DBObject $oObject, $sAttCode, $bExtendedOutput = false)
|
||||
{
|
||||
$this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode);
|
||||
$this->fields[$sAttCode] = $this->MakeResultValue($oObject, $sAttCode, $bExtendedOutput);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,18 +143,39 @@ class RestResultWithObjects extends RestResult
|
||||
* @param int An error code (RestResult::OK is no issue has been found)
|
||||
* @param string $sMessage Description of the error if any, an empty string otherwise
|
||||
* @param DBObject $oObject The object being reported
|
||||
* @param array $aFields An array of attribute codes. List of the attributes to be reported.
|
||||
* @param array $aFieldSpec An array of class => attribute codes (Cf. RestUtils::GetFieldList). List of the attributes to be reported.
|
||||
* @param boolean $bExtendedOutput Output all of the link set attributes ?
|
||||
* @return void
|
||||
*/
|
||||
public function AddObject($iCode, $sMessage, $oObject, $aFields)
|
||||
public function AddObject($iCode, $sMessage, $oObject, $aFieldSpec = null, $bExtendedOutput = false)
|
||||
{
|
||||
$oObjRes = new ObjectResult(get_class($oObject), $oObject->GetKey());
|
||||
$sClass = get_class($oObject);
|
||||
$oObjRes = new ObjectResult($sClass, $oObject->GetKey());
|
||||
$oObjRes->code = $iCode;
|
||||
$oObjRes->message = $sMessage;
|
||||
|
||||
$aFields = null;
|
||||
if (!is_null($aFieldSpec))
|
||||
{
|
||||
// Enum all classes in the hierarchy, starting with the current one
|
||||
foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false) as $sRefClass)
|
||||
{
|
||||
if (array_key_exists($sRefClass, $aFieldSpec))
|
||||
{
|
||||
$aFields = $aFieldSpec[$sRefClass];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_null($aFields))
|
||||
{
|
||||
// No fieldspec given, or not found...
|
||||
$aFields = array('id', 'friendlyname');
|
||||
}
|
||||
|
||||
foreach ($aFields as $sAttCode)
|
||||
{
|
||||
$oObjRes->AddField($oObject, $sAttCode);
|
||||
$oObjRes->AddField($oObject, $sAttCode, $bExtendedOutput);
|
||||
}
|
||||
|
||||
$sObjKey = get_class($oObject).'::'.$oObject->GetKey();
|
||||
@@ -265,6 +286,10 @@ class CoreServices implements iRestServiceProvider
|
||||
'verb' => 'core/get_related',
|
||||
'description' => 'Get related objects through the specified relation'
|
||||
);
|
||||
$aOps[] = array(
|
||||
'verb' => 'core/check_credentials',
|
||||
'description' => 'Check user credentials'
|
||||
);
|
||||
}
|
||||
return $aOps;
|
||||
}
|
||||
@@ -285,11 +310,12 @@ class CoreServices implements iRestServiceProvider
|
||||
$sClass = RestUtils::GetClass($aParams, 'class');
|
||||
$aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
|
||||
$aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
|
||||
$bExtendedOutput = (RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+');
|
||||
|
||||
$oObject = RestUtils::MakeObjectFromFields($sClass, $aFields);
|
||||
$oObject->DBInsert();
|
||||
|
||||
$oResult->AddObject(0, 'created', $oObject, $aShowFields);
|
||||
$oResult->AddObject(0, 'created', $oObject, $aShowFields, $bExtendedOutput);
|
||||
break;
|
||||
|
||||
case 'core/update':
|
||||
@@ -298,12 +324,13 @@ class CoreServices implements iRestServiceProvider
|
||||
$key = RestUtils::GetMandatoryParam($aParams, 'key');
|
||||
$aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
|
||||
$aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
|
||||
$bExtendedOutput = (RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+');
|
||||
|
||||
$oObject = RestUtils::FindObjectFromKey($sClass, $key);
|
||||
RestUtils::UpdateObjectFromFields($oObject, $aFields);
|
||||
$oObject->DBUpdate();
|
||||
|
||||
$oResult->AddObject(0, 'updated', $oObject, $aShowFields);
|
||||
$oResult->AddObject(0, 'updated', $oObject, $aShowFields, $bExtendedOutput);
|
||||
break;
|
||||
|
||||
case 'core/apply_stimulus':
|
||||
@@ -312,6 +339,7 @@ class CoreServices implements iRestServiceProvider
|
||||
$key = RestUtils::GetMandatoryParam($aParams, 'key');
|
||||
$aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
|
||||
$aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
|
||||
$bExtendedOutput = (RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+');
|
||||
$sStimulus = RestUtils::GetMandatoryParam($aParams, 'stimulus');
|
||||
|
||||
$oObject = RestUtils::FindObjectFromKey($sClass, $key);
|
||||
@@ -347,7 +375,7 @@ class CoreServices implements iRestServiceProvider
|
||||
if ($oObject->ApplyStimulus($sStimulus))
|
||||
{
|
||||
$oObject->DBUpdate();
|
||||
$oResult->AddObject(0, 'updated', $oObject, $aShowFields);
|
||||
$oResult->AddObject(0, 'updated', $oObject, $aShowFields, $bExtendedOutput);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -363,11 +391,12 @@ class CoreServices implements iRestServiceProvider
|
||||
$sClass = RestUtils::GetClass($aParams, 'class');
|
||||
$key = RestUtils::GetMandatoryParam($aParams, 'key');
|
||||
$aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
|
||||
$bExtendedOutput = (RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+');
|
||||
|
||||
$oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
$oResult->AddObject(0, '', $oObject, $aShowFields);
|
||||
$oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
|
||||
}
|
||||
$oResult->message = "Found: ".$oObjectSet->Count();
|
||||
break;
|
||||
@@ -388,7 +417,6 @@ class CoreServices implements iRestServiceProvider
|
||||
$key = RestUtils::GetMandatoryParam($aParams, 'key');
|
||||
$sRelation = RestUtils::GetMandatoryParam($aParams, 'relation');
|
||||
$iMaxRecursionDepth = RestUtils::GetOptionalParam($aParams, 'depth', 20 /* = MAX_RECURSION_DEPTH */);
|
||||
$aShowFields = array('id', 'friendlyname');
|
||||
|
||||
$oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
|
||||
$aIndexByClass = array();
|
||||
@@ -397,7 +425,7 @@ class CoreServices implements iRestServiceProvider
|
||||
$aRelated = array();
|
||||
$aGraph = array();
|
||||
$aIndexByClass[get_class($oObject)][$oObject->GetKey()] = null;
|
||||
$oResult->AddObject(0, '', $oObject, $aShowFields);
|
||||
$oResult->AddObject(0, '', $oObject);
|
||||
$this->GetRelatedObjects($oObject, $sRelation, $iMaxRecursionDepth, $aRelated, $aGraph);
|
||||
|
||||
foreach($aRelated as $sClass => $aObjects)
|
||||
@@ -405,7 +433,7 @@ class CoreServices implements iRestServiceProvider
|
||||
foreach($aObjects as $oRelatedObj)
|
||||
{
|
||||
$aIndexByClass[get_class($oRelatedObj)][$oRelatedObj->GetKey()] = null;
|
||||
$oResult->AddObject(0, '', $oRelatedObj, $aShowFields);
|
||||
$oResult->AddObject(0, '', $oRelatedObj);
|
||||
}
|
||||
}
|
||||
foreach($aGraph as $sSrcKey => $aDestinations)
|
||||
@@ -431,6 +459,21 @@ class CoreServices implements iRestServiceProvider
|
||||
}
|
||||
break;
|
||||
|
||||
case 'core/check_credentials':
|
||||
$oResult = new RestResult();
|
||||
$sUser = RestUtils::GetMandatoryParam($aParams, 'user');
|
||||
$sPassword = RestUtils::GetMandatoryParam($aParams, 'password');
|
||||
|
||||
if (UserRights::CheckCredentials($sUser, $sPassword) !== true)
|
||||
{
|
||||
$oResult->authorized = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oResult->authorized = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// unknown operation: handled at a higher level
|
||||
}
|
||||
@@ -503,7 +546,7 @@ class CoreServices implements iRestServiceProvider
|
||||
$sPlanned = 'Must be deleted explicitely';
|
||||
}
|
||||
}
|
||||
$oResult->AddObject($iCode, $sPlanned, $oToDelete, array('id', 'friendlyname'));
|
||||
$oResult->AddObject($iCode, $sPlanned, $oToDelete);
|
||||
}
|
||||
}
|
||||
foreach ($oDeletionPlan->ListUpdates() as $sRemoteClass => $aToUpdate)
|
||||
@@ -521,7 +564,7 @@ class CoreServices implements iRestServiceProvider
|
||||
$iCode = RestDelete::AUTO_UPDATE;
|
||||
$sPlanned = 'Reset external keys: '.$aData['attributes_list'];
|
||||
}
|
||||
$oResult->AddObject($iCode, $sPlanned, $oToUpdate, array('id', 'friendlyname'));
|
||||
$oResult->AddObject($iCode, $sPlanned, $oToUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ abstract class Trigger extends cmdbAbstractObject
|
||||
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
// Find the related
|
||||
// Find the related actions
|
||||
$oLinkedActions = $this->Get('action_list');
|
||||
while ($oLink = $oLinkedActions->Fetch())
|
||||
{
|
||||
@@ -109,16 +109,40 @@ abstract class TriggerOnObject extends Trigger
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("target_class", array("class_category"=>"bizmodel", "more_values"=>null, "sql"=>"target_class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeClass("target_class", array("class_category"=>"bizmodel", "more_values"=>"User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql"=>"target_class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values"=>null, "sql"=>"filter", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
|
||||
|
||||
public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
|
||||
$sFilter = trim($this->Get('filter'));
|
||||
if (strlen($sFilter) > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
|
||||
if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass()))
|
||||
{
|
||||
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterClass', $this->Get('target_class'));
|
||||
}
|
||||
}
|
||||
catch(OqlException $e)
|
||||
{
|
||||
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterQuery', $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given object is in the scope of this trigger
|
||||
* and can potentially be the subject of notifications
|
||||
@@ -128,7 +152,37 @@ abstract class TriggerOnObject extends Trigger
|
||||
public function IsInScope(DBObject $oObject)
|
||||
{
|
||||
$sRootClass = $this->Get('target_class');
|
||||
return ($oObject instanceof $sRootClass);
|
||||
return ($oObject instanceof $sRootClass);
|
||||
}
|
||||
|
||||
public function DoActivate($aContextArgs)
|
||||
{
|
||||
$bGo = true;
|
||||
if (isset($aContextArgs['this->id']))
|
||||
{
|
||||
$bGo = $this->IsTargetObject($aContextArgs['this->id']);
|
||||
}
|
||||
if ($bGo)
|
||||
{
|
||||
parent::DoActivate($aContextArgs);
|
||||
}
|
||||
}
|
||||
|
||||
public function IsTargetObject($iObjectId)
|
||||
{
|
||||
$sFilter = trim($this->Get('filter'));
|
||||
if (strlen($sFilter) > 0)
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL($sFilter);
|
||||
$oSearch->AddCondition('id', $iObjectId, '=');
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$bRet = ($oSet->Count() > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bRet = true;
|
||||
}
|
||||
return $bRet;
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -154,7 +208,7 @@ class TriggerOnPortalUpdate extends TriggerOnObject
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
}
|
||||
@@ -181,7 +235,7 @@ abstract class TriggerOnStateChange extends TriggerOnObject
|
||||
MetaModel::Init_AddAttribute(new AttributeString("state", array("allowed_values"=>null, "sql"=>"state", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
@@ -209,7 +263,7 @@ class TriggerOnStateEnter extends TriggerOnStateChange
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
@@ -237,7 +291,7 @@ class TriggerOnStateLeave extends TriggerOnStateChange
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
|
||||
@@ -265,7 +319,7 @@ class TriggerOnObjectCreate extends TriggerOnObject
|
||||
MetaModel::Init_InheritAttributes();
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
|
||||
|
||||
@@ -382,14 +382,34 @@ class ValueSetEnumClasses extends ValueSetEnum
|
||||
}
|
||||
|
||||
protected function LoadValues($aArgs)
|
||||
{
|
||||
// First, get the additional values
|
||||
{
|
||||
// Call the parent to parse the additional values...
|
||||
parent::LoadValues($aArgs);
|
||||
|
||||
// Translate the labels of the additional values
|
||||
foreach($this->m_aValues as $sClass => $void)
|
||||
{
|
||||
if (MetaModel::IsValidClass($sClass))
|
||||
{
|
||||
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($this->m_aValues[$sClass]);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, add the classes from the category definition
|
||||
foreach (MetaModel::GetClasses($this->m_sCategories) as $sClass)
|
||||
{
|
||||
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
|
||||
if (MetaModel::IsValidClass($sClass))
|
||||
{
|
||||
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($this->m_aValues[$sClass]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -16,36 +16,17 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @author Stephan Rosenke <stephan.rosenke@itomig.de>
|
||||
* @author Stephan Rosenke <stephan.rosenke@itomig.de>
|
||||
* @author David M. Gümbel <david.guembel@itomig.de>
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:UserLocal' => 'iTop-Benutzer',
|
||||
'Class:UserLocal+' => 'Benutzer von iTop authentifiziert',
|
||||
'Class:UserLocal/Attribute:password' => 'Passwort',
|
||||
'Class:UserLocal/Attribute:password+' => 'Benutzerpasswort',
|
||||
));
|
||||
|
||||
|
||||
|
||||
?>
|
||||
?>
|
||||
51
datamodels/1.x/authent-local/es_cr.dict.authent-local.php
Normal file
51
datamodels/1.x/authent-local/es_cr.dict.authent-local.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2013 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2013 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:UserLocal' => 'Usuario de iTop',
|
||||
'Class:UserLocal+' => 'Usuario Autenticado vía iTop',
|
||||
'Class:UserLocal/Attribute:password' => 'Contraseña',
|
||||
'Class:UserLocal/Attribute:password+' => 'Contraseña',
|
||||
));
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,51 +1,32 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @author Hirofumi Kosaka <kosaka@rworks.jp>
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Class:UserLocal' => 'iTopユーザー', // 'iTop user',
|
||||
'Class:UserLocal+' => 'iTopローカル認証ユーザー', // 'User authentified by iTop',
|
||||
'Class:UserLocal/Attribute:password' => 'パスワード', // 'Password',
|
||||
'Class:UserLocal/Attribute:password+' => '認証文字列', // 'user authentication string',
|
||||
));
|
||||
|
||||
|
||||
|
||||
?>
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Hirofumi Kosaka <kosaka@rworks.jp>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Class:UserLocal' => 'iTopユーザー',
|
||||
'Class:UserLocal+' => 'iTopローカル認証ユーザー',
|
||||
'Class:UserLocal/Attribute:password' => 'パスワード',
|
||||
'Class:UserLocal/Attribute:password+' => '認証文字列',
|
||||
));
|
||||
?>
|
||||
@@ -74,7 +74,10 @@ class UserLocal extends UserInternal
|
||||
|
||||
public function CanChangePassword()
|
||||
{
|
||||
// For now everyone can change their password..
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,18 +88,47 @@ class UserLocal extends UserInternal
|
||||
// Let's ask the password to compare the hashed values
|
||||
if ($oPassword->CheckPassword($sOldPassword))
|
||||
{
|
||||
$this->Set('password', $sNewPassword);
|
||||
$oChange = MetaModel::NewObject("CMDBChange");
|
||||
$oChange->Set("date", time());
|
||||
$sUserString = CMDBChange::GetCurrentUserName();
|
||||
$oChange->Set("userinfo", $sUserString);
|
||||
$oChange->DBInsert();
|
||||
$this->DBUpdateTracked($oChange, true);
|
||||
$this->SetPassword($sNewPassword);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use with care!
|
||||
*/
|
||||
public function SetPassword($sNewPassword)
|
||||
{
|
||||
$this->Set('password', $sNewPassword);
|
||||
$oChange = MetaModel::NewObject("CMDBChange");
|
||||
$oChange->Set("date", time());
|
||||
$sUserString = CMDBChange::GetCurrentUserName();
|
||||
$oChange->Set("userinfo", $sUserString);
|
||||
$oChange->DBInsert();
|
||||
$this->DBUpdateTracked($oChange, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of flags (OPT_ATT_HIDDEN, OPT_ATT_READONLY, OPT_ATT_MANDATORY...)
|
||||
* for the given attribute in the current state of the object
|
||||
* @param $sAttCode string $sAttCode The code of the attribute
|
||||
* @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);
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
if (strpos('contactid,login,language,password,profile_list,allowed_org_list', $sAttCode) !== false)
|
||||
{
|
||||
// contactid and allowed_org_list are disabled to make sure the portal remains accessible
|
||||
$aReasons[] = 'Sorry, this attribute is read-only in the demonstration mode!';
|
||||
$iFlags |= OPT_ATT_READONLY;
|
||||
}
|
||||
}
|
||||
return $iFlags;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -17,32 +17,16 @@
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:UserLocal' => 'Пользователь iTop',
|
||||
'Class:UserLocal+' => 'Пользователь аутентифицированный iTop',
|
||||
'Class:UserLocal/Attribute:password' => 'Пароль',
|
||||
'Class:UserLocal/Attribute:password+' => 'строка аутентификации пользователя',
|
||||
));
|
||||
|
||||
?>
|
||||
?>
|
||||
@@ -56,7 +56,7 @@ class ItopWelcome extends ModuleHandlerAPI
|
||||
new WebPageMenuNode('NotificationsMenu', utils::GetAbsoluteUrlAppRoot().'pages/notifications.php', $oAdminMenu->GetIndex(), 3 /* fRank */);
|
||||
new OQLMenuNode('AuditCategories', 'SELECT AuditCategory', $oAdminMenu->GetIndex(), 4 /* fRank */);
|
||||
new WebPageMenuNode('RunQueriesMenu', utils::GetAbsoluteUrlAppRoot().'pages/run_query.php', $oAdminMenu->GetIndex(), 8 /* fRank */);
|
||||
new OQLMenuNode('QueryMenu', 'SELECT Query', $oAdminMenu->GetIndex(), 8.5 /* fRank */);
|
||||
new OQLMenuNode('QueryMenu', 'SELECT Query', $oAdminMenu->GetIndex(), 8.5 /* fRank */, true);
|
||||
new WebPageMenuNode('ExportMenu', utils::GetAbsoluteUrlAppRoot().'webservices/export.php', $oAdminMenu->GetIndex(), 9 /* fRank */);
|
||||
new WebPageMenuNode('DataModelMenu', utils::GetAbsoluteUrlAppRoot().'pages/schema.php', $oAdminMenu->GetIndex(), 10 /* fRank */);
|
||||
new WebPageMenuNode('UniversalSearchMenu', utils::GetAbsoluteUrlAppRoot().'pages/UniversalSearch.php', $oAdminMenu->GetIndex(), 11 /* fRank */);
|
||||
|
||||
@@ -1,30 +1,43 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserExternal
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:UserExternal' => 'Внешний пользователь',
|
||||
'Class:UserExternal+' => 'Пользователь аутентифицированный вне iTop',
|
||||
'Class:UserExternal+' => 'Пользователь, аутентифицированный вне iTop',
|
||||
));
|
||||
?>
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -166,7 +166,7 @@ class UserLDAP extends UserInternal
|
||||
|
||||
protected function LogMessage($sMessage, $aData = array())
|
||||
{
|
||||
if (MetaModel::IsLogEnabledIssue())
|
||||
if (MetaModel::GetModuleSetting('authent-ldap', 'debug', false) && MetaModel::IsLogEnabledIssue())
|
||||
{
|
||||
if (MetaModel::IsValidClass('EventIssue'))
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@ SetupWebPage::AddModule(
|
||||
LDAP_OPT_PROTOCOL_VERSION => 3,
|
||||
LDAP_OPT_REFERRALS => 0,
|
||||
),
|
||||
'debug' => false,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,32 +1,45 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLDAP
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:UserLDAP' => 'Пользователь LDAP',
|
||||
'Class:UserLDAP+' => 'Пользователь аутентифицированный в LDAP',
|
||||
'Class:UserLDAP+' => 'Пользователь, аутентифицированный в LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Пароль',
|
||||
'Class:UserLDAP/Attribute:password+' => 'строка аутентификации пользователя',
|
||||
'Class:UserLDAP/Attribute:password+' => 'Строка аутентификации пользователя',
|
||||
));
|
||||
?>
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,32 +1,45 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:UserLocal' => 'Пользователь iTop',
|
||||
'Class:UserLocal+' => 'Пользователь аутентифицированный iTop',
|
||||
'Class:UserLocal+' => 'Пользователь, аутентифицированный в iTop',
|
||||
'Class:UserLocal/Attribute:password' => 'Пароль',
|
||||
'Class:UserLocal/Attribute:password+' => 'строка аутентификации пользователя',
|
||||
'Class:UserLocal/Attribute:password+' => 'Строка аутентификации пользователя',
|
||||
));
|
||||
?>
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
<attribute id="item_id"/>
|
||||
</attributes>
|
||||
</index>
|
||||
<index id="3">
|
||||
<attributes>
|
||||
<attribute id="item_org_id"/>
|
||||
</attributes>
|
||||
</index>
|
||||
</indexes>
|
||||
</properties>
|
||||
<fields>
|
||||
|
||||
@@ -225,6 +225,10 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
|
||||
.btn_hidden {
|
||||
display: none;
|
||||
}
|
||||
.drag_in {
|
||||
-webkit-box-shadow:inset 0 0 10px 2px #1C94C4;
|
||||
box-shadow:inset 0 0 10px 2px #1C94C4;
|
||||
}
|
||||
EOF
|
||||
);
|
||||
$oPage->add('<fieldset>');
|
||||
@@ -239,7 +243,7 @@ EOF
|
||||
$sDeleteBtn = Dict::S('Attachments:DeleteBtn');
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
function RemoveNewAttachment(att_id)
|
||||
function RemoveAttachment(att_id)
|
||||
{
|
||||
$('#attachment_'+att_id).attr('name', 'removed_attachments[]');
|
||||
$('#display_attachment_'+att_id).hide();
|
||||
@@ -283,7 +287,7 @@ EOF
|
||||
else
|
||||
{
|
||||
var sDownloadLink = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=download_document&class=Attachment&id='+data.att_id+'&field=contents';
|
||||
$('#attachments').append('<div class="attachment" id="display_attachment_'+data.att_id+'"><a data-preview="'+data.preview+'" href="'+sDownloadLink+'"><img src="'+data.icon+'"><br/>'+data.msg+'<input id="attachment_'+data.att_id+'" type="hidden" name="attachments[]" value="'+data.att_id+'"/></a><br/><input type="button" class="btn_hidden" value="{$sDeleteBtn}" onClick="RemoveNewAttachment('+data.att_id+');"/></div>');
|
||||
$('#attachments').append('<div class="attachment" id="display_attachment_'+data.att_id+'"><a data-preview="'+data.preview+'" href="'+sDownloadLink+'"><img src="'+data.icon+'"><br/>'+data.msg+'<input id="attachment_'+data.att_id+'" type="hidden" name="attachments[]" value="'+data.att_id+'"/></a><br/><input type="button" class="btn_hidden" value="{$sDeleteBtn}" onClick="RemoveAttachment('+data.att_id+');"/></div>');
|
||||
if($sIsDeleteEnabled)
|
||||
{
|
||||
$('#display_attachment_'+data.att_id).hover( function() { $(this).children(':button').toggleClass('btn_hidden'); } );
|
||||
@@ -315,7 +319,7 @@ EOF
|
||||
$sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName);
|
||||
$sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
|
||||
$sDownloadLink = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=download_document&class=Attachment&id='.$iAttId.'&field=contents';
|
||||
$oPage->add('<div class="attachment" id="attachment_'.$iAttId.'"><a data-preview="'.$sPreview.'" href="'.$sDownloadLink.'"><img src="'.$sIcon.'"><br/>'.$sFileName.'<input type="hidden" name="attachments[]" value="'.$iAttId.'"/></a><br/> <input id="btn_remove_'.$iAttId.'" type="button" class="btn_hidden" value="Delete" onClick="$(\'#attachment_'.$iAttId.'\').remove();"/> </div>');
|
||||
$oPage->add('<div class="attachment" id="display_attachment_'.$iAttId.'"><a data-preview="'.$sPreview.'" href="'.$sDownloadLink.'"><img src="'.$sIcon.'"><br/>'.$sFileName.'<input id="attachment_'.$iAttId.'" type="hidden" name="attachments[]" value="'.$iAttId.'"/></a><br/> <input id="btn_remove_'.$iAttId.'" type="button" class="btn_hidden" value="Delete" onClick="RemoveAttachment('.$iAttId.');"/> </div>');
|
||||
}
|
||||
|
||||
// Suggested attachments are listed here but treated as temporary
|
||||
@@ -343,7 +347,7 @@ EOF
|
||||
$sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName);
|
||||
$sDownloadLink = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=download_document&class=Attachment&id='.$iAttId.'&field=contents';
|
||||
$sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
|
||||
$oPage->add('<div class="attachment" id="display_attachment_'.$iAttId.'"><a data-preview="'.$sPreview.'" href="'.$sDownloadLink.'"><img src="'.$sIcon.'"><br/>'.$sFileName.'<input type="hidden" name="attachments[]" value="'.$iAttId.'"/></a><br/> <input id="btn_remove_'.$iAttId.'" type="button" class="btn_hidden" value="Delete" onClick="RemoveNewAttachment('.$iAttId.');"/> </div>');
|
||||
$oPage->add('<div class="attachment" id="display_attachment_'.$iAttId.'"><a data-preview="'.$sPreview.'" href="'.$sDownloadLink.'"><img src="'.$sIcon.'"><br/>'.$sFileName.'<input id="attachment_'+data.result.att_id+'" type="hidden" name="attachments[]" value="'.$iAttId.'"/></a><br/> <input id="btn_remove_'.$iAttId.'" type="button" class="btn_hidden" value="Delete" onClick="RemoveAttachment('.$iAttId.');"/> </div>');
|
||||
$oPage->add_ready_script("$('#attachment_plugin').trigger('add_attachment', [$iAttId, '".addslashes($sFileName)."']);");
|
||||
}
|
||||
}
|
||||
@@ -352,7 +356,88 @@ EOF
|
||||
$oPage->add('</span>');
|
||||
$oPage->add('<div style="clear:both"></div>');
|
||||
$sMaxUpload = $this->GetMaxUpload();
|
||||
$oPage->p(Dict::S('Attachments:AddAttachment').'<input type="file" name="file" id="file" onChange="ajaxFileUpload();"><span style="display:none;" id="attachment_loading"> <img src="../images/indicator.gif"></span> '.$sMaxUpload);
|
||||
// $oPage->p(Dict::S('Attachments:AddAttachment').'<input type="file" name="file" id="file" onChange="ajaxFileUpload();"><span style="display:none;" id="attachment_loading"> <img src="../images/indicator.gif"></span> '.$sMaxUpload);
|
||||
$oPage->p(Dict::S('Attachments:AddAttachment').'<input type="file" name="file" id="file"><span style="display:none;" id="attachment_loading"> <img src="../images/indicator.gif"></span> '.$sMaxUpload);
|
||||
|
||||
$oPage->add_linked_script('../js/jquery.iframe-transport.js');
|
||||
$oPage->add_linked_script('../js/jquery.fileupload.js');
|
||||
|
||||
$oPage->add_ready_script(
|
||||
<<< EOF
|
||||
$('#file').fileupload({
|
||||
url: GetAbsoluteUrlModulesRoot()+'itop-attachments/ajax.attachment.php',
|
||||
formData: { operation: 'add', temp_id: '$sTempId', obj_class: '$sClass' },
|
||||
dataType: 'json',
|
||||
done: function (e, data) {
|
||||
if(typeof(data.result.error) != 'undefined')
|
||||
{
|
||||
if(data.result.error != '')
|
||||
{
|
||||
alert(data.result.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sDownloadLink = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=download_document&class=Attachment&id='+data.result.att_id+'&field=contents';
|
||||
$('#attachments').append('<div class="attachment" id="display_attachment_'+data.result.att_id+'"><a data-preview="'+data.result.preview+'" href="'+sDownloadLink+'"><img src="'+data.result.icon+'"><br/>'+data.result.msg+'<input id="attachment_'+data.result.att_id+'" type="hidden" name="attachments[]" value="'+data.result.att_id+'"/></a><br/><input type="button" class="btn_hidden" value="{$sDeleteBtn}" onClick="RemoveAttachment('+data.result.att_id+');"/></div>');
|
||||
if($sIsDeleteEnabled)
|
||||
{
|
||||
$('#display_attachment_'+data.result.att_id).hover( function() { $(this).children(':button').toggleClass('btn_hidden'); } );
|
||||
}
|
||||
$('#attachment_plugin').trigger('add_attachment', [data.result.att_id, data.msg]);
|
||||
}
|
||||
}
|
||||
},
|
||||
start: function() {
|
||||
$('#attachment_loading').show();
|
||||
},
|
||||
stop: function() {
|
||||
$('#attachment_loading').hide();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).bind('dragover', function (e) {
|
||||
var bFiles = false;
|
||||
|
||||
if (e.dataTransfer.types)
|
||||
{
|
||||
for (var i = 0; i < e.dataTransfer.types.length; i++)
|
||||
{
|
||||
if (e.dataTransfer.types[i] == "text/plain")
|
||||
{
|
||||
bFiles = false; // mozilla contains "Files" in the types list when dragging images inside the page, but it also contains "text/plain" before
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.dataTransfer.types[i] == "Files")
|
||||
{
|
||||
bFiles = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFiles) return; // Not dragging files
|
||||
|
||||
var dropZone = $('#file').closest('fieldset');
|
||||
if (!dropZone.is(':visible'))
|
||||
{
|
||||
// Hidden, but inside an inactive tab? Higlight the tab
|
||||
var sTabId = dropZone.closest('.ui-tabs-panel').attr('aria-labelledby');
|
||||
dropZone = $('#'+sTabId).closest('li');
|
||||
}
|
||||
timeout = window.dropZoneTimeout;
|
||||
if (!timeout) {
|
||||
dropZone.addClass('drag_in');
|
||||
} else {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
window.dropZoneTimeout = setTimeout(function () {
|
||||
window.dropZoneTimeout = null;
|
||||
dropZone.removeClass('drag_in');
|
||||
}, 300);
|
||||
});
|
||||
EOF
|
||||
);
|
||||
$oPage->p('<span style="display:none;" id="attachment_loading">Loading, please wait...</span>');
|
||||
$oPage->p('<input type="hidden" id="attachment_plugin" name="attachment_plugin"/>');
|
||||
$oPage->add('</fieldset>');
|
||||
@@ -401,14 +486,15 @@ EOF
|
||||
{
|
||||
$aActions = array();
|
||||
$aAttachmentIds = utils::ReadParam('attachments', array());
|
||||
|
||||
$aRemovedAttachmentIds = utils::ReadParam('removed_attachments', array());
|
||||
|
||||
// Get all current attachments
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
|
||||
while ($oAttachment = $oSet->Fetch())
|
||||
{
|
||||
// Remove attachments that are no longer attached to the current object
|
||||
if (!in_array($oAttachment->GetKey(), $aAttachmentIds))
|
||||
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentIds))
|
||||
{
|
||||
$oAttachment->DBDelete();
|
||||
$aActions[] = self::GetActionDescription($oAttachment, false /* false => deletion */);
|
||||
@@ -419,7 +505,6 @@ EOF
|
||||
$sTempId = session_id().'_'.$iTransactionId;
|
||||
// The object is being created from a form, check if there are pending attachments
|
||||
// for this object, but deleting the "new" ones that were already removed from the form
|
||||
$aRemovedAttachmentIds = utils::ReadParam('removed_attachments', array());
|
||||
$sOQL = 'SELECT Attachment WHERE temp_id = :temp_id';
|
||||
$oSearch = DBObjectSearch::FromOQL($sOQL);
|
||||
foreach($aAttachmentIds as $iAttachmentId)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Attachments:TabTitle_Count' => 'Anexos (%1$d)',
|
||||
'Attachments:EmptyTabTitle' => 'Anexos',
|
||||
'Attachments:FieldsetTitle' => 'Anexos',
|
||||
'Attachments:DeleteBtn' => 'Excluir',
|
||||
'Attachments:History_File_Added' => 'Anexo %1$s adicionado.',
|
||||
'Attachments:History_File_Removed' => 'Anexo %1$s excluído.',
|
||||
'Attachments:AddAttachment' => 'Adicionar anexo: ',
|
||||
'Attachments:UploadNotAllowedOnThisSystem' => 'Arquivo carregado NÃO PERMITIDO pelo sistema.',
|
||||
'Attachment:Max_Go' => '(Tamanho máximo arquivo: %1$s Gb)',
|
||||
'Attachment:Max_Mo' => '(Tamanho máximo arquivo: %1$s Mb)',
|
||||
'Attachment:Max_Ko' => '(Tamanho máximo arquivo: %1$s Kb)',
|
||||
'Attachments:NoAttachment' => 'Nenhum anexo. ',
|
||||
));
|
||||
?>
|
||||
@@ -932,20 +932,6 @@
|
||||
$this->Set('last_update', time());
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="ComputeValues">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public function ComputeValues()
|
||||
{
|
||||
if ($this->IsNew())
|
||||
{
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
$sName = sprintf('C-%06d', $iKey);
|
||||
$this->Set('ref', $sName);
|
||||
}
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="GetIcon">
|
||||
<comment>/**
|
||||
* Get the icon representing this object
|
||||
|
||||
@@ -1,126 +1,64 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:RoutineChange' => 'Регулярное изменение',
|
||||
'Class:RoutineChange+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_validate' => 'Проверить',
|
||||
'Class:RoutineChange/Stimulus:ev_validate+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_reject' => 'Reject~~',
|
||||
'Class:RoutineChange/Stimulus:ev_reject+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:RoutineChange/Stimulus:ev_assign+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_reopen' => 'Переоткрыть',
|
||||
'Class:RoutineChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:RoutineChange/Stimulus:ev_plan+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_approve' => 'Approve~~',
|
||||
'Class:RoutineChange/Stimulus:ev_approve+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_replan' => 'Перепланировать',
|
||||
'Class:RoutineChange/Stimulus:ev_replan+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove' => 'Do Not Approve~~',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:RoutineChange/Stimulus:ev_implement+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_monitor' => 'Контролировать',
|
||||
'Class:RoutineChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:RoutineChange/Stimulus:ev_finish+' => '',
|
||||
'Class:NormalChange' => 'Обычное изменение',
|
||||
'Class:NormalChange+' => '',
|
||||
'Class:NormalChange/Attribute:acceptance_date' => 'Дата принятия',
|
||||
'Class:NormalChange/Attribute:acceptance_date+' => '',
|
||||
'Class:NormalChange/Attribute:acceptance_comment' => 'Коментарий принятия',
|
||||
'Class:NormalChange/Attribute:acceptance_comment+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_validate' => 'Проверить',
|
||||
'Class:NormalChange/Stimulus:ev_validate+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:NormalChange/Stimulus:ev_reject+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:NormalChange/Stimulus:ev_assign+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_reopen' => 'Переоткрыть',
|
||||
'Class:NormalChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:NormalChange/Stimulus:ev_plan+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:NormalChange/Stimulus:ev_approve+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_replan' => 'Перепланировать',
|
||||
'Class:NormalChange/Stimulus:ev_replan+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_notapprove' => 'Отклонить утверждение',
|
||||
'Class:NormalChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:NormalChange/Stimulus:ev_implement+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_monitor' => 'Контролировать',
|
||||
'Class:NormalChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:NormalChange/Stimulus:ev_finish+' => '',
|
||||
'Class:EmergencyChange' => 'Критическое изменение',
|
||||
'Class:EmergencyChange+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_validate' => 'Проверить',
|
||||
'Class:EmergencyChange/Stimulus:ev_validate+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:EmergencyChange/Stimulus:ev_reject+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:EmergencyChange/Stimulus:ev_assign+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_reopen' => 'Переоткрыть',
|
||||
'Class:EmergencyChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:EmergencyChange/Stimulus:ev_plan+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:EmergencyChange/Stimulus:ev_approve+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_replan' => 'Перепланировать',
|
||||
'Class:EmergencyChange/Stimulus:ev_replan+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_notapprove' => 'Отклонить утверждение',
|
||||
'Class:EmergencyChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:EmergencyChange/Stimulus:ev_implement+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_monitor' => 'Контролировать',
|
||||
'Class:EmergencyChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:EmergencyChange/Stimulus:ev_finish+' => '',
|
||||
'Menu:ChangeManagement' => 'Управление изменениями',
|
||||
'Menu:Change:Overview' => 'Обзор',
|
||||
'Menu:Change:Overview+' => '',
|
||||
'Menu:NewChange' => 'Новые изменения',
|
||||
'Menu:NewChange' => 'Новый запрос на изменение',
|
||||
'Menu:NewChange+' => 'Создание нового запроса на изменение',
|
||||
'Menu:SearchChanges' => 'Поиск изменений',
|
||||
'Menu:SearchChanges+' => 'Поиск запросов на изменения',
|
||||
'Menu:SearchChanges+' => 'Поиск запросов на изменение',
|
||||
'Menu:Change:Shortcuts' => 'Ярлыки',
|
||||
'Menu:Change:Shortcuts+' => '',
|
||||
'Menu:WaitingAcceptance' => 'Изменения ожидающие принятия',
|
||||
'Menu:WaitingAcceptance' => 'Изменения, ожидающие принятия',
|
||||
'Menu:WaitingAcceptance+' => '',
|
||||
'Menu:WaitingApproval' => 'Изменения ожидающие утверждения',
|
||||
'Menu:WaitingApproval' => 'Изменения, ожидающие утверждения',
|
||||
'Menu:WaitingApproval+' => '',
|
||||
'Menu:Changes' => 'Открытые изменения',
|
||||
'Menu:Changes+' => '',
|
||||
'Menu:MyChanges' => 'Изменения назначенные на меня',
|
||||
'Menu:MyChanges+' => 'Изменения назначенные на меня (как агент)',
|
||||
'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~~',
|
||||
'Menu:Changes+' => 'Все открытые изменения',
|
||||
'Menu:MyChanges' => 'Изменения, назначенные на меня',
|
||||
'Menu:MyChanges+' => 'Изменения, назначенные на меня (как агента)',
|
||||
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Изменения по категориям за 7 дней',
|
||||
'UI-ChangeManagementOverview-Last-7-days' => 'Количество изменений за 7 дней',
|
||||
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Изменения по домену за 7 дней',
|
||||
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Изменения по статусу за 7 дней',
|
||||
));
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
|
||||
//
|
||||
// Class: Change
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Change' => 'Изменение',
|
||||
'Class:Change+' => '',
|
||||
'Class:Change/Attribute:status' => 'Статус',
|
||||
@@ -133,15 +71,15 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Change/Attribute:status/Value:rejected+' => '',
|
||||
'Class:Change/Attribute:status/Value:assigned' => 'Назначен',
|
||||
'Class:Change/Attribute:status/Value:assigned+' => '',
|
||||
'Class:Change/Attribute:status/Value:plannedscheduled' => 'Намечен и запланирован',
|
||||
'Class:Change/Attribute:status/Value:plannedscheduled' => 'Запланирован',
|
||||
'Class:Change/Attribute:status/Value:plannedscheduled+' => '',
|
||||
'Class:Change/Attribute:status/Value:approved' => 'Утверждён',
|
||||
'Class:Change/Attribute:status/Value:approved+' => '',
|
||||
'Class:Change/Attribute:status/Value:notapproved' => 'Не утверждём',
|
||||
'Class:Change/Attribute:status/Value:notapproved' => 'Не утверждён',
|
||||
'Class:Change/Attribute:status/Value:notapproved+' => '',
|
||||
'Class:Change/Attribute:status/Value:implemented' => 'Реализован',
|
||||
'Class:Change/Attribute:status/Value:implemented+' => '',
|
||||
'Class:Change/Attribute:status/Value:monitored' => 'Контролируемый',
|
||||
'Class:Change/Attribute:status/Value:monitored' => 'Под наблюдением',
|
||||
'Class:Change/Attribute:status/Value:monitored+' => '',
|
||||
'Class:Change/Attribute:status/Value:closed' => 'Закрыт',
|
||||
'Class:Change/Attribute:status/Value:closed+' => '',
|
||||
@@ -149,59 +87,61 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Change/Attribute:reason+' => '',
|
||||
'Class:Change/Attribute:requestor_id' => 'Инициатор запроса',
|
||||
'Class:Change/Attribute:requestor_id+' => '',
|
||||
'Class:Change/Attribute:requestor_email' => 'Инициатор запроса',
|
||||
'Class:Change/Attribute:requestor_email' => 'Email инициатора запроса',
|
||||
'Class:Change/Attribute:requestor_email+' => '',
|
||||
'Class:Change/Attribute:creation_date' => 'Создан',
|
||||
'Class:Change/Attribute:creation_date+' => '',
|
||||
'Class:Change/Attribute:impact' => 'Воздействие',
|
||||
'Class:Change/Attribute:impact' => 'Критичность',
|
||||
'Class:Change/Attribute:impact+' => '',
|
||||
'Class:Change/Attribute:supervisor_group_id' => 'Руководитель команды',
|
||||
'Class:Change/Attribute:supervisor_group_id' => 'Команда наблюдателя',
|
||||
'Class:Change/Attribute:supervisor_group_id+' => '',
|
||||
'Class:Change/Attribute:supervisor_group_name' => 'Руководитель команды',
|
||||
'Class:Change/Attribute:supervisor_group_name' => 'Команда наблюдателя',
|
||||
'Class:Change/Attribute:supervisor_group_name+' => '',
|
||||
'Class:Change/Attribute:supervisor_id' => 'Руководитель',
|
||||
'Class:Change/Attribute:supervisor_id' => 'Наблюдатель',
|
||||
'Class:Change/Attribute:supervisor_id+' => '',
|
||||
'Class:Change/Attribute:supervisor_email' => 'Руководитель',
|
||||
'Class:Change/Attribute:supervisor_email' => 'Email наблюдателя',
|
||||
'Class:Change/Attribute:supervisor_email+' => '',
|
||||
'Class:Change/Attribute:manager_group_id' => 'Менеджер команды',
|
||||
'Class:Change/Attribute:manager_group_id' => 'Команда менеджера',
|
||||
'Class:Change/Attribute:manager_group_id+' => '',
|
||||
'Class:Change/Attribute:manager_group_name' => 'Менеджер команды',
|
||||
'Class:Change/Attribute:manager_group_name' => 'Команда менеджера',
|
||||
'Class:Change/Attribute:manager_group_name+' => '',
|
||||
'Class:Change/Attribute:manager_id' => 'Менеджер',
|
||||
'Class:Change/Attribute:manager_id+' => '',
|
||||
'Class:Change/Attribute:manager_email' => 'Менеджер',
|
||||
'Class:Change/Attribute:manager_email' => 'Email менеджера',
|
||||
'Class:Change/Attribute:manager_email+' => '',
|
||||
'Class:Change/Attribute:outage' => 'Отключение',
|
||||
'Class:Change/Attribute:outage' => 'Простой услуги',
|
||||
'Class:Change/Attribute:outage+' => '',
|
||||
'Class:Change/Attribute:outage/Value:no' => 'Нет',
|
||||
'Class:Change/Attribute:outage/Value:no+' => '',
|
||||
'Class:Change/Attribute:outage/Value:yes' => 'Отключение',
|
||||
'Class:Change/Attribute:outage/Value:yes' => 'Да',
|
||||
'Class:Change/Attribute:outage/Value:yes+' => '',
|
||||
'Class:Change/Attribute:fallback' => 'Резервный план',
|
||||
'Class:Change/Attribute:fallback' => 'План отката',
|
||||
'Class:Change/Attribute:fallback+' => '',
|
||||
'Class:Change/Attribute:parent_id' => 'Parent change~~',
|
||||
'Class:Change/Attribute:parent_id' => 'Родительское изменение',
|
||||
'Class:Change/Attribute:parent_id+' => '',
|
||||
'Class:Change/Attribute:parent_name' => 'Parent change Ref~~',
|
||||
'Class:Change/Attribute:parent_name' => 'Имя родительского изменения',
|
||||
'Class:Change/Attribute:parent_name+' => '',
|
||||
'Class:Change/Attribute:related_request_list' => 'Related requests~~',
|
||||
'Class:Change/Attribute:related_request_list+' => '',
|
||||
'Class:Change/Attribute:related_problems_list' => 'Related problems~~',
|
||||
'Class:Change/Attribute:related_problems_list+' => '',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Child changes~~',
|
||||
'Class:Change/Attribute:child_changes_list+' => '',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent friendly name~~',
|
||||
'Class:Change/Attribute:related_request_list' => 'Связанные запросы',
|
||||
'Class:Change/Attribute:related_request_list+' => 'Связанные запросы',
|
||||
'Class:Change/Attribute:related_problems_list' => 'Связанные проблемы',
|
||||
'Class:Change/Attribute:related_problems_list+' => 'Связанные проблемы',
|
||||
'Class:Change/Attribute:related_incident_list' => 'Связанные инциденты',
|
||||
'Class:Change/Attribute:related_incident_list+' => 'Связанные инциденты',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Дочерние изменения',
|
||||
'Class:Change/Attribute:child_changes_list+' => 'Дочерние изменения',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Родительское изменение',
|
||||
'Class:Change/Attribute:parent_id_friendlyname+' => '',
|
||||
'Class:Change/Attribute:parent_id_finalclass_recall' => 'Change type~~',
|
||||
'Class:Change/Attribute:parent_id_finalclass_recall' => 'Тип изменения',
|
||||
'Class:Change/Attribute:parent_id_finalclass_recall+' => '',
|
||||
'Class:Change/Stimulus:ev_validate' => 'Проверка',
|
||||
'Class:Change/Stimulus:ev_validate' => 'Подтвердить',
|
||||
'Class:Change/Stimulus:ev_validate+' => '',
|
||||
'Class:Change/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:Change/Stimulus:ev_reject+' => '',
|
||||
'Class:Change/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:Change/Stimulus:ev_assign+' => '',
|
||||
'Class:Change/Stimulus:ev_reopen' => 'Переоткрыть',
|
||||
'Class:Change/Stimulus:ev_reopen' => 'Вновь открыть',
|
||||
'Class:Change/Stimulus:ev_reopen+' => '',
|
||||
'Class:Change/Stimulus:ev_plan' => 'План',
|
||||
'Class:Change/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:Change/Stimulus:ev_plan+' => '',
|
||||
'Class:Change/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:Change/Stimulus:ev_approve+' => '',
|
||||
@@ -211,25 +151,63 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Change/Stimulus:ev_notapprove+' => '',
|
||||
'Class:Change/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:Change/Stimulus:ev_implement+' => '',
|
||||
'Class:Change/Stimulus:ev_monitor' => 'Наблюдение',
|
||||
'Class:Change/Stimulus:ev_monitor' => 'Наблюдать',
|
||||
'Class:Change/Stimulus:ev_monitor+' => '',
|
||||
'Class:Change/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:Change/Stimulus:ev_finish+' => '',
|
||||
'Class:ApprovedChange' => 'Утверждённые изменения',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: RoutineChange
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:RoutineChange' => 'Стандартное изменение',
|
||||
'Class:RoutineChange+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_validate' => 'Подтвердить',
|
||||
'Class:RoutineChange/Stimulus:ev_validate+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:RoutineChange/Stimulus:ev_reject+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:RoutineChange/Stimulus:ev_assign+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_reopen' => 'Вновь открыть',
|
||||
'Class:RoutineChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:RoutineChange/Stimulus:ev_plan+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:RoutineChange/Stimulus:ev_approve+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_replan' => 'Перепланировать',
|
||||
'Class:RoutineChange/Stimulus:ev_replan+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove' => 'Отклонить',
|
||||
'Class:RoutineChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:RoutineChange/Stimulus:ev_implement+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_monitor' => 'Наблюдать',
|
||||
'Class:RoutineChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:RoutineChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:RoutineChange/Stimulus:ev_finish+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ApprovedChange
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:ApprovedChange' => 'Утверждаемые изменения',
|
||||
'Class:ApprovedChange+' => '',
|
||||
'Class:ApprovedChange/Attribute:approval_date' => 'Дата утверждения',
|
||||
'Class:ApprovedChange/Attribute:approval_date+' => '',
|
||||
'Class:ApprovedChange/Attribute:approval_comment' => 'Коментарий утверждения',
|
||||
'Class:ApprovedChange/Attribute:approval_comment+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_validate' => 'Проверка',
|
||||
'Class:ApprovedChange/Stimulus:ev_validate' => 'Подтвердить',
|
||||
'Class:ApprovedChange/Stimulus:ev_validate+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_reject' => 'Отклонение',
|
||||
'Class:ApprovedChange/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:ApprovedChange/Stimulus:ev_reject+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_assign' => 'Назначение',
|
||||
'Class:ApprovedChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:ApprovedChange/Stimulus:ev_assign+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_reopen' => 'Переоткрыть',
|
||||
'Class:ApprovedChange/Stimulus:ev_reopen' => 'Вновь открыть',
|
||||
'Class:ApprovedChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_plan' => 'План',
|
||||
'Class:ApprovedChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:ApprovedChange/Stimulus:ev_plan+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:ApprovedChange/Stimulus:ev_approve+' => '',
|
||||
@@ -239,9 +217,76 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:ApprovedChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:ApprovedChange/Stimulus:ev_implement+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_monitor' => 'Контролировать',
|
||||
'Class:ApprovedChange/Stimulus:ev_monitor' => 'Наблюдать',
|
||||
'Class:ApprovedChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:ApprovedChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:ApprovedChange/Stimulus:ev_finish+' => '',
|
||||
));
|
||||
?>
|
||||
|
||||
//
|
||||
// Class: NormalChange
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:NormalChange' => 'Нормальное изменение',
|
||||
'Class:NormalChange+' => '',
|
||||
'Class:NormalChange/Attribute:acceptance_date' => 'Дата принятия',
|
||||
'Class:NormalChange/Attribute:acceptance_date+' => '',
|
||||
'Class:NormalChange/Attribute:acceptance_comment' => 'Комментарий принятия',
|
||||
'Class:NormalChange/Attribute:acceptance_comment+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_validate' => 'Подтвердить',
|
||||
'Class:NormalChange/Stimulus:ev_validate+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:NormalChange/Stimulus:ev_reject+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:NormalChange/Stimulus:ev_assign+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_reopen' => 'Вновь открыть',
|
||||
'Class:NormalChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:NormalChange/Stimulus:ev_plan+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:NormalChange/Stimulus:ev_approve+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_replan' => 'Перепланировать',
|
||||
'Class:NormalChange/Stimulus:ev_replan+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_notapprove' => 'Отклонить',
|
||||
'Class:NormalChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:NormalChange/Stimulus:ev_implement+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_monitor' => 'Наблюдать',
|
||||
'Class:NormalChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:NormalChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:NormalChange/Stimulus:ev_finish+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: EmergencyChange
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:EmergencyChange' => 'Экстренное изменение',
|
||||
'Class:EmergencyChange+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_validate' => 'Подтвердить',
|
||||
'Class:EmergencyChange/Stimulus:ev_validate+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_reject' => 'Отклонить',
|
||||
'Class:EmergencyChange/Stimulus:ev_reject+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:EmergencyChange/Stimulus:ev_assign+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_reopen' => 'Вновь открыть',
|
||||
'Class:EmergencyChange/Stimulus:ev_reopen+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_plan' => 'Планировать',
|
||||
'Class:EmergencyChange/Stimulus:ev_plan+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_approve' => 'Утвердить',
|
||||
'Class:EmergencyChange/Stimulus:ev_approve+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_replan' => 'Перепланировать',
|
||||
'Class:EmergencyChange/Stimulus:ev_replan+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_notapprove' => 'Отклонить',
|
||||
'Class:EmergencyChange/Stimulus:ev_notapprove+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_implement' => 'Реализовать',
|
||||
'Class:EmergencyChange/Stimulus:ev_implement+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_monitor' => 'Наблюдать',
|
||||
'Class:EmergencyChange/Stimulus:ev_monitor+' => '',
|
||||
'Class:EmergencyChange/Stimulus:ev_finish' => 'Закончить',
|
||||
'Class:EmergencyChange/Stimulus:ev_finish+' => '',
|
||||
));
|
||||
|
||||
?>
|
||||
|
||||
@@ -105,6 +105,15 @@
|
||||
<default_value/>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="outage" xsi:type="AttributeEnum">
|
||||
<values>
|
||||
<value>yes</value>
|
||||
<value>no</value>
|
||||
</values>
|
||||
<sql>outage</sql>
|
||||
<default_value>no</default_value>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="related_request_list" xsi:type="AttributeLinkedSet">
|
||||
<linked_class>UserRequest</linked_class>
|
||||
<ext_key_to_me>parent_change_id</ext_key_to_me>
|
||||
@@ -187,6 +196,9 @@
|
||||
<attribute id="changemanager_id">
|
||||
<hidden/>
|
||||
</attribute>
|
||||
<attribute id="outage">
|
||||
<hidden/>
|
||||
</attribute>
|
||||
</flags>
|
||||
<transitions>
|
||||
<transition>
|
||||
@@ -237,6 +249,9 @@
|
||||
<attribute id="approval_date">
|
||||
<hidden/>
|
||||
</attribute>
|
||||
<attribute id="outage">
|
||||
<hidden/>
|
||||
</attribute>
|
||||
</flags>
|
||||
<transitions>
|
||||
<transition>
|
||||
@@ -299,6 +314,10 @@
|
||||
<attribute id="changemanager_id">
|
||||
<mandatory/>
|
||||
</attribute>
|
||||
<attribute id="outage">
|
||||
<mandatory/>
|
||||
<must_prompt/>
|
||||
</attribute>
|
||||
</flags>
|
||||
<transitions>
|
||||
<transition>
|
||||
@@ -383,6 +402,9 @@
|
||||
<attribute id="parent_id">
|
||||
<read_only/>
|
||||
</attribute>
|
||||
<attribute id="outage">
|
||||
<read_only/>
|
||||
</attribute>
|
||||
</flags>
|
||||
<transitions>
|
||||
<transition>
|
||||
@@ -451,6 +473,9 @@
|
||||
<attribute id="parent_id">
|
||||
<normal/>
|
||||
</attribute>
|
||||
<attribute id="outage">
|
||||
<read_only/>
|
||||
</attribute>
|
||||
</flags>
|
||||
<transitions>
|
||||
<transition>
|
||||
@@ -523,6 +548,9 @@
|
||||
<attribute id="parent_id">
|
||||
<read_only/>
|
||||
</attribute>
|
||||
<attribute id="outage">
|
||||
<read_only/>
|
||||
</attribute>
|
||||
</flags>
|
||||
<transitions/>
|
||||
</state>
|
||||
@@ -605,20 +633,6 @@
|
||||
$this->Set('last_update', time());
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="ComputeValues">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public function ComputeValues()
|
||||
{
|
||||
if ($this->IsNew())
|
||||
{
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
$sName = sprintf('C-%06d', $iKey);
|
||||
$this->Set('ref', $sName);
|
||||
}
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="GetIcon">
|
||||
<comment>/**
|
||||
* Get the icon representing this object
|
||||
@@ -752,6 +766,9 @@
|
||||
<item id="category">
|
||||
<rank>10</rank>
|
||||
</item>
|
||||
<item id="outage">
|
||||
<rank>15.1</rank>
|
||||
</item>
|
||||
<item id="reject_reason">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
|
||||
@@ -110,5 +110,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:Change/Attribute:related_incident_list+' => '',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Change Friendly Name',
|
||||
'Class:Change/Attribute:parent_id_friendlyname+' => '',
|
||||
'Class:Change/Attribute:outage' => 'Ausfall',
|
||||
'Class:Change/Attribute:outage+' => '',
|
||||
'Class:Change/Attribute:outage/Value:no' => 'Nein',
|
||||
'Class:Change/Attribute:outage/Value:no+' => '',
|
||||
'Class:Change/Attribute:outage/Value:yes' => 'Ja',
|
||||
'Class:Change/Attribute:outage/Value:yes+' => '',
|
||||
));
|
||||
?>
|
||||
@@ -132,6 +132,12 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:Change/Stimulus:ev_approve+' => '',
|
||||
'Class:Change/Stimulus:ev_finish' => 'Close',
|
||||
'Class:Change/Stimulus:ev_finish+' => '',
|
||||
'Class:Change/Attribute:outage' => 'Outage',
|
||||
'Class:Change/Attribute:outage+' => '',
|
||||
'Class:Change/Attribute:outage/Value:no' => 'No',
|
||||
'Class:Change/Attribute:outage/Value:no+' => '',
|
||||
'Class:Change/Attribute:outage/Value:yes' => 'Yes',
|
||||
'Class:Change/Attribute:outage/Value:yes+' => '',
|
||||
));
|
||||
|
||||
?>
|
||||
|
||||
@@ -133,6 +133,12 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Class:Change/Stimulus:ev_approve+' => 'Aprobar',
|
||||
'Class:Change/Stimulus:ev_finish' => 'Finalizar',
|
||||
'Class:Change/Stimulus:ev_finish+' => 'Finalizar',
|
||||
'Class:Change/Attribute:outage' => 'Falla',
|
||||
'Class:Change/Attribute:outage+' => 'Falla',
|
||||
'Class:Change/Attribute:outage/Value:no' => 'No',
|
||||
'Class:Change/Attribute:outage/Value:no+' => 'No',
|
||||
'Class:Change/Attribute:outage/Value:yes' => 'Si',
|
||||
'Class:Change/Attribute:outage/Value:yes+' => 'Si',
|
||||
));
|
||||
|
||||
?>
|
||||
|
||||
@@ -94,6 +94,12 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:Change/Stimulus:ev_approve+' => '',
|
||||
'Class:Change/Stimulus:ev_finish' => 'Fermer',
|
||||
'Class:Change/Stimulus:ev_finish+' => '',
|
||||
'Class:Change/Attribute:outage' => 'Interruption de service',
|
||||
'Class:Change/Attribute:outage+' => '',
|
||||
'Class:Change/Attribute:outage/Value:no' => 'Non',
|
||||
'Class:Change/Attribute:outage/Value:no+' => '',
|
||||
'Class:Change/Attribute:outage/Value:yes' => 'Oui',
|
||||
'Class:Change/Attribute:outage/Value:yes+' => '',
|
||||
));
|
||||
|
||||
|
||||
|
||||
137
datamodels/2.x/itop-change-mgmt/pt_br.dict.itop-change-mgmt.php
Normal file
137
datamodels/2.x/itop-change-mgmt/pt_br.dict.itop-change-mgmt.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Menu:ChangeManagement' => 'Gerenciamento Mudanças',
|
||||
'Menu:Change:Overview' => 'Visão geral',
|
||||
'Menu:Change:Overview+' => '',
|
||||
'Menu:NewChange' => 'Nova mudança',
|
||||
'Menu:NewChange+' => 'Criar uma nova solicitação de mudança',
|
||||
'Menu:SearchChanges' => 'Pesquisar por mudanças',
|
||||
'Menu:SearchChanges+' => 'Pesquisar por solicitação de mudança',
|
||||
'Menu:Change:Shortcuts' => 'Atalho',
|
||||
'Menu:Change:Shortcuts+' => '',
|
||||
'Menu:WaitingAcceptance' => 'Mudanças à espera de aceitação',
|
||||
'Menu:WaitingAcceptance+' => '',
|
||||
'Menu:WaitingApproval' => 'Mudanças aguardando aprovação',
|
||||
'Menu:WaitingApproval+' => '',
|
||||
'Menu:Changes' => 'Mudanças abertas',
|
||||
'Menu:Changes+' => 'Todas mudanças abertas',
|
||||
'Menu:MyChanges' => 'Mudanças atribuídas a mim',
|
||||
'Menu:MyChanges+' => 'Mudanças atribuídas a mim (como Agente)',
|
||||
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Mudanças por categoria nos últimos 7 dias',
|
||||
'UI-ChangeManagementOverview-Last-7-days' => 'Número de mudanças nos últimos 7 dias',
|
||||
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Mudanças por domínio nos últimos 7 dias',
|
||||
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Mudanças por status nos últimos 7 dias',
|
||||
));
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
|
||||
//
|
||||
// Class: Change
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:Change' => 'Mudanças',
|
||||
'Class:Change+' => '',
|
||||
'Class:Change/Attribute:status' => 'Status',
|
||||
'Class:Change/Attribute:status+' => '',
|
||||
'Class:Change/Attribute:status/Value:new' => 'Nova',
|
||||
'Class:Change/Attribute:status/Value:new+' => '',
|
||||
'Class:Change/Attribute:status/Value:assigned' => 'Atribuido',
|
||||
'Class:Change/Attribute:status/Value:assigned+' => '',
|
||||
'Class:Change/Attribute:status/Value:planned' => 'Planejado',
|
||||
'Class:Change/Attribute:status/Value:planned+' => '',
|
||||
'Class:Change/Attribute:status/Value:rejected' => 'Rejeitado',
|
||||
'Class:Change/Attribute:status/Value:rejected+' => '',
|
||||
'Class:Change/Attribute:status/Value:approved' => 'Aprovado',
|
||||
'Class:Change/Attribute:status/Value:approved+' => '',
|
||||
'Class:Change/Attribute:status/Value:closed' => 'Fechado',
|
||||
'Class:Change/Attribute:status/Value:closed+' => '',
|
||||
'Class:Change/Attribute:category' => 'Categoria',
|
||||
'Class:Change/Attribute:category+' => '',
|
||||
'Class:Change/Attribute:category/Value:application' => 'aplicação',
|
||||
'Class:Change/Attribute:category/Value:application+' => 'aplicação',
|
||||
'Class:Change/Attribute:category/Value:hardware' => 'hardware',
|
||||
'Class:Change/Attribute:category/Value:hardware+' => 'hardware',
|
||||
'Class:Change/Attribute:category/Value:network' => 'rede',
|
||||
'Class:Change/Attribute:category/Value:network+' => 'rede',
|
||||
'Class:Change/Attribute:category/Value:other' => 'outro',
|
||||
'Class:Change/Attribute:category/Value:other+' => 'outro',
|
||||
'Class:Change/Attribute:category/Value:software' => 'software',
|
||||
'Class:Change/Attribute:category/Value:software+' => 'software',
|
||||
'Class:Change/Attribute:category/Value:system' => 'sistema',
|
||||
'Class:Change/Attribute:category/Value:system+' => 'sistema',
|
||||
'Class:Change/Attribute:reject_reason' => 'Razão rejeição',
|
||||
'Class:Change/Attribute:reject_reason+' => '',
|
||||
'Class:Change/Attribute:changemanager_id' => 'Gerente mudança',
|
||||
'Class:Change/Attribute:changemanager_id+' => '',
|
||||
'Class:Change/Attribute:changemanager_email' => 'Email gerente mudança',
|
||||
'Class:Change/Attribute:changemanager_email+' => '',
|
||||
'Class:Change/Attribute:parent_id' => 'Parente mudança',
|
||||
'Class:Change/Attribute:parent_id+' => '',
|
||||
'Class:Change/Attribute:parent_name' => 'Ref parente mudança',
|
||||
'Class:Change/Attribute:parent_name+' => '',
|
||||
'Class:Change/Attribute:creation_date' => 'Data criação',
|
||||
'Class:Change/Attribute:creation_date+' => '',
|
||||
'Class:Change/Attribute:approval_date' => 'Data aprovação',
|
||||
'Class:Change/Attribute:approval_date+' => '',
|
||||
'Class:Change/Attribute:fallback_plan' => 'Plano de contingência',
|
||||
'Class:Change/Attribute:fallback_plan+' => '',
|
||||
'Class:Change/Attribute:related_request_list' => 'Solicitações relacionadas',
|
||||
'Class:Change/Attribute:related_request_list+' => 'Todas as solicitações de usuários ligados a esta mudança',
|
||||
'Class:Change/Attribute:related_incident_list' => 'Incidentes relacionados',
|
||||
'Class:Change/Attribute:related_incident_list+' => 'Todos os incidentes ligados a esta mudança',
|
||||
'Class:Change/Attribute:related_problems_list' => 'Problemas relacionados',
|
||||
'Class:Change/Attribute:related_problems_list+' => 'Todos os problemas relacionados com esta mudança',
|
||||
'Class:Change/Attribute:child_changes_list' => 'Mudanças filhas',
|
||||
'Class:Change/Attribute:child_changes_list+' => 'Todas as sub-mudanças ligadas a esta mudança',
|
||||
'Class:Change/Attribute:parent_id_friendlyname' => 'Nome amigável mudança relacionado',
|
||||
'Class:Change/Attribute:parent_id_friendlyname+' => '',
|
||||
'Class:Change/Stimulus:ev_assign' => 'Atribuir',
|
||||
'Class:Change/Stimulus:ev_assign+' => '',
|
||||
'Class:Change/Stimulus:ev_plan' => 'Planejar',
|
||||
'Class:Change/Stimulus:ev_plan+' => '',
|
||||
'Class:Change/Stimulus:ev_reject' => 'Rejeitar',
|
||||
'Class:Change/Stimulus:ev_reject+' => '',
|
||||
'Class:Change/Stimulus:ev_reopen' => 'Re-abrir',
|
||||
'Class:Change/Stimulus:ev_reopen+' => '',
|
||||
'Class:Change/Stimulus:ev_approve' => 'Aprovar',
|
||||
'Class:Change/Stimulus:ev_approve+' => '',
|
||||
'Class:Change/Stimulus:ev_finish' => 'Fechar',
|
||||
'Class:Change/Stimulus:ev_finish+' => '',
|
||||
));
|
||||
|
||||
?>
|
||||
@@ -780,7 +780,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
//
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:VirtualDevice' => 'Device Virtuel',
|
||||
'Class:VirtualDevice' => 'Equipement Virtuel',
|
||||
'Class:VirtualDevice+' => '',
|
||||
'Class:VirtualDevice/Attribute:status' => 'Statut',
|
||||
'Class:VirtualDevice/Attribute:status+' => '',
|
||||
@@ -801,7 +801,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
//
|
||||
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:VirtualHost' => 'Host Virtuel',
|
||||
'Class:VirtualHost' => 'Hôte Virtuel',
|
||||
'Class:VirtualHost+' => '',
|
||||
'Class:VirtualHost/Attribute:virtualmachine_list' => 'Machines virtuelles',
|
||||
'Class:VirtualHost/Attribute:virtualmachine_list+' => '',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -14,6 +14,15 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Module providing end-user devices: phone, printer...
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-endusers-devices/2.0.0',
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
|
||||
<constants>
|
||||
<constant id="PORTAL_TYPE_TO_CLASS" xsi:type="string" _delta="redefine"><![CDATA[{"service_request":"UserRequest","incident":"Incident"}]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_PUBLIC_LOG" xsi:type="string" _delta="define"><![CDATA[public_log]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_USER_COMMENT" xsi:type="string" _delta="define"><![CDATA[user_comment]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_FORM_ATTRIBUTES" xsi:type="string" _delta="define"><![CDATA[title,description,impact,urgency]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_TYPE" xsi:type="string" _delta="define"><![CDATA[]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_LIST_ZLIST" xsi:type="string" _delta="define"><![CDATA[finalclass,title,start_date,status,servicesubcategory_id,priority,caller_id]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_CLOSED_ZLIST" xsi:type="string" _delta="define"><![CDATA[title,start_date,close_date,servicesubcategory_id]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_DETAILS_ZLIST" xsi:type="string" _delta="define"><![CDATA[{"col:left":["ref","caller_id","servicesubcategory_id","title","description","solution"],"col:right":["status","priority","start_date","resolution_date","last_update","agent_id"]}]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_DISPLAY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Incident WHERE org_id = :contact->org_id AND caller_id = :contact->id]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_DISPLAY_POWERUSER_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Incident WHERE org_id = :contact->org_id]]></constant>
|
||||
</constants>
|
||||
<classes>
|
||||
<class id="Incident" _delta="define">
|
||||
<parent>Ticket</parent>
|
||||
@@ -227,7 +239,7 @@
|
||||
</field>
|
||||
<field id="sla_tto_passed" xsi:type="AttributeSubItem">
|
||||
<target_attcode>tto</target_attcode>
|
||||
<item_code>100_passed</item_code>
|
||||
<item_code>100_triggered</item_code>
|
||||
</field>
|
||||
<field id="sla_tto_over" xsi:type="AttributeSubItem">
|
||||
<target_attcode>tto</target_attcode>
|
||||
@@ -239,7 +251,7 @@
|
||||
</field>
|
||||
<field id="sla_ttr_passed" xsi:type="AttributeSubItem">
|
||||
<target_attcode>ttr</target_attcode>
|
||||
<item_code>100_passed</item_code>
|
||||
<item_code>100_triggered</item_code>
|
||||
</field>
|
||||
<field id="sla_ttr_over" xsi:type="AttributeSubItem">
|
||||
<target_attcode>ttr</target_attcode>
|
||||
@@ -1265,13 +1277,6 @@
|
||||
// Compute the priority of the ticket
|
||||
$this->Set('priority', $this->ComputePriority());
|
||||
|
||||
if ($this->IsNew())
|
||||
{
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
$sName = sprintf('I-%06d', $iKey);
|
||||
$this->Set('ref', $sName);
|
||||
}
|
||||
|
||||
return parent::ComputeValues();
|
||||
}]]></code>
|
||||
</method>
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Menu:IncidentManagement' => 'Gerenciamento Incidentes',
|
||||
'Menu:IncidentManagement+' => 'Gerenciamento Incidentes',
|
||||
'Menu:Incident:Overview' => 'Visão geral',
|
||||
'Menu:Incident:Overview+' => 'Visão geral',
|
||||
'Menu:NewIncident' => 'Novo incidente',
|
||||
'Menu:NewIncident+' => 'Criar uma novo incidente',
|
||||
'Menu:SearchIncidents' => 'Pesquisar por incidentes',
|
||||
'Menu:SearchIncidents+' => 'Pesquisar por solicitações incidentes',
|
||||
'Menu:Incident:Shortcuts' => 'Atalho',
|
||||
'Menu:Incident:Shortcuts+' => '',
|
||||
'Menu:Incident:MyIncidents' => 'Incidentes atribuídos para mim',
|
||||
'Menu:Incident:MyIncidents+' => 'Incidentes atribuídos para mim (como agente)',
|
||||
'Menu:Incident:EscalatedIncidents' => 'Incidentes escalados',
|
||||
'Menu:Incident:EscalatedIncidents+' => 'Incidentes escalados',
|
||||
'Menu:Incident:OpenIncidents' => 'Todos incidentes abertos',
|
||||
'Menu:Incident:OpenIncidents+' => 'Todos incidentes abertos',
|
||||
'Menu:Incident:UnassignedIncidents' => 'Incidentes ainda não atribuídos',
|
||||
'Menu:Incident:UnassignedIncidents+' => 'Incidentes ainda não atribuídos',
|
||||
'Menu:Incident:HelpdeskIncidents' => 'Incidentes atribuídos a nível 2',
|
||||
'Menu:Incident:HelpdeskIncidents+' => 'Incidentes atribuídos a nível 2',
|
||||
'UI-IncidentManagementOverview-IncidentByPriority-last-14-days' => 'Últimos 14 dias por incidente prioridade',
|
||||
'UI-IncidentManagementOverview-Last-14-days' => 'Últimos 14 dias por incidente prioridade',
|
||||
'UI-IncidentManagementOverview-OpenIncidentByStatus' => 'Incidentes abertos por estado',
|
||||
'UI-IncidentManagementOverview-OpenIncidentByAgent' => 'Incidentes abertos por agentes',
|
||||
'UI-IncidentManagementOverview-OpenIncidentByCustomer' => 'Incidentes abertos por cliente',
|
||||
));
|
||||
|
||||
|
||||
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: Incident
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:Incident' => 'Incidente',
|
||||
'Class:Incident+' => '',
|
||||
'Class:Incident/Attribute:status' => 'Estado',
|
||||
'Class:Incident/Attribute:status+' => '',
|
||||
'Class:Incident/Attribute:status/Value:new' => 'Novo',
|
||||
'Class:Incident/Attribute:status/Value:new+' => '',
|
||||
'Class:Incident/Attribute:status/Value:escalated_tto' => 'TTO escalado',
|
||||
'Class:Incident/Attribute:status/Value:escalated_tto+' => '',
|
||||
'Class:Incident/Attribute:status/Value:assigned' => 'Atribuído',
|
||||
'Class:Incident/Attribute:status/Value:assigned+' => '',
|
||||
'Class:Incident/Attribute:status/Value:escalated_ttr' => 'TTR escalado',
|
||||
'Class:Incident/Attribute:status/Value:escalated_ttr+' => '',
|
||||
'Class:Incident/Attribute:status/Value:waiting_for_approval' => 'Aguardando aprovação',
|
||||
'Class:Incident/Attribute:status/Value:waiting_for_approval+' => '',
|
||||
'Class:Incident/Attribute:status/Value:pending' => 'Pendente',
|
||||
'Class:Incident/Attribute:status/Value:pending+' => '',
|
||||
'Class:Incident/Attribute:status/Value:resolved' => 'Resolvido',
|
||||
'Class:Incident/Attribute:status/Value:resolved+' => '',
|
||||
'Class:Incident/Attribute:status/Value:closed' => 'Fechado',
|
||||
'Class:Incident/Attribute:status/Value:closed+' => '',
|
||||
'Class:Incident/Attribute:impact' => 'Impacto',
|
||||
'Class:Incident/Attribute:impact+' => '',
|
||||
'Class:Incident/Attribute:impact/Value:1' => 'Um departamento',
|
||||
'Class:Incident/Attribute:impact/Value:1+' => '',
|
||||
'Class:Incident/Attribute:impact/Value:2' => 'Um serviço',
|
||||
'Class:Incident/Attribute:impact/Value:2+' => '',
|
||||
'Class:Incident/Attribute:impact/Value:3' => 'Uma pessoa',
|
||||
'Class:Incident/Attribute:impact/Value:3+' => '',
|
||||
'Class:Incident/Attribute:priority' => 'Prioridade',
|
||||
'Class:Incident/Attribute:priority+' => '',
|
||||
'Class:Incident/Attribute:priority/Value:1' => 'Crítica',
|
||||
'Class:Incident/Attribute:priority/Value:1+' => 'Crítica',
|
||||
'Class:Incident/Attribute:priority/Value:2' => 'Alta',
|
||||
'Class:Incident/Attribute:priority/Value:2+' => 'Alta',
|
||||
'Class:Incident/Attribute:priority/Value:3' => 'Média',
|
||||
'Class:Incident/Attribute:priority/Value:3+' => 'Média',
|
||||
'Class:Incident/Attribute:priority/Value:4' => 'Baixa',
|
||||
'Class:Incident/Attribute:priority/Value:4+' => 'Baixa',
|
||||
'Class:Incident/Attribute:urgency' => 'Urgência',
|
||||
'Class:Incident/Attribute:urgency+' => '',
|
||||
'Class:Incident/Attribute:urgency/Value:1' => 'Crítica',
|
||||
'Class:Incident/Attribute:urgency/Value:1+' => 'Crítica',
|
||||
'Class:Incident/Attribute:urgency/Value:2' => 'Alta',
|
||||
'Class:Incident/Attribute:urgency/Value:2+' => 'Alta',
|
||||
'Class:Incident/Attribute:urgency/Value:3' => 'Média',
|
||||
'Class:Incident/Attribute:urgency/Value:3+' => 'Média',
|
||||
'Class:Incident/Attribute:urgency/Value:4' => 'Baixa',
|
||||
'Class:Incident/Attribute:urgency/Value:4+' => 'Baixa',
|
||||
'Class:Incident/Attribute:origin' => 'Origem',
|
||||
'Class:Incident/Attribute:origin+' => '',
|
||||
'Class:Incident/Attribute:origin/Value:mail' => 'Email',
|
||||
'Class:Incident/Attribute:origin/Value:mail+' => 'Email',
|
||||
'Class:Incident/Attribute:origin/Value:monitoring' => 'Monitoramento',
|
||||
'Class:Incident/Attribute:origin/Value:monitoring+' => 'Monitoramento',
|
||||
'Class:Incident/Attribute:origin/Value:phone' => 'Telefone',
|
||||
'Class:Incident/Attribute:origin/Value:phone+' => 'Telefone',
|
||||
'Class:Incident/Attribute:origin/Value:portal' => 'Portal',
|
||||
'Class:Incident/Attribute:origin/Value:portal+' => 'Portal',
|
||||
'Class:Incident/Attribute:service_id' => 'Serviço',
|
||||
'Class:Incident/Attribute:service_id+' => '',
|
||||
'Class:Incident/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:Incident/Attribute:service_name+' => '',
|
||||
'Class:Incident/Attribute:servicesubcategory_id' => 'Sub-categoria serviço',
|
||||
'Class:Incident/Attribute:servicesubcategory_id+' => '',
|
||||
'Class:Incident/Attribute:servicesubcategory_name' => 'Nome Sub-categoria serviço',
|
||||
'Class:Incident/Attribute:servicesubcategory_name+' => '',
|
||||
'Class:Incident/Attribute:escalation_flag' => 'Alerta vermelho',
|
||||
'Class:Incident/Attribute:escalation_flag+' => '',
|
||||
'Class:Incident/Attribute:escalation_flag/Value:no' => 'Não',
|
||||
'Class:Incident/Attribute:escalation_flag/Value:no+' => 'Não',
|
||||
'Class:Incident/Attribute:escalation_flag/Value:yes' => 'Sim',
|
||||
'Class:Incident/Attribute:escalation_flag/Value:yes+' => 'Sim',
|
||||
'Class:Incident/Attribute:escalation_reason' => 'Razão alerta',
|
||||
'Class:Incident/Attribute:escalation_reason+' => '',
|
||||
'Class:Incident/Attribute:assignment_date' => 'Data atribuição',
|
||||
'Class:Incident/Attribute:assignment_date+' => '',
|
||||
'Class:Incident/Attribute:resolution_date' => 'Data resolução',
|
||||
'Class:Incident/Attribute:resolution_date+' => '',
|
||||
'Class:Incident/Attribute:last_pending_date' => 'Última data pendente',
|
||||
'Class:Incident/Attribute:last_pending_date+' => '',
|
||||
'Class:Incident/Attribute:cumulatedpending' => 'Pendências acumuladas',
|
||||
'Class:Incident/Attribute:cumulatedpending+' => '',
|
||||
'Class:Incident/Attribute:tto' => 'TTO',
|
||||
'Class:Incident/Attribute:tto+' => '',
|
||||
'Class:Incident/Attribute:ttr' => 'TTR',
|
||||
'Class:Incident/Attribute:ttr+' => '',
|
||||
'Class:Incident/Attribute:tto_escalation_deadline' => 'Prazo determinado TTO',
|
||||
'Class:Incident/Attribute:tto_escalation_deadline+' => '',
|
||||
'Class:Incident/Attribute:sla_tto_passed' => 'SLA TTO passou',
|
||||
'Class:Incident/Attribute:sla_tto_passed+' => '',
|
||||
'Class:Incident/Attribute:sla_tto_over' => 'SLA TTO acima',
|
||||
'Class:Incident/Attribute:sla_tto_over+' => '',
|
||||
'Class:Incident/Attribute:ttr_escalation_deadline' => 'Prazo determinado TTR',
|
||||
'Class:Incident/Attribute:ttr_escalation_deadline+' => '',
|
||||
'Class:Incident/Attribute:sla_ttr_passed' => 'SLA TTR passou',
|
||||
'Class:Incident/Attribute:sla_ttr_passed+' => '',
|
||||
'Class:Incident/Attribute:sla_ttr_over' => 'SLA TTR acima',
|
||||
'Class:Incident/Attribute:sla_ttr_over+' => '',
|
||||
'Class:Incident/Attribute:time_spent' => 'Atraso resolução',
|
||||
'Class:Incident/Attribute:time_spent+' => '',
|
||||
'Class:Incident/Attribute:resolution_code' => 'Código resolução',
|
||||
'Class:Incident/Attribute:resolution_code+' => '',
|
||||
'Class:Incident/Attribute:resolution_code/Value:assistance' => 'Assistência',
|
||||
'Class:Incident/Attribute:resolution_code/Value:assistance+' => 'Assistência',
|
||||
'Class:Incident/Attribute:resolution_code/Value:bug fixed' => 'Bug corrigido',
|
||||
'Class:Incident/Attribute:resolution_code/Value:bug fixed+' => 'Bug corrigido',
|
||||
'Class:Incident/Attribute:resolution_code/Value:hardware repair' => 'Hardware reparado',
|
||||
'Class:Incident/Attribute:resolution_code/Value:hardware repair+' => 'Hardware reparado',
|
||||
'Class:Incident/Attribute:resolution_code/Value:other' => 'Outro',
|
||||
'Class:Incident/Attribute:resolution_code/Value:other+' => 'Outro',
|
||||
'Class:Incident/Attribute:resolution_code/Value:software patch' => 'Software patch',
|
||||
'Class:Incident/Attribute:resolution_code/Value:software patch+' => 'Software patch',
|
||||
'Class:Incident/Attribute:resolution_code/Value:system update' => 'Atualização sistema',
|
||||
'Class:Incident/Attribute:resolution_code/Value:system update+' => 'Atualização sistema',
|
||||
'Class:Incident/Attribute:resolution_code/Value:training' => 'Treinamento',
|
||||
'Class:Incident/Attribute:resolution_code/Value:training+' => 'Treinamento',
|
||||
'Class:Incident/Attribute:solution' => 'Solução',
|
||||
'Class:Incident/Attribute:solution+' => '',
|
||||
'Class:Incident/Attribute:pending_reason' => 'Razão pendência',
|
||||
'Class:Incident/Attribute:pending_reason+' => '',
|
||||
'Class:Incident/Attribute:parent_incident_id' => 'Incidente principal',
|
||||
'Class:Incident/Attribute:parent_incident_id+' => '',
|
||||
'Class:Incident/Attribute:parent_incident_ref' => 'Ref Incidente principal',
|
||||
'Class:Incident/Attribute:parent_incident_ref+' => '',
|
||||
'Class:Incident/Attribute:parent_problem_id' => 'Problema principal',
|
||||
'Class:Incident/Attribute:parent_problem_id+' => '',
|
||||
'Class:Incident/Attribute:parent_problem_ref' => 'Ref problema principal',
|
||||
'Class:Incident/Attribute:parent_problem_ref+' => '',
|
||||
'Class:Incident/Attribute:parent_change_id' => 'Mudança principal',
|
||||
'Class:Incident/Attribute:parent_change_id+' => '',
|
||||
'Class:Incident/Attribute:parent_change_ref' => 'Ref mudança principal',
|
||||
'Class:Incident/Attribute:parent_change_ref+' => '',
|
||||
'Class:Incident/Attribute:child_incidents_list' => 'Sub-Incidentes',
|
||||
'Class:Incident/Attribute:child_incidents_list+' => 'Todos os sub-incidentes vinculados a esse incidente',
|
||||
'Class:Incident/Attribute:public_log' => 'Log público',
|
||||
'Class:Incident/Attribute:public_log+' => '',
|
||||
'Class:Incident/Attribute:user_satisfaction' => 'Satisfação do usuário',
|
||||
'Class:Incident/Attribute:user_satisfaction+' => '',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:1' => 'Muito satisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:1+' => 'Muito satisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:2' => 'Bastante satisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:2+' => 'Bastante satisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:3' => 'Bastante insatisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:3+' => 'Bastante insatisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:4' => 'Muito insatisfeito',
|
||||
'Class:Incident/Attribute:user_satisfaction/Value:4+' => 'Muito insatisfeito',
|
||||
'Class:Incident/Attribute:user_comment' => 'Comentário usuário',
|
||||
'Class:Incident/Attribute:user_comment+' => '',
|
||||
'Class:Incident/Attribute:parent_incident_id_friendlyname' => 'parent_incident_id_friendlyname',
|
||||
'Class:Incident/Attribute:parent_incident_id_friendlyname+' => '',
|
||||
'Class:Incident/Stimulus:ev_assign' => 'Atribuir',
|
||||
'Class:Incident/Stimulus:ev_assign+' => '',
|
||||
'Class:Incident/Stimulus:ev_reassign' => 'Re-atribuir',
|
||||
'Class:Incident/Stimulus:ev_reassign+' => '',
|
||||
'Class:Incident/Stimulus:ev_pending' => 'Pendente',
|
||||
'Class:Incident/Stimulus:ev_pending+' => '',
|
||||
'Class:Incident/Stimulus:ev_timeout' => 'Timeout',
|
||||
'Class:Incident/Stimulus:ev_timeout+' => '',
|
||||
'Class:Incident/Stimulus:ev_autoresolve' => 'Resolvido automaticamente',
|
||||
'Class:Incident/Stimulus:ev_autoresolve+' => '',
|
||||
'Class:Incident/Stimulus:ev_autoclose' => 'Fechado automaticamente',
|
||||
'Class:Incident/Stimulus:ev_autoclose+' => '',
|
||||
'Class:Incident/Stimulus:ev_resolve' => 'Marcar como resolvido',
|
||||
'Class:Incident/Stimulus:ev_resolve+' => '',
|
||||
'Class:Incident/Stimulus:ev_close' => 'Fechar esta solicitação',
|
||||
'Class:Incident/Stimulus:ev_close+' => '',
|
||||
'Class:Incident/Stimulus:ev_reopen' => 'Re-abrir',
|
||||
'Class:Incident/Stimulus:ev_reopen+' => '',
|
||||
'Class:Incident/Error:CannotAssignParentIncidentIdToSelf' => 'Não é possível atribuir o incidente principal ao próprio incidente',
|
||||
));
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,40 +1,69 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Classes in 'bizmodel'
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: KnownError
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:KnownError' => 'Известные ошибки',
|
||||
'Class:KnownError+' => 'Ошибки задокументированные как известные',
|
||||
'Class:KnownError' => 'Известная ошибка',
|
||||
'Class:KnownError+' => 'Проблема, имеющая задокументированные корневую причину и обходное решение',
|
||||
'Class:KnownError/Attribute:name' => 'Название',
|
||||
'Class:KnownError/Attribute:name+' => '',
|
||||
'Class:KnownError/Attribute:org_id' => 'Клинт',
|
||||
'Class:KnownError/Attribute:org_id' => 'Организация',
|
||||
'Class:KnownError/Attribute:org_id+' => '',
|
||||
'Class:KnownError/Attribute:problem_id' => 'Связанная проблема',
|
||||
'Class:KnownError/Attribute:cust_name' => 'Имя клиента',
|
||||
'Class:KnownError/Attribute:cust_name+' => '',
|
||||
'Class:KnownError/Attribute:problem_id' => 'Проблема',
|
||||
'Class:KnownError/Attribute:problem_id+' => '',
|
||||
'Class:KnownError/Attribute:problem_ref' => 'Ссылка на проблему',
|
||||
'Class:KnownError/Attribute:problem_ref+' => '',
|
||||
'Class:KnownError/Attribute:symptom' => 'Проявление',
|
||||
'Class:KnownError/Attribute:symptom+' => '',
|
||||
'Class:KnownError/Attribute:root_cause' => 'Основная причина',
|
||||
'Class:KnownError/Attribute:root_cause' => 'Корневая причина',
|
||||
'Class:KnownError/Attribute:root_cause+' => '',
|
||||
'Class:KnownError/Attribute:workaround' => 'Обходное решение',
|
||||
'Class:KnownError/Attribute:workaround+' => '',
|
||||
@@ -59,71 +88,98 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:KnownError/Attribute:version' => 'Версия',
|
||||
'Class:KnownError/Attribute:version+' => '',
|
||||
'Class:KnownError/Attribute:ci_list' => 'КЕ',
|
||||
'Class:KnownError/Attribute:ci_list+' => '',
|
||||
'Class:KnownError/Attribute:ci_list+' => 'Связанный конфигурационные единицы',
|
||||
'Class:KnownError/Attribute:document_list' => 'Документы',
|
||||
'Class:KnownError/Attribute:document_list+' => '',
|
||||
'Class:lnkErrorToFunctionalCI' => 'Link Error / FunctionalCI~~',
|
||||
'Class:lnkErrorToFunctionalCI+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_id' => 'Error~~',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_id+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:reason' => 'Reason~~',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:reason+' => '',
|
||||
'Class:lnkDocumentToError' => 'Link Documents / Errors~~',
|
||||
'Class:lnkDocumentToError+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:document_id' => 'Document~~',
|
||||
'Class:lnkDocumentToError/Attribute:document_id+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:error_id' => 'Error~~',
|
||||
'Class:lnkDocumentToError/Attribute:error_id+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:link_type' => 'link_type~~',
|
||||
'Class:lnkDocumentToError/Attribute:link_type+' => '',
|
||||
'Class:FAQ' => 'FAQ~~',
|
||||
'Class:FAQ+' => '',
|
||||
'Class:FAQ/Attribute:title' => 'Title~~',
|
||||
'Class:FAQ/Attribute:title+' => '',
|
||||
'Class:FAQ/Attribute:summary' => 'Summary~~',
|
||||
'Class:FAQ/Attribute:summary+' => '',
|
||||
'Class:FAQ/Attribute:description' => 'Description~~',
|
||||
'Class:FAQ/Attribute:description+' => '',
|
||||
'Class:FAQ/Attribute:category_id' => 'Category~~',
|
||||
'Class:FAQ/Attribute:category_id+' => '',
|
||||
'Class:FAQ/Attribute:error_code' => 'Error code~~',
|
||||
'Class:FAQ/Attribute:error_code+' => '',
|
||||
'Class:FAQ/Attribute:key_words' => 'Key words~~',
|
||||
'Class:FAQ/Attribute:key_words+' => '',
|
||||
'Class:FAQCategory' => 'FAQ Category~~',
|
||||
'Class:FAQCategory+' => '',
|
||||
'Class:FAQCategory/Attribute:name' => 'Name~~',
|
||||
'Class:FAQCategory/Attribute:name+' => '',
|
||||
'Class:FAQCategory/Attribute:faq_list' => 'FAQs~~',
|
||||
'Class:FAQCategory/Attribute:faq_list+' => '',
|
||||
'Menu:ProblemManagement' => 'Управление проблемами',
|
||||
'Menu:ProblemManagement+' => 'Управление проблемами',
|
||||
'Menu:Problem:Shortcuts' => 'Ярлыки',
|
||||
'Menu:NewError' => 'Новая известная ошибка',
|
||||
'Menu:NewError+' => 'Создание новой известной ошибки',
|
||||
'Menu:SearchError' => 'Поиск известных ошибок',
|
||||
'Menu:SearchError+' => 'Поиск известных ошибок',
|
||||
'Menu:Problem:KnownErrors' => 'Все известные ошибки',
|
||||
'Menu:Problem:KnownErrors+' => 'Все известные ошибки',
|
||||
'Menu:FAQCategory' => 'FAQ categories~~',
|
||||
'Menu:FAQCategory+' => '',
|
||||
'Menu:FAQ' => 'FAQs~~',
|
||||
'Menu:FAQ+' => '',
|
||||
'Class:KnownError/Attribute:cust_name' => 'Имя клиента',
|
||||
'Class:KnownError/Attribute:cust_name+' => '',
|
||||
'Class:KnownError/Attribute:problem_ref' => 'Ссылка',
|
||||
'Class:KnownError/Attribute:problem_ref+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_name' => 'CI name~~',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_name+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_name' => 'Error name~~',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_name+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:document_name' => 'Document Name~~',
|
||||
'Class:lnkDocumentToError/Attribute:document_name+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:error_name' => 'Error name~~',
|
||||
'Class:lnkDocumentToError/Attribute:error_name+' => '',
|
||||
'Class:FAQ/Attribute:category_name' => 'Category name~~',
|
||||
'Class:FAQ/Attribute:category_name+' => '',
|
||||
'Class:KnownError/Attribute:document_list+' => 'Связанные документы',
|
||||
));
|
||||
?>
|
||||
|
||||
//
|
||||
// Class: lnkErrorToFunctionalCI
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkErrorToFunctionalCI' => 'Связь Известная ошибка/Функциональная КЕ',
|
||||
'Class:lnkErrorToFunctionalCI+' => 'Infra related to a known error',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id' => 'КЕ',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_name' => 'Имя КЕ',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_name+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_id' => 'Известная ошибка',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_id+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_name' => 'Имя известной ошибки',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:error_name+' => '',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:reason' => 'Причина',
|
||||
'Class:lnkErrorToFunctionalCI/Attribute:reason+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkDocumentToError
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkDocumentToError' => 'Связь Документ/Известная ошибка',
|
||||
'Class:lnkDocumentToError+' => 'A link between a document and a known error',
|
||||
'Class:lnkDocumentToError/Attribute:document_id' => 'Документ',
|
||||
'Class:lnkDocumentToError/Attribute:document_id+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:document_name' => 'Имя документа',
|
||||
'Class:lnkDocumentToError/Attribute:document_name+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:error_id' => 'Известная ошибка',
|
||||
'Class:lnkDocumentToError/Attribute:error_id+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:error_name' => 'Часто задаваемые вопросы',
|
||||
'Class:lnkDocumentToError/Attribute:error_name+' => '',
|
||||
'Class:lnkDocumentToError/Attribute:link_type' => 'Тип связи',
|
||||
'Class:lnkDocumentToError/Attribute:link_type+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: FAQ
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:FAQ' => 'FAQ',
|
||||
'Class:FAQ+' => 'Часто задаваемые вопросы',
|
||||
'Class:FAQ/Attribute:title' => 'Название',
|
||||
'Class:FAQ/Attribute:title+' => '',
|
||||
'Class:FAQ/Attribute:summary' => 'Краткое содержание',
|
||||
'Class:FAQ/Attribute:summary+' => '',
|
||||
'Class:FAQ/Attribute:description' => 'Описание',
|
||||
'Class:FAQ/Attribute:description+' => '',
|
||||
'Class:FAQ/Attribute:category_id' => 'Категория',
|
||||
'Class:FAQ/Attribute:category_id+' => '',
|
||||
'Class:FAQ/Attribute:category_name' => 'Имя категории',
|
||||
'Class:FAQ/Attribute:category_name+' => '',
|
||||
'Class:FAQ/Attribute:error_code' => 'Код ошибки',
|
||||
'Class:FAQ/Attribute:error_code+' => '',
|
||||
'Class:FAQ/Attribute:key_words' => 'Ключевые слова',
|
||||
'Class:FAQ/Attribute:key_words+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: FAQCategory
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:FAQCategory' => 'Категории ЧаВо',
|
||||
'Class:FAQCategory+' => 'Category for FAQ',
|
||||
'Class:FAQCategory/Attribute:name' => 'Имя',
|
||||
'Class:FAQCategory/Attribute:name+' => '',
|
||||
'Class:FAQCategory/Attribute:faq_list' => 'ЧаВо',
|
||||
'Class:FAQCategory/Attribute:faq_list+' => 'All the frequently asked questions related to this category',
|
||||
));
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Menu:ProblemManagement' => 'Problem Management',
|
||||
'Menu:ProblemManagement+' => 'Problem Management',
|
||||
'Menu:Problem:Shortcuts' => 'Shortcuts',
|
||||
'Menu:NewError' => 'Создать известную ошибку',
|
||||
'Menu:NewError+' => 'Creation of a new known error',
|
||||
'Menu:SearchError' => 'Найти известную ошибку',
|
||||
'Menu:SearchError+' => 'Search for known errors',
|
||||
'Menu:Problem:KnownErrors' => 'Известные ошибки',
|
||||
'Menu:Problem:KnownErrors+' => 'База известных ошибок',
|
||||
'Menu:FAQCategory' => 'Категории FAQ',
|
||||
'Menu:FAQCategory+' => 'Категории FAQ',
|
||||
'Menu:FAQ' => 'FAQ',
|
||||
'Menu:FAQ+' => 'Часто задаваемые вопросы',
|
||||
|
||||
));
|
||||
?>
|
||||
|
||||
@@ -504,13 +504,6 @@
|
||||
{
|
||||
// Compute the priority of the ticket
|
||||
$this->Set('priority', $this->ComputePriority());
|
||||
|
||||
if ($this->IsNew())
|
||||
{
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
$sName = sprintf('P-%06d', $iKey);
|
||||
$this->Set('ref', $sName);
|
||||
}
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="OnInsert">
|
||||
|
||||
@@ -1,28 +1,80 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Classes in 'bizmodel'
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
|
||||
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Menu:ProblemManagement' => 'Управление проблемами',
|
||||
'Menu:ProblemManagement+' => 'Управление проблемами',
|
||||
'Menu:Problem:Overview' => 'Обзор',
|
||||
'Menu:Problem:Overview+' => 'Overview',
|
||||
'Menu:NewProblem' => 'Создать проблему',
|
||||
'Menu:NewProblem+' => 'Новая проблема',
|
||||
'Menu:SearchProblems' => 'Найти проблему',
|
||||
'Menu:SearchProblems+' => 'Search for problems',
|
||||
'Menu:Problem:Shortcuts' => 'Ярлыки',
|
||||
'Menu:Problem:MyProblems' => 'Назначенные мне проблемы',
|
||||
'Menu:Problem:MyProblems+' => 'Мои проблемы',
|
||||
'Menu:Problem:OpenProblems' => 'Открытые проблемы',
|
||||
'Menu:Problem:OpenProblems+' => 'Все открытые проблемы',
|
||||
'UI-ProblemManagementOverview-ProblemByService' => 'Проблемы по сервису',
|
||||
'UI-ProblemManagementOverview-ProblemByService+' => 'Проблемы по сервису',
|
||||
'UI-ProblemManagementOverview-ProblemByPriority' => 'Проблемы по приоритету',
|
||||
'UI-ProblemManagementOverview-ProblemByPriority+' => 'Проблемы по приоритету',
|
||||
'UI-ProblemManagementOverview-ProblemUnassigned' => 'Неназначенные проблемы',
|
||||
'UI-ProblemManagementOverview-ProblemUnassigned+' => 'Неназначенные проблемы',
|
||||
'UI:ProblemMgmtMenuOverview:Title' => 'Панель управления проблемами',
|
||||
'UI:ProblemMgmtMenuOverview:Title+' => 'Панель управления проблемами',
|
||||
|
||||
));
|
||||
//
|
||||
// Class: Problem
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Problem' => 'Проблема',
|
||||
'Class:Problem+' => '',
|
||||
@@ -30,7 +82,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Problem/Attribute:status+' => '',
|
||||
'Class:Problem/Attribute:status/Value:new' => 'Новая',
|
||||
'Class:Problem/Attribute:status/Value:new+' => '',
|
||||
'Class:Problem/Attribute:status/Value:assigned' => 'Подписана',
|
||||
'Class:Problem/Attribute:status/Value:assigned' => 'Назначена',
|
||||
'Class:Problem/Attribute:status/Value:assigned+' => '',
|
||||
'Class:Problem/Attribute:status/Value:resolved' => 'Решена',
|
||||
'Class:Problem/Attribute:status/Value:resolved+' => '',
|
||||
@@ -38,82 +90,62 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Problem/Attribute:status/Value:closed+' => '',
|
||||
'Class:Problem/Attribute:service_id' => 'Услуга',
|
||||
'Class:Problem/Attribute:service_id+' => '',
|
||||
'Class:Problem/Attribute:servicesubcategory_id' => 'Категория услуги',
|
||||
'Class:Problem/Attribute:service_name' => 'Имя услуги',
|
||||
'Class:Problem/Attribute:service_name+' => '',
|
||||
'Class:Problem/Attribute:servicesubcategory_id' => 'Тип запроса',
|
||||
'Class:Problem/Attribute:servicesubcategory_id+' => '',
|
||||
'Class:Problem/Attribute:servicesubcategory_name' => 'Тип запроса',
|
||||
'Class:Problem/Attribute:servicesubcategory_name+' => '',
|
||||
'Class:Problem/Attribute:product' => 'Продукт',
|
||||
'Class:Problem/Attribute:product+' => '',
|
||||
'Class:Problem/Attribute:impact' => 'Воздействие',
|
||||
'Class:Problem/Attribute:impact' => 'Влияние',
|
||||
'Class:Problem/Attribute:impact+' => '',
|
||||
'Class:Problem/Attribute:impact/Value:1' => 'Лицо',
|
||||
'Class:Problem/Attribute:impact/Value:1' => 'Услуга',
|
||||
'Class:Problem/Attribute:impact/Value:1+' => '',
|
||||
'Class:Problem/Attribute:impact/Value:2' => 'Сервис',
|
||||
'Class:Problem/Attribute:impact/Value:2' => 'Отдел',
|
||||
'Class:Problem/Attribute:impact/Value:2+' => '',
|
||||
'Class:Problem/Attribute:impact/Value:3' => 'Департамент',
|
||||
'Class:Problem/Attribute:impact/Value:3' => 'Персона',
|
||||
'Class:Problem/Attribute:impact/Value:3+' => '',
|
||||
'Class:Problem/Attribute:urgency' => 'Срочность',
|
||||
'Class:Problem/Attribute:urgency+' => '',
|
||||
'Class:Problem/Attribute:urgency/Value:1' => 'Низкая',
|
||||
'Class:Problem/Attribute:urgency/Value:1+' => 'Низкая',
|
||||
'Class:Problem/Attribute:urgency/Value:2' => 'Средняя',
|
||||
'Class:Problem/Attribute:urgency/Value:2+' => 'Средняя',
|
||||
'Class:Problem/Attribute:urgency/Value:3' => 'Высокая',
|
||||
'Class:Problem/Attribute:urgency/Value:3+' => 'Высокая',
|
||||
'Class:Problem/Attribute:urgency/Value:4' => 'low~~',
|
||||
'Class:Problem/Attribute:urgency/Value:4+' => '',
|
||||
'Class:Problem/Attribute:urgency/Value:1' => 'Критическая',
|
||||
'Class:Problem/Attribute:urgency/Value:1+' => 'critical',
|
||||
'Class:Problem/Attribute:urgency/Value:2' => 'Высокая',
|
||||
'Class:Problem/Attribute:urgency/Value:2+' => 'high',
|
||||
'Class:Problem/Attribute:urgency/Value:3' => 'Средняя',
|
||||
'Class:Problem/Attribute:urgency/Value:3+' => 'medium',
|
||||
'Class:Problem/Attribute:urgency/Value:4' => 'Низкая',
|
||||
'Class:Problem/Attribute:urgency/Value:4+' => 'low',
|
||||
'Class:Problem/Attribute:priority' => 'Приоритет',
|
||||
'Class:Problem/Attribute:priority+' => '',
|
||||
'Class:Problem/Attribute:priority/Value:1' => 'Низкий',
|
||||
'Class:Problem/Attribute:priority/Value:1+' => '',
|
||||
'Class:Problem/Attribute:priority/Value:2' => 'Средний',
|
||||
'Class:Problem/Attribute:priority/Value:2+' => '',
|
||||
'Class:Problem/Attribute:priority/Value:3' => 'Высокий',
|
||||
'Class:Problem/Attribute:priority/Value:3+' => '',
|
||||
'Class:Problem/Attribute:priority/Value:4' => 'Low~~',
|
||||
'Class:Problem/Attribute:priority/Value:4+' => '',
|
||||
'Class:Problem/Attribute:related_change_id' => 'Связанные изменения',
|
||||
'Class:Problem/Attribute:priority/Value:1' => 'Критический',
|
||||
'Class:Problem/Attribute:priority/Value:1+' => 'Critical',
|
||||
'Class:Problem/Attribute:priority/Value:2' => 'Высокий',
|
||||
'Class:Problem/Attribute:priority/Value:2+' => 'High',
|
||||
'Class:Problem/Attribute:priority/Value:3' => 'Средний',
|
||||
'Class:Problem/Attribute:priority/Value:3+' => 'Medium',
|
||||
'Class:Problem/Attribute:priority/Value:4' => 'Низкий',
|
||||
'Class:Problem/Attribute:priority/Value:4+' => 'Low',
|
||||
'Class:Problem/Attribute:related_change_id' => 'Связанное изменение',
|
||||
'Class:Problem/Attribute:related_change_id+' => '',
|
||||
'Class:Problem/Attribute:assignment_date' => 'Дата назначения',
|
||||
'Class:Problem/Attribute:related_change_ref' => 'Ссылка на изменение',
|
||||
'Class:Problem/Attribute:related_change_ref+' => '',
|
||||
'Class:Problem/Attribute:assignment_date' => 'Назначение',
|
||||
'Class:Problem/Attribute:assignment_date+' => '',
|
||||
'Class:Problem/Attribute:resolution_date' => 'Дата решения',
|
||||
'Class:Problem/Attribute:resolution_date' => 'Решение',
|
||||
'Class:Problem/Attribute:resolution_date+' => '',
|
||||
'Class:Problem/Attribute:knownerrors_list' => 'Известные ошибки',
|
||||
'Class:Problem/Attribute:knownerrors_list+' => '',
|
||||
'Class:Problem/Attribute:related_request_list' => 'Related requests~~',
|
||||
'Class:Problem/Attribute:related_request_list+' => '',
|
||||
'Class:Problem/Attribute:knownerrors_list+' => 'Связанные известные ошибки',
|
||||
'Class:Problem/Attribute:related_request_list' => 'Запросы',
|
||||
'Class:Problem/Attribute:related_request_list+' => 'Связанные запросы',
|
||||
'Class:Problem/Stimulus:ev_assign' => 'Назначить',
|
||||
'Class:Problem/Stimulus:ev_assign+' => '',
|
||||
'Class:Problem/Stimulus:ev_reassign' => 'Переназначить',
|
||||
'Class:Problem/Stimulus:ev_reassign+' => '',
|
||||
'Class:Problem/Stimulus:ev_resolve' => 'Решение',
|
||||
'Class:Problem/Stimulus:ev_resolve' => 'Отметить как решенную',
|
||||
'Class:Problem/Stimulus:ev_resolve+' => '',
|
||||
'Class:Problem/Stimulus:ev_close' => 'Закрыть',
|
||||
'Class:Problem/Stimulus:ev_close+' => '',
|
||||
'Menu:ProblemManagement' => 'Управление проблемами',
|
||||
'Menu:ProblemManagement+' => 'Управление проблемами',
|
||||
'Menu:Problem:Overview' => 'Обзор',
|
||||
'Menu:Problem:Overview+' => 'Обзор',
|
||||
'Menu:NewProblem' => 'Новая проблема',
|
||||
'Menu:NewProblem+' => 'Новая проблема',
|
||||
'Menu:SearchProblems' => 'Поиск проблем',
|
||||
'Menu:SearchProblems+' => 'Поиск проблем',
|
||||
'Menu:Problem:Shortcuts' => 'Ярлыки',
|
||||
'Menu:Problem:MyProblems' => 'Мои проблемы',
|
||||
'Menu:Problem:MyProblems+' => 'Мои проблемы',
|
||||
'Menu:Problem:OpenProblems' => 'Все открытые проблемы',
|
||||
'Menu:Problem:OpenProblems+' => 'Все открытые проблемы',
|
||||
'UI-ProblemManagementOverview-ProblemByService' => 'Проблемы по сервису',
|
||||
'UI-ProblemManagementOverview-ProblemByService+' => 'Проблемы по сервису',
|
||||
'UI-ProblemManagementOverview-ProblemByPriority' => 'Проблемы по приоритету',
|
||||
'UI-ProblemManagementOverview-ProblemByPriority+' => 'Проблемы по приоритету',
|
||||
'UI-ProblemManagementOverview-ProblemUnassigned' => 'Неназначенные проблемы',
|
||||
'UI-ProblemManagementOverview-ProblemUnassigned+' => 'Неназначенные проблемы',
|
||||
'UI:ProblemMgmtMenuOverview:Title' => 'Панель управление проблемами',
|
||||
'UI:ProblemMgmtMenuOverview:Title+' => 'Панель управление проблемами',
|
||||
'Class:Problem/Attribute:service_name' => 'Название',
|
||||
'Class:Problem/Attribute:service_name+' => '',
|
||||
'Class:Problem/Attribute:servicesubcategory_name' => 'Название',
|
||||
'Class:Problem/Attribute:servicesubcategory_name+' => '',
|
||||
'Class:Problem/Attribute:related_change_ref' => 'Ссылка',
|
||||
'Class:Problem/Attribute:related_change_ref+' => '',
|
||||
));
|
||||
?>
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
|
||||
<constants>
|
||||
<constant id="PORTAL_POWER_USER_PROFILE" xsi:type="string" _delta="define"><![CDATA[Portal power user]]></constant>
|
||||
<constant id="PORTAL_SERVICECATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_SERVICE_SUBCATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT ServiceSubcategory WHERE service_id = :svc_id AND ServiceSubcategory.status != "obsolete"]]></constant>
|
||||
<constant id="PORTAL_VALIDATE_SERVICECATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.id = :id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_VALIDATE_SERVICESUBCATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT ServiceSubcategory AS Sub JOIN Service AS Svc ON Sub.service_id = Svc.id WHERE Sub.id=:id AND Sub.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_ALL_PARAMS" xsi:type="string" _delta="define"><![CDATA[from_service_id,org_id,caller_id,service_id,servicesubcategory_id,title,description,impact,emergency,moreinfo,caller_id,start_date,end_date,duration,impact_duration]]></constant>
|
||||
<constant id="PORTAL_SET_TYPE_FROM" xsi:type="string" _delta="define"><![CDATA[request_type]]></constant>
|
||||
<constant id="PORTAL_TYPE_TO_CLASS" xsi:type="string" _delta="define"><![CDATA[{"service_request":"UserRequest","incident":"Incident"}]]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_CRITERIA" xsi:type="string" _delta="define"><![CDATA[ref,start_date,close_date,service_id,caller_id]]></constant>
|
||||
<constant id="PORTAL_TYPE_TO_CLASS" xsi:type="string" _delta="redefine"><![CDATA[{"service_request":"UserRequest","incident":"Incident"}]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_PUBLIC_LOG" xsi:type="string" _delta="define"><![CDATA[public_log]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_USER_COMMENT" xsi:type="string" _delta="define"><![CDATA[user_comment]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_FORM_ATTRIBUTES" xsi:type="string" _delta="define"><![CDATA[title,description,impact,urgency]]></constant>
|
||||
@@ -17,15 +9,8 @@
|
||||
<constant id="PORTAL_USERREQUEST_LIST_ZLIST" xsi:type="string" _delta="define"><![CDATA[finalclass,title,start_date,status,servicesubcategory_id,priority,caller_id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_CLOSED_ZLIST" xsi:type="string" _delta="define"><![CDATA[title,start_date,close_date,servicesubcategory_id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_DETAILS_ZLIST" xsi:type="string" _delta="define"><![CDATA[{"col:left":["ref","caller_id","servicesubcategory_id","title","description","solution"],"col:right":["status","priority","start_date","resolution_date","last_update","agent_id"]}]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_PUBLIC_LOG" xsi:type="string" _delta="define"><![CDATA[public_log]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_USER_COMMENT" xsi:type="string" _delta="define"><![CDATA[user_comment]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_FORM_ATTRIBUTES" xsi:type="string" _delta="define"><![CDATA[title,description,impact,urgency]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_TYPE" xsi:type="string" _delta="define"><![CDATA[]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_LIST_ZLIST" xsi:type="string" _delta="define"><![CDATA[finalclass,title,start_date,status,servicesubcategory_id,priority,caller_id]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_CLOSED_ZLIST" xsi:type="string" _delta="define"><![CDATA[title,start_date,close_date,servicesubcategory_id]]></constant>
|
||||
<constant id="PORTAL_INCIDENT_DETAILS_ZLIST" xsi:type="string" _delta="define"><![CDATA[{"col:left":["ref","caller_id","servicesubcategory_id","title","description","solution"],"col:right":["status","priority","start_date","resolution_date","last_update","agent_id"]}]]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_FILTER_service_id" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_FILTER_caller_id" xsi:type="string" _delta="define"><![CDATA[SELECT Person WHERE org_id = :org_id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_DISPLAY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT UserRequest WHERE org_id = :contact->org_id AND caller_id = :contact->id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_DISPLAY_POWERUSER_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT UserRequest WHERE org_id = :contact->org_id]]></constant>
|
||||
</constants>
|
||||
<classes>
|
||||
<class id="UserRequest" _delta="define">
|
||||
@@ -281,7 +266,7 @@
|
||||
</field>
|
||||
<field id="sla_tto_passed" xsi:type="AttributeSubItem">
|
||||
<target_attcode>tto</target_attcode>
|
||||
<item_code>100_passed</item_code>
|
||||
<item_code>100_triggered</item_code>
|
||||
</field>
|
||||
<field id="sla_tto_over" xsi:type="AttributeSubItem">
|
||||
<target_attcode>tto</target_attcode>
|
||||
@@ -293,7 +278,7 @@
|
||||
</field>
|
||||
<field id="sla_ttr_passed" xsi:type="AttributeSubItem">
|
||||
<target_attcode>ttr</target_attcode>
|
||||
<item_code>100_passed</item_code>
|
||||
<item_code>100_triggered</item_code>
|
||||
</field>
|
||||
<field id="sla_ttr_over" xsi:type="AttributeSubItem">
|
||||
<target_attcode>ttr</target_attcode>
|
||||
@@ -677,7 +662,7 @@
|
||||
<hidden/>
|
||||
</attribute>
|
||||
<attribute id="last_pending_date">
|
||||
<hidden/>
|
||||
<hidden/>
|
||||
</attribute>
|
||||
<attribute id="time_spent">
|
||||
<hidden/>
|
||||
@@ -1682,14 +1667,6 @@
|
||||
// Compute the priority of the ticket
|
||||
$this->Set('priority', $this->ComputePriority());
|
||||
|
||||
if ($this->IsNew())
|
||||
{
|
||||
// Object not yet in the Database
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
$sName = sprintf('R-%06d', $iKey);
|
||||
$this->Set('ref', $sName);
|
||||
}
|
||||
|
||||
return parent::ComputeValues();
|
||||
}]]></code>
|
||||
</method>
|
||||
@@ -2304,7 +2281,7 @@
|
||||
<rank>0</rank>
|
||||
<title>Menu:RequestManagement</title>
|
||||
<icon>itop-welcome-itil/images/user-request-deadline.png</icon>
|
||||
<subtitle>Open Requests</subtitle>
|
||||
<subtitle>Menu:UserRequest:OpenRequests</subtitle>
|
||||
<query>SELECT UserRequest WHERE status != "closed"</query>
|
||||
<group_by>status</group_by>
|
||||
<values>new,assigned,escalated_tto,escalated_ttr,resolved</values>
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Menu:RequestManagement' => 'Gerenciamento Solicitações',
|
||||
'Menu:RequestManagement+' => 'Gerenciamento Solicitações',
|
||||
'Menu:RequestManagementProvider' => 'Provedor de Solicitações',
|
||||
'Menu:RequestManagementProvider+' => 'Provedor de Solicitações',
|
||||
'Menu:UserRequest:Provider' => 'Solicitações abertas transferidas para provedor',
|
||||
'Menu:UserRequest:Provider+' => 'Solicitações abertas transferidas para provedor',
|
||||
'Menu:UserRequest:Overview' => 'Visão geral',
|
||||
'Menu:UserRequest:Overview+' => 'Visão geral',
|
||||
'Menu:NewUserRequest' => 'Nova solicitação',
|
||||
'Menu:NewUserRequest+' => 'Criar uma nova solicitação',
|
||||
'Menu:SearchUserRequests' => 'Pesquisar por solicitação',
|
||||
'Menu:SearchUserRequests+' => 'Pesquisar por solicitação',
|
||||
'Menu:UserRequest:Shortcuts' => 'Atalho',
|
||||
'Menu:UserRequest:Shortcuts+' => '',
|
||||
'Menu:UserRequest:MyRequests' => 'Solicitações abertas por mim',
|
||||
'Menu:UserRequest:MyRequests+' => 'Solicitações abertas por mim (como agente)',
|
||||
'Menu:UserRequest:MySupportRequests' => "Minhas solicitações de suporte",
|
||||
'Menu:UserRequest:MySupportRequests+' => "Minhas solicitações de suporte",
|
||||
'Menu:UserRequest:EscalatedRequests' => 'Hot Requests',
|
||||
'Menu:UserRequest:EscalatedRequests+' => 'Hot Requests',
|
||||
'Menu:UserRequest:OpenRequests' => 'Todas solicitações abertas',
|
||||
'Menu:UserRequest:OpenRequests+' => 'Todas solicitações abertas',
|
||||
'UI:WelcomeMenu:MyAssignedCalls' => 'Solicitações atribuidas a mim',
|
||||
'UI-RequestManagementOverview-RequestByType-last-14-days' => 'Solicitações dos últimos 14 dias por tipo',
|
||||
'UI-RequestManagementOverview-Last-14-days' => 'Número de solicitações dos últimos 14 dias',
|
||||
'UI-RequestManagementOverview-OpenRequestByStatus' => 'Solicitações abertas por status',
|
||||
'UI-RequestManagementOverview-OpenRequestByAgent' => 'Solicitações abertas por agente',
|
||||
'UI-RequestManagementOverview-OpenRequestByType' => 'Solicitações abertas por tipo',
|
||||
'UI-RequestManagementOverview-OpenRequestByCustomer' => 'Solicitações abertas por cliente',
|
||||
'Class:UserRequest:KnownErrorList' => 'Erros conhecidos',
|
||||
));
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserRequest
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:UserRequest' => 'Solicitação usuário',
|
||||
'Class:UserRequest+' => '',
|
||||
'Class:UserRequest/Attribute:status' => 'Estado',
|
||||
'Class:UserRequest/Attribute:status+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:new' => 'Nova',
|
||||
'Class:UserRequest/Attribute:status/Value:new+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_tto' => 'TTO escalado',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_tto+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:assigned' => 'Atribuído',
|
||||
'Class:UserRequest/Attribute:status/Value:assigned+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_ttr' => 'TTR escalado',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_ttr+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:waiting_for_approval' => 'Aguardando aprovação',
|
||||
'Class:UserRequest/Attribute:status/Value:waiting_for_approval+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:approved' => 'Aprovado',
|
||||
'Class:UserRequest/Attribute:status/Value:approved+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:rejected' => 'Rejeitado',
|
||||
'Class:UserRequest/Attribute:status/Value:rejected+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:pending' => 'Pendência',
|
||||
'Class:UserRequest/Attribute:status/Value:pending+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:resolved' => 'Resolvido',
|
||||
'Class:UserRequest/Attribute:status/Value:resolved+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:closed' => 'Fechado',
|
||||
'Class:UserRequest/Attribute:status/Value:closed+' => '',
|
||||
'Class:UserRequest/Attribute:request_type' => 'Tipo solicitação',
|
||||
'Class:UserRequest/Attribute:request_type+' => '',
|
||||
'Class:UserRequest/Attribute:request_type/Value:service_request' => 'Solicitação serviço',
|
||||
'Class:UserRequest/Attribute:request_type/Value:service_request+' => 'Solicitação serviço',
|
||||
'Class:UserRequest/Attribute:impact' => 'Impacto',
|
||||
'Class:UserRequest/Attribute:impact+' => '',
|
||||
'Class:UserRequest/Attribute:impact/Value:1' => 'Um departamento',
|
||||
'Class:UserRequest/Attribute:impact/Value:1+' => '',
|
||||
'Class:UserRequest/Attribute:impact/Value:2' => 'Um serviço',
|
||||
'Class:UserRequest/Attribute:impact/Value:2+' => '',
|
||||
'Class:UserRequest/Attribute:impact/Value:3' => 'Uma pessoa',
|
||||
'Class:UserRequest/Attribute:impact/Value:3+' => '',
|
||||
'Class:UserRequest/Attribute:priority' => 'Prioridade',
|
||||
'Class:UserRequest/Attribute:priority+' => '',
|
||||
'Class:UserRequest/Attribute:priority/Value:1' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:priority/Value:1+' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:priority/Value:2' => 'Alta',
|
||||
'Class:UserRequest/Attribute:priority/Value:2+' => 'Alta',
|
||||
'Class:UserRequest/Attribute:priority/Value:3' => 'Média',
|
||||
'Class:UserRequest/Attribute:priority/Value:3+' => 'Média',
|
||||
'Class:UserRequest/Attribute:priority/Value:4' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:priority/Value:4+' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:urgency' => 'Urgência',
|
||||
'Class:UserRequest/Attribute:urgency+' => '',
|
||||
'Class:UserRequest/Attribute:urgency/Value:1' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:urgency/Value:1+' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:urgency/Value:2' => 'Alta',
|
||||
'Class:UserRequest/Attribute:urgency/Value:2+' => 'Alta',
|
||||
'Class:UserRequest/Attribute:urgency/Value:3' => 'Média',
|
||||
'Class:UserRequest/Attribute:urgency/Value:3+' => 'Média',
|
||||
'Class:UserRequest/Attribute:urgency/Value:4' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:urgency/Value:4+' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:origin' => 'Origem',
|
||||
'Class:UserRequest/Attribute:origin+' => '',
|
||||
'Class:UserRequest/Attribute:origin/Value:mail' => 'Email',
|
||||
'Class:UserRequest/Attribute:origin/Value:mail+' => 'Email',
|
||||
'Class:UserRequest/Attribute:origin/Value:monitoring' => 'Monitoramento',
|
||||
'Class:UserRequest/Attribute:origin/Value:monitoring+' => 'Monitoramento',
|
||||
'Class:UserRequest/Attribute:origin/Value:phone' => 'Telefone',
|
||||
'Class:UserRequest/Attribute:origin/Value:phone+' => 'Telefone',
|
||||
'Class:UserRequest/Attribute:origin/Value:portal' => 'Portal',
|
||||
'Class:UserRequest/Attribute:origin/Value:portal+' => 'Portal',
|
||||
'Class:UserRequest/Attribute:approver_id' => 'Aprovador',
|
||||
'Class:UserRequest/Attribute:approver_id+' => '',
|
||||
'Class:UserRequest/Attribute:approver_email' => 'Email aprovador',
|
||||
'Class:UserRequest/Attribute:approver_email+' => '',
|
||||
'Class:UserRequest/Attribute:service_id' => 'Serviço',
|
||||
'Class:UserRequest/Attribute:service_id+' => '',
|
||||
'Class:UserRequest/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:UserRequest/Attribute:service_name+' => '',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_id' => 'Sub-categoria serviço',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_id+' => '',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_name' => 'Nome Sub-categoria serviço',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_name+' => '',
|
||||
'Class:UserRequest/Attribute:escalation_flag' => 'Alerta vermelho',
|
||||
'Class:UserRequest/Attribute:escalation_flag+' => '',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:no' => 'Não',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:no+' => 'Não',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:yes' => 'Sim',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:yes+' => 'Sim',
|
||||
'Class:UserRequest/Attribute:escalation_reason' => 'Hot reason',
|
||||
'Class:UserRequest/Attribute:escalation_reason+' => '',
|
||||
'Class:UserRequest/Attribute:assignment_date' => 'Data atribuição',
|
||||
'Class:UserRequest/Attribute:assignment_date+' => '',
|
||||
'Class:UserRequest/Attribute:resolution_date' => 'Data resolução',
|
||||
'Class:UserRequest/Attribute:resolution_date+' => '',
|
||||
'Class:UserRequest/Attribute:last_pending_date' => 'Última data pendente',
|
||||
'Class:UserRequest/Attribute:last_pending_date+' => '',
|
||||
'Class:UserRequest/Attribute:cumulatedpending' => 'Pendências acumuladas',
|
||||
'Class:UserRequest/Attribute:cumulatedpending+' => '',
|
||||
'Class:UserRequest/Attribute:tto' => 'TTO',
|
||||
'Class:UserRequest/Attribute:tto+' => '',
|
||||
'Class:UserRequest/Attribute:ttr' => 'TTR',
|
||||
'Class:UserRequest/Attribute:ttr+' => '',
|
||||
'Class:UserRequest/Attribute:tto_escalation_deadline' => 'Prazo determinado TTO',
|
||||
'Class:UserRequest/Attribute:tto_escalation_deadline+' => '',
|
||||
'Class:UserRequest/Attribute:sla_tto_passed' => 'SLA TTO passou',
|
||||
'Class:UserRequest/Attribute:sla_tto_passed+' => '',
|
||||
'Class:UserRequest/Attribute:sla_tto_over' => 'SLA TTO acima',
|
||||
'Class:UserRequest/Attribute:sla_tto_over+' => '',
|
||||
'Class:UserRequest/Attribute:ttr_escalation_deadline' => 'Prazo determinado TTR',
|
||||
'Class:UserRequest/Attribute:ttr_escalation_deadline+' => '',
|
||||
'Class:UserRequest/Attribute:sla_ttr_passed' => 'SLA TTR passou',
|
||||
'Class:UserRequest/Attribute:sla_ttr_passed+' => '',
|
||||
'Class:UserRequest/Attribute:sla_ttr_over' => 'SLA TTR acima',
|
||||
'Class:UserRequest/Attribute:sla_ttr_over+' => '',
|
||||
'Class:UserRequest/Attribute:time_spent' => 'Atraso resolução',
|
||||
'Class:UserRequest/Attribute:time_spent+' => '',
|
||||
'Class:UserRequest/Attribute:resolution_code' => 'Código resolução',
|
||||
'Class:UserRequest/Attribute:resolution_code+' => '',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:assistance' => 'Assistência',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:assistance+' => 'Assistência',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:bug fixed' => 'Bug corrigido',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:bug fixed+' => 'Bug corrigido',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:hardware repair' => 'Hardware reparado',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:hardware repair+' => 'Hardware reparado',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:other' => 'Outro',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:other+' => 'Outro',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:software patch' => 'Software patch',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:software patch+' => 'Software patch',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:system update' => 'Atualização sistema',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:system update+' => 'Atualização sistema',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:training' => 'Treinamento',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:training+' => 'Treinamento',
|
||||
'Class:UserRequest/Attribute:solution' => 'Solução',
|
||||
'Class:UserRequest/Attribute:solution+' => '',
|
||||
'Class:UserRequest/Attribute:pending_reason' => 'Razão pendência',
|
||||
'Class:UserRequest/Attribute:pending_reason+' => '',
|
||||
'Class:UserRequest/Attribute:parent_request_id' => 'Solicitação principal',
|
||||
'Class:UserRequest/Attribute:parent_request_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_incident_id' => 'Incidente principal',
|
||||
'Class:UserRequest/Attribute:parent_incident_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_request_ref' => 'Ref solitação',
|
||||
'Class:UserRequest/Attribute:parent_request_ref+' => '',
|
||||
'Class:UserRequest/Attribute:parent_problem_id' => 'Problema principal',
|
||||
'Class:UserRequest/Attribute:parent_problem_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_problem_ref' => 'Ref problema',
|
||||
'Class:UserRequest/Attribute:parent_problem_ref+' => '',
|
||||
'Class:UserRequest/Attribute:parent_change_id' => 'Mudança principal',
|
||||
'Class:UserRequest/Attribute:parent_change_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_change_ref' => 'Ref mudança',
|
||||
'Class:UserRequest/Attribute:parent_change_ref+' => '',
|
||||
'Class:UserRequest/Attribute:related_request_list' => 'Sub-Solicitação',
|
||||
'Class:UserRequest/Attribute:related_request_list+' => 'Todas as solicitações vinculadas a essa solicitação principal',
|
||||
'Class:UserRequest/Attribute:public_log' => 'Log público',
|
||||
'Class:UserRequest/Attribute:public_log+' => '',
|
||||
'Class:UserRequest/Attribute:user_satisfaction' => 'Satisfação do usuário',
|
||||
'Class:UserRequest/Attribute:user_satisfaction+' => '',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:1' => 'Muito satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:1+' => 'Muito satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:2' => 'Bastante satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:2+' => 'Bastante satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:3' => 'Bastante insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:3+' => 'Bastante insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:4' => 'Muito insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:4+' => 'Muito insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_comment' => 'Comentário usuário',
|
||||
'Class:UserRequest/Attribute:user_comment+' => '',
|
||||
'Class:UserRequest/Attribute:parent_request_id_friendlyname' => 'parent_request_id_friendlyname',
|
||||
'Class:UserRequest/Attribute:parent_request_id_friendlyname+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_assign' => 'Atribuir',
|
||||
'Class:UserRequest/Stimulus:ev_assign+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_reassign' => 'Re-atribuir',
|
||||
'Class:UserRequest/Stimulus:ev_reassign+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_approve' => 'Aprovar',
|
||||
'Class:UserRequest/Stimulus:ev_approve+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_reject' => 'Rejeitar',
|
||||
'Class:UserRequest/Stimulus:ev_reject+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_pending' => 'Pendência',
|
||||
'Class:UserRequest/Stimulus:ev_pending+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_timeout' => 'Timeout',
|
||||
'Class:UserRequest/Stimulus:ev_timeout+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_autoresolve' => 'Resolvido automaticamente',
|
||||
'Class:UserRequest/Stimulus:ev_autoresolve+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_autoclose' => 'Fechado automaticamente',
|
||||
'Class:UserRequest/Stimulus:ev_autoclose+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_resolve' => 'Marcar como resolvido',
|
||||
'Class:UserRequest/Stimulus:ev_resolve+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_close' => 'Fechar esta solicitação',
|
||||
'Class:UserRequest/Stimulus:ev_close+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_reopen' => 'Re-abrir',
|
||||
'Class:UserRequest/Stimulus:ev_reopen+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_wait_for_approval' => 'Aguardar por aprovação',
|
||||
'Class:UserRequest/Stimulus:ev_wait_for_approval+' => '',
|
||||
'Class:UserRequest/Error:CannotAssignParentRequestIdToSelf' => 'Não é possível atribuir a solicitação principal para a própria solicitação',
|
||||
));
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -1,24 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
|
||||
<constants>
|
||||
<constant id="PORTAL_POWER_USER_PROFILE" xsi:type="string" _delta="define"><![CDATA[Portal power user]]></constant>
|
||||
<constant id="PORTAL_SERVICECATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_SERVICE_SUBCATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT ServiceSubcategory WHERE service_id = :svc_id AND ServiceSubcategory.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_VALIDATE_SERVICECATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.id = :id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_VALIDATE_SERVICESUBCATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT ServiceSubcategory AS Sub JOIN Service AS Svc ON Sub.service_id = Svc.id WHERE Sub.id=:id AND Sub.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_ALL_PARAMS" xsi:type="string" _delta="define"><![CDATA[from_service_id,org_id,caller_id,service_id,servicesubcategory_id,title,description,impact,emergency,moreinfo,caller_id,start_date,end_date,duration,impact_duration]]></constant>
|
||||
<constant id="PORTAL_SET_TYPE_FROM" xsi:type="string" _delta="define"><![CDATA[request_type]]></constant>
|
||||
<constant id="PORTAL_TYPE_TO_CLASS" xsi:type="string" _delta="define"><![CDATA[]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_PUBLIC_LOG" xsi:type="string" _delta="define"><![CDATA[public_log]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_USER_COMMENT" xsi:type="string" _delta="define"><![CDATA[user_comment]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_FORM_ATTRIBUTES" xsi:type="string" _delta="define"><![CDATA[title,description,impact,urgency]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_TYPE" xsi:type="string" _delta="define"><![CDATA[request_type]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_LIST_ZLIST" xsi:type="string" _delta="define"><![CDATA[finalclass,title,start_date,status,servicesubcategory_id,priority,caller_id]]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_CRITERIA" xsi:type="string" _delta="define"><![CDATA[ref,start_date,close_date,service_id,caller_id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_CLOSED_ZLIST" xsi:type="string" _delta="define"><![CDATA[title,start_date,close_date,servicesubcategory_id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_DETAILS_ZLIST" xsi:type="string" _delta="define"><![CDATA[{"col:left":["ref","caller_id","servicesubcategory_id","title","description","solution"],"col:right":["status","priority","start_date","resolution_date","last_update","agent_id"]}]]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_FILTER_service_id" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_FILTER_caller_id" xsi:type="string" _delta="define"><![CDATA[SELECT Person WHERE org_id = :org_id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_DISPLAY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT UserRequest WHERE org_id = :contact->org_id AND caller_id = :contact->id]]></constant>
|
||||
<constant id="PORTAL_USERREQUEST_DISPLAY_POWERUSER_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT UserRequest WHERE org_id = :contact->org_id]]></constant>
|
||||
</constants>
|
||||
<classes>
|
||||
<class id="UserRequest" _delta="define">
|
||||
@@ -280,7 +271,7 @@
|
||||
</field>
|
||||
<field id="sla_tto_passed" xsi:type="AttributeSubItem">
|
||||
<target_attcode>tto</target_attcode>
|
||||
<item_code>100_passed</item_code>
|
||||
<item_code>100_triggered</item_code>
|
||||
</field>
|
||||
<field id="sla_tto_over" xsi:type="AttributeSubItem">
|
||||
<target_attcode>tto</target_attcode>
|
||||
@@ -292,7 +283,7 @@
|
||||
</field>
|
||||
<field id="sla_ttr_passed" xsi:type="AttributeSubItem">
|
||||
<target_attcode>ttr</target_attcode>
|
||||
<item_code>100_passed</item_code>
|
||||
<item_code>100_triggered</item_code>
|
||||
</field>
|
||||
<field id="sla_ttr_over" xsi:type="AttributeSubItem">
|
||||
<target_attcode>ttr</target_attcode>
|
||||
@@ -1662,13 +1653,6 @@
|
||||
// Compute the priority of the ticket
|
||||
$this->Set('priority', $this->ComputePriority());
|
||||
|
||||
if ($this->IsNew())
|
||||
{
|
||||
$iKey = MetaModel::GetNextKey(get_class($this));
|
||||
$sName = sprintf('R-%06d', $iKey);
|
||||
$this->Set('ref', $sName);
|
||||
}
|
||||
|
||||
return parent::ComputeValues();
|
||||
}]]></code>
|
||||
</method>
|
||||
@@ -2275,7 +2259,7 @@
|
||||
<rank>0</rank>
|
||||
<title>Menu:RequestManagement</title>
|
||||
<icon>itop-welcome-itil/images/user-request-deadline.png</icon>
|
||||
<subtitle>Open Requests</subtitle>
|
||||
<subtitle>Menu:UserRequest:OpenRequests</subtitle>
|
||||
<query>SELECT UserRequest WHERE status != "closed"</query>
|
||||
<group_by>status</group_by>
|
||||
<values>new,assigned,escalated_tto,escalated_ttr,resolved</values>
|
||||
|
||||
@@ -253,7 +253,6 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Portal:ShowServices' => 'Service-Katalog',
|
||||
'Portal:SelectRequestType' => 'Wählen Sie den Typ der Anfrage',
|
||||
'Portal:SelectServiceElementFrom_Service' => 'Wählen Sie ein Service-Element für %1$s',
|
||||
'Portal:SelectRequestTemplate' => 'Wählen Sie eine Template für %1$s',
|
||||
'Portal:ListServices' => 'Liste der Services',
|
||||
'Portal:TitleDetailsFor_Service' => 'Details für Service',
|
||||
'Portal:Button:CreateRequestFromService' => 'EIne Benutzeranfrage betreffend dieses Diensts erzeugen',
|
||||
|
||||
@@ -275,7 +275,6 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Portal:ShowServices' => 'Service catalogue',
|
||||
'Portal:SelectRequestType' => 'Select a type of request',
|
||||
'Portal:SelectServiceElementFrom_Service' => 'Select a service element for %1$s',
|
||||
'Portal:SelectRequestTemplate' => 'Select a template for %1$s',
|
||||
'Portal:ListServices' => 'List of services',
|
||||
'Portal:TitleDetailsFor_Service' => 'Details for Service',
|
||||
'Portal:Button:CreateRequestFromService' => 'Create a Request for this service',
|
||||
|
||||
@@ -279,7 +279,6 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
|
||||
'Portal:ShowServices' => 'Catálogo de Servicios',
|
||||
'Portal:SelectRequestType' => 'Seleccione un Tipo de Solicitud',
|
||||
'Portal:SelectServiceElementFrom_Service' => 'Seleccione un Elemento de Servicio para %1$s',
|
||||
'Portal:SelectRequestTemplate' => 'Seleccione una Plantilla para %1$s',
|
||||
'Portal:ListServices' => 'Lista de Servicios',
|
||||
'Portal:TitleDetailsFor_Service' => 'Detalles para el Servicio',
|
||||
'Portal:Button:CreateRequestFromService' => 'Crear una Solicitud para este Servicio',
|
||||
|
||||
@@ -264,7 +264,6 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Portal:ShowServices' => 'Catalogue de service',
|
||||
'Portal:SelectRequestType' => 'Sélectionnez un type de requête',
|
||||
'Portal:SelectServiceElementFrom_Service' => 'Sélectionnez un élément de service pour %1$s',
|
||||
'Portal:SelectRequestTemplate' => 'Sélectionnez un modèle de requête pour %1$s',
|
||||
'Portal:ListServices' => 'Liste des services',
|
||||
'Portal:TitleDetailsFor_Service' => 'Détail d\'un service',
|
||||
'Portal:Button:CreateRequestFromService' => 'Créer une requête pour ce service',
|
||||
|
||||
@@ -250,7 +250,6 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Portal:ShowServices' => 'サービスカタログ',
|
||||
'Portal:SelectRequestType' => '要求のタイプを選択',
|
||||
'Portal:SelectServiceElementFrom_Service' => '%1$s のサービス要素を選択',
|
||||
'Portal:SelectRequestTemplate' => 'Select a template for %1$s のテンプレートを選択',
|
||||
'Portal:ListServices' => 'サービスのリスト',
|
||||
'Portal:TitleDetailsFor_Service' => 'サービスの詳細',
|
||||
'Portal:Button:CreateRequestFromService' => 'このサービスへの要求を作成',
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
<?php
|
||||
//
|
||||
// File generated by ... on the 2012-06-05T18:30:57+0200
|
||||
// Please do not edit manually
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
//
|
||||
// ben on met quoi ici ?
|
||||
// Signé: Romain
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; version 3 of the License.
|
||||
//
|
||||
// This program 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
/**
|
||||
* Classes and menus for itop-tickets (version 1.0.0)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Persistent classes for a CMDB
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
class Ticket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
'category' => 'bizmodel,searchable,structure',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => 'ref',
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array('ref'),
|
||||
'db_table' => 'ticket',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => '',
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeString("ref", array("allowed_values"=>null, "sql"=>'ref', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("organization_id", array("targetclass"=>'Organization', "allowed_values"=>null, "sql"=>'organization_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>'Person', "allowed_values"=>null, "sql"=>'caller_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("team_id", array("targetclass"=>'Team', "allowed_values"=>null, "sql"=>'team_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("agent_id", array("targetclass"=>'Person', "allowed_values"=>null, "sql"=>'agent_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("title", array("allowed_values"=>null, "sql"=>'title', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeText("description", array("allowed_values"=>null, "sql"=>'description', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("start_date", array("allowed_values"=>null, "sql"=>'start_date', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("end_date", array("allowed_values"=>null, "sql"=>'end_date', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("last_update", array("allowed_values"=>null, "sql"=>'last_update', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeDateTime("close_date", array("allowed_values"=>null, "sql"=>'close_date', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeCaseLog("private_log", array("allowed_values"=>null, "sql"=>'private_log', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("contacts_list", array("linked_class"=>'lnkContactToTicket', "ext_key_to_me"=>'ticket_id', "ext_key_to_remote"=>'contact_id', "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "duplicates"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("functionalcis_list", array("linked_class"=>'lnkFunctionalCIToTicket', "ext_key_to_me"=>'ticket_id', "ext_key_to_remote"=>'functionalci_id', "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "duplicates"=>false, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array (
|
||||
0 => 'ref',
|
||||
1 => 'organization_id',
|
||||
2 => 'caller_id',
|
||||
3 => 'team_id',
|
||||
4 => 'agent_id',
|
||||
5 => 'title',
|
||||
6 => 'description',
|
||||
7 => 'start_date',
|
||||
8 => 'end_date',
|
||||
9 => 'last_update',
|
||||
10 => 'close_date',
|
||||
11 => 'private_log',
|
||||
12 => 'contacts_list',
|
||||
13 => 'functionalcis_list',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('standard_search', array (
|
||||
0 => 'ref',
|
||||
1 => 'title',
|
||||
2 => 'description',
|
||||
3 => 'start_date',
|
||||
4 => 'end_date',
|
||||
5 => 'last_update',
|
||||
6 => 'close_date',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('list', array (
|
||||
0 => 'ref',
|
||||
1 => 'organization_id',
|
||||
2 => 'title',
|
||||
3 => 'caller_id',
|
||||
4 => 'team_id',
|
||||
5 => 'agent_id',
|
||||
6 => 'start_date',
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class lnkContactToTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
'category' => 'bizModel',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('ticket_id', 'contact_id'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array('ticket_id', 'contact_id'),
|
||||
'db_table' => 'lnkcontacttoticket',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => '',
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>'Ticket', "allowed_values"=>null, "sql"=>'ticket_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("contact_id", array("targetclass"=>'Contact', "allowed_values"=>null, "sql"=>'contact_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array (
|
||||
0 => 'ticket_id',
|
||||
1 => 'contact_id',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('standard_search', array (
|
||||
0 => 'ticket_id',
|
||||
1 => 'contact_id',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('list', array (
|
||||
0 => 'ticket_id',
|
||||
1 => 'contact_id',
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class lnkFunctionalCIToTicket extends cmdbAbstractObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
'category' => 'bizModel',
|
||||
'key_type' => 'autoincrement',
|
||||
'name_attcode' => array('ticket_id', 'functionalci_id'),
|
||||
'state_attcode' => '',
|
||||
'reconc_keys' => array('ticket_id', 'functionalci_id'),
|
||||
'db_table' => 'lnkfunctionalcitoticket',
|
||||
'db_key_field' => 'id',
|
||||
'db_finalclass_field' => '',
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("ticket_id", array("targetclass"=>'Ticket', "allowed_values"=>null, "sql"=>'ticket_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("functionalci_id", array("targetclass"=>'FunctionalCI', "allowed_values"=>null, "sql"=>'functionalci_id', "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||
|
||||
|
||||
MetaModel::Init_SetZListItems('details', array (
|
||||
0 => 'ticket_id',
|
||||
1 => 'functionalci_id',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('standard_search', array (
|
||||
0 => 'ticket_id',
|
||||
1 => 'functionalci_id',
|
||||
));
|
||||
MetaModel::Init_SetZListItems('list', array (
|
||||
0 => 'ticket_id',
|
||||
1 => 'functionalci_id',
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Menu:RequestManagement' => 'Gerenciamento Solicitações',
|
||||
'Menu:RequestManagement+' => 'Gerenciamento Solicitações',
|
||||
'Menu:RequestManagementProvider' => 'Solicitações provedoras',
|
||||
'Menu:RequestManagementProvider+' => 'Solicitações provedoras',
|
||||
'Menu:UserRequest:Provider' => 'Solicitações abertas transferidas para provedor',
|
||||
'Menu:UserRequest:Provider+' => 'Solicitações abertas transferidas para provedor',
|
||||
'Menu:UserRequest:Overview' => 'Visão geral',
|
||||
'Menu:UserRequest:Overview+' => 'Visão geral',
|
||||
'Menu:NewUserRequest' => 'Nova solicitação',
|
||||
'Menu:NewUserRequest+' => 'Criar uma nova solicitação',
|
||||
'Menu:SearchUserRequests' => 'Pesquisar por solicitação',
|
||||
'Menu:SearchUserRequests+' => 'Pesquisar por solicitação',
|
||||
'Menu:UserRequest:Shortcuts' => 'Atalho',
|
||||
'Menu:UserRequest:Shortcuts+' => '',
|
||||
'Menu:UserRequest:MyRequests' => 'Solicitações abertas por mim',
|
||||
'Menu:UserRequest:MyRequests+' => 'Solicitações abertas por mim (como agente)',
|
||||
'Menu:UserRequest:MySupportRequests' => "Minhas solicitações de suporte",
|
||||
'Menu:UserRequest:MySupportRequests+' => "Minhas solicitações de suporte",
|
||||
'Menu:UserRequest:EscalatedRequests' => 'Hot requests',
|
||||
'Menu:UserRequest:EscalatedRequests+' => 'Hot requests',
|
||||
'Menu:UserRequest:OpenRequests' => 'Todas solicitações abertas',
|
||||
'Menu:UserRequest:OpenRequests+' => 'Todas solicitações abertas',
|
||||
'UI:WelcomeMenu:MyAssignedCalls' => 'Solicitações atribuidas a mim',
|
||||
'UI-RequestManagementOverview-RequestByType-last-14-days' => 'Solicitações dos últimos 14 dias (por tipo)',
|
||||
'UI-RequestManagementOverview-Last-14-days' => 'Solicitações dos últimos 14 dias (por dia)',
|
||||
'UI-RequestManagementOverview-OpenRequestByStatus' => 'Solicitações abertas por status',
|
||||
'UI-RequestManagementOverview-OpenRequestByAgent' => 'Solicitações abertas por agente',
|
||||
'UI-RequestManagementOverview-OpenRequestByType' => 'Solicitações abertas por tipo',
|
||||
'UI-RequestManagementOverview-OpenRequestByCustomer' => 'Solicitações abertas por organização',
|
||||
'Class:UserRequest:KnownErrorList' => 'Erros conhecidos',
|
||||
'Menu:UserRequest:MyWorkOrders' => 'Ordens de serviço atribuídas a mim',
|
||||
'Menu:UserRequest:MyWorkOrders+' => 'Todas as Ordens de serviço atribuídos a min',
|
||||
'Class:Problem:KnownProblemList' => 'Problemas conhecidos',
|
||||
));
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserRequest
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:UserRequest' => 'Usuário solicitante',
|
||||
'Class:UserRequest+' => '',
|
||||
'Class:UserRequest/Attribute:status' => 'Estado',
|
||||
'Class:UserRequest/Attribute:status+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:new' => 'Nova',
|
||||
'Class:UserRequest/Attribute:status/Value:new+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_tto' => 'TTO escalado',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_tto+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:assigned' => 'Atribuido',
|
||||
'Class:UserRequest/Attribute:status/Value:assigned+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_ttr' => 'TTR escalado',
|
||||
'Class:UserRequest/Attribute:status/Value:escalated_ttr+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:waiting_for_approval' => 'Aguardando aprovação',
|
||||
'Class:UserRequest/Attribute:status/Value:waiting_for_approval+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:approved' => 'Aprovado',
|
||||
'Class:UserRequest/Attribute:status/Value:approved+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:rejected' => 'Rejeitado',
|
||||
'Class:UserRequest/Attribute:status/Value:rejected+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:pending' => 'Pendente',
|
||||
'Class:UserRequest/Attribute:status/Value:pending+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:resolved' => 'Resolvido',
|
||||
'Class:UserRequest/Attribute:status/Value:resolved+' => '',
|
||||
'Class:UserRequest/Attribute:status/Value:closed' => 'Fechado',
|
||||
'Class:UserRequest/Attribute:status/Value:closed+' => '',
|
||||
'Class:UserRequest/Attribute:request_type' => 'Tipo solicitação',
|
||||
'Class:UserRequest/Attribute:request_type+' => '',
|
||||
'Class:UserRequest/Attribute:request_type/Value:incident' => 'Incidente',
|
||||
'Class:UserRequest/Attribute:request_type/Value:incident+' => 'Incidente',
|
||||
'Class:UserRequest/Attribute:request_type/Value:service_request' => 'Solicitação serviço',
|
||||
'Class:UserRequest/Attribute:request_type/Value:service_request+' => 'Solicitação serviço',
|
||||
'Class:UserRequest/Attribute:impact' => 'Impacto',
|
||||
'Class:UserRequest/Attribute:impact+' => '',
|
||||
'Class:UserRequest/Attribute:impact/Value:1' => 'Um departamento',
|
||||
'Class:UserRequest/Attribute:impact/Value:1+' => '',
|
||||
'Class:UserRequest/Attribute:impact/Value:2' => 'Um serviço',
|
||||
'Class:UserRequest/Attribute:impact/Value:2+' => '',
|
||||
'Class:UserRequest/Attribute:impact/Value:3' => 'Uma pessoa',
|
||||
'Class:UserRequest/Attribute:impact/Value:3+' => '',
|
||||
'Class:UserRequest/Attribute:priority' => 'Prioridade',
|
||||
'Class:UserRequest/Attribute:priority+' => '',
|
||||
'Class:UserRequest/Attribute:priority/Value:1' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:priority/Value:1+' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:priority/Value:2' => 'Alta',
|
||||
'Class:UserRequest/Attribute:priority/Value:2+' => 'Alta',
|
||||
'Class:UserRequest/Attribute:priority/Value:3' => 'Média',
|
||||
'Class:UserRequest/Attribute:priority/Value:3+' => 'Média',
|
||||
'Class:UserRequest/Attribute:priority/Value:4' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:priority/Value:4+' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:urgency' => 'Urgência',
|
||||
'Class:UserRequest/Attribute:urgency+' => '',
|
||||
'Class:UserRequest/Attribute:urgency/Value:1' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:urgency/Value:1+' => 'Crítica',
|
||||
'Class:UserRequest/Attribute:urgency/Value:2' => 'Alta',
|
||||
'Class:UserRequest/Attribute:urgency/Value:2+' => 'Alta',
|
||||
'Class:UserRequest/Attribute:urgency/Value:3' => 'Média',
|
||||
'Class:UserRequest/Attribute:urgency/Value:3+' => 'Média',
|
||||
'Class:UserRequest/Attribute:urgency/Value:4' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:urgency/Value:4+' => 'Baixa',
|
||||
'Class:UserRequest/Attribute:origin' => 'Origem',
|
||||
'Class:UserRequest/Attribute:origin+' => '',
|
||||
'Class:UserRequest/Attribute:origin/Value:mail' => 'Email',
|
||||
'Class:UserRequest/Attribute:origin/Value:mail+' => 'Email',
|
||||
'Class:UserRequest/Attribute:origin/Value:monitoring' => 'Monitoramento',
|
||||
'Class:UserRequest/Attribute:origin/Value:monitoring+' => 'Monitoramento',
|
||||
'Class:UserRequest/Attribute:origin/Value:phone' => 'Telefone',
|
||||
'Class:UserRequest/Attribute:origin/Value:phone+' => 'Telefone',
|
||||
'Class:UserRequest/Attribute:origin/Value:portal' => 'Portal',
|
||||
'Class:UserRequest/Attribute:origin/Value:portal+' => 'Portal',
|
||||
'Class:UserRequest/Attribute:approver_id' => 'Aprovador',
|
||||
'Class:UserRequest/Attribute:approver_id+' => '',
|
||||
'Class:UserRequest/Attribute:approver_email' => 'Email aprovador',
|
||||
'Class:UserRequest/Attribute:approver_email+' => '',
|
||||
'Class:UserRequest/Attribute:service_id' => 'Serviço',
|
||||
'Class:UserRequest/Attribute:service_id+' => '',
|
||||
'Class:UserRequest/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:UserRequest/Attribute:service_name+' => '',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_id' => 'Sub-categoria serviço',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_id+' => '',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_name' => 'Nome Sub-categoria serviço',
|
||||
'Class:UserRequest/Attribute:servicesubcategory_name+' => '',
|
||||
'Class:UserRequest/Attribute:escalation_flag' => 'Alerta vermelho',
|
||||
'Class:UserRequest/Attribute:escalation_flag+' => '',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:no' => 'Não',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:no+' => 'Não',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:yes' => 'Sim',
|
||||
'Class:UserRequest/Attribute:escalation_flag/Value:yes+' => 'Sim',
|
||||
'Class:UserRequest/Attribute:escalation_reason' => 'Razão alerta',
|
||||
'Class:UserRequest/Attribute:escalation_reason+' => '',
|
||||
'Class:UserRequest/Attribute:assignment_date' => 'Data atribuição',
|
||||
'Class:UserRequest/Attribute:assignment_date+' => '',
|
||||
'Class:UserRequest/Attribute:resolution_date' => 'Data resolução',
|
||||
'Class:UserRequest/Attribute:resolution_date+' => '',
|
||||
'Class:UserRequest/Attribute:last_pending_date' => 'Última data pendente',
|
||||
'Class:UserRequest/Attribute:last_pending_date+' => '',
|
||||
'Class:UserRequest/Attribute:cumulatedpending' => 'Pendências acumuladas',
|
||||
'Class:UserRequest/Attribute:cumulatedpending+' => '',
|
||||
'Class:UserRequest/Attribute:tto' => 'TTO',
|
||||
'Class:UserRequest/Attribute:tto+' => '',
|
||||
'Class:UserRequest/Attribute:ttr' => 'TTR',
|
||||
'Class:UserRequest/Attribute:ttr+' => '',
|
||||
'Class:UserRequest/Attribute:tto_escalation_deadline' => 'Prazo determinado TTO',
|
||||
'Class:UserRequest/Attribute:tto_escalation_deadline+' => '',
|
||||
'Class:UserRequest/Attribute:sla_tto_passed' => 'SLA TTO passou',
|
||||
'Class:UserRequest/Attribute:sla_tto_passed+' => '',
|
||||
'Class:UserRequest/Attribute:sla_tto_over' => 'SLA TTO acima',
|
||||
'Class:UserRequest/Attribute:sla_tto_over+' => '',
|
||||
'Class:UserRequest/Attribute:ttr_escalation_deadline' => 'Prazo determinado TTR',
|
||||
'Class:UserRequest/Attribute:ttr_escalation_deadline+' => '',
|
||||
'Class:UserRequest/Attribute:sla_ttr_passed' => 'SLA TTR passou',
|
||||
'Class:UserRequest/Attribute:sla_ttr_passed+' => '',
|
||||
'Class:UserRequest/Attribute:sla_ttr_over' => 'SLA TTR acima',
|
||||
'Class:UserRequest/Attribute:sla_ttr_over+' => '',
|
||||
'Class:UserRequest/Attribute:time_spent' => 'Atraso resolução',
|
||||
'Class:UserRequest/Attribute:time_spent+' => '',
|
||||
'Class:UserRequest/Attribute:resolution_code' => 'Código resolução',
|
||||
'Class:UserRequest/Attribute:resolution_code+' => '',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:assistance' => 'Assistência',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:assistance+' => 'Assistência',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:bug fixed' => 'Bug corrigido',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:bug fixed+' => 'Bug corrigido',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:hardware repair' => 'Hardware reparado',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:hardware repair+' => 'Hardware reparado',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:other' => 'Outros',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:other+' => 'Outros',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:software patch' => 'Software patch',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:software patch+' => 'Software patch',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:system update' => 'Atualização sistema',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:system update+' => 'Atualização sistema',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:training' => 'Treinamento',
|
||||
'Class:UserRequest/Attribute:resolution_code/Value:training+' => 'Treinamento',
|
||||
'Class:UserRequest/Attribute:solution' => 'Solução',
|
||||
'Class:UserRequest/Attribute:solution+' => '',
|
||||
'Class:UserRequest/Attribute:pending_reason' => 'Razão pendência',
|
||||
'Class:UserRequest/Attribute:pending_reason+' => '',
|
||||
'Class:UserRequest/Attribute:parent_request_id' => 'Solicitação principal',
|
||||
'Class:UserRequest/Attribute:parent_request_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_request_ref' => 'Ref solicitação',
|
||||
'Class:UserRequest/Attribute:parent_request_ref+' => '',
|
||||
'Class:UserRequest/Attribute:parent_problem_id' => 'Problema principal',
|
||||
'Class:UserRequest/Attribute:parent_problem_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_problem_ref' => 'Ref problema',
|
||||
'Class:UserRequest/Attribute:parent_problem_ref+' => '',
|
||||
'Class:UserRequest/Attribute:parent_change_id' => 'Mudança principal',
|
||||
'Class:UserRequest/Attribute:parent_change_id+' => '',
|
||||
'Class:UserRequest/Attribute:parent_change_ref' => 'Ref mudança',
|
||||
'Class:UserRequest/Attribute:parent_change_ref+' => '',
|
||||
'Class:UserRequest/Attribute:related_request_list' => 'Sub-solicitação',
|
||||
'Class:UserRequest/Attribute:related_request_list+' => 'Todas as solicitações vinculadas a essa solicitação principal',
|
||||
'Class:UserRequest/Attribute:public_log' => 'Log público',
|
||||
'Class:UserRequest/Attribute:public_log+' => '',
|
||||
'Class:UserRequest/Attribute:user_satisfaction' => 'Satisfação do usuário',
|
||||
'Class:UserRequest/Attribute:user_satisfaction+' => '',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:1' => 'Muito satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:1+' => 'Muito satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:2' => 'Bastante satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:2+' => 'Bastante satisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:3' => 'Bastante insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:3+' => 'Bastante insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:4' => 'Muito insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_satisfaction/Value:4+' => 'Muito insatisfeito',
|
||||
'Class:UserRequest/Attribute:user_comment' => 'Comentário usuário',
|
||||
'Class:UserRequest/Attribute:user_comment+' => '',
|
||||
'Class:UserRequest/Attribute:parent_request_id_friendlyname' => 'parent_request_id_friendlyname',
|
||||
'Class:UserRequest/Attribute:parent_request_id_friendlyname+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_assign' => 'Atribuir',
|
||||
'Class:UserRequest/Stimulus:ev_assign+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_reassign' => 'Re-Atribuir',
|
||||
'Class:UserRequest/Stimulus:ev_reassign+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_approve' => 'Aprovar',
|
||||
'Class:UserRequest/Stimulus:ev_approve+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_reject' => 'Rejeitar',
|
||||
'Class:UserRequest/Stimulus:ev_reject+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_pending' => 'Pendência',
|
||||
'Class:UserRequest/Stimulus:ev_pending+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_timeout' => 'Timeout',
|
||||
'Class:UserRequest/Stimulus:ev_timeout+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_autoresolve' => 'Resolvido automaticamente',
|
||||
'Class:UserRequest/Stimulus:ev_autoresolve+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_autoclose' => 'Fechado automaticamente',
|
||||
'Class:UserRequest/Stimulus:ev_autoclose+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_resolve' => 'Marcar como resolvido',
|
||||
'Class:UserRequest/Stimulus:ev_resolve+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_close' => 'Fechar esta solicitação',
|
||||
'Class:UserRequest/Stimulus:ev_close+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_reopen' => 'Re-abrir',
|
||||
'Class:UserRequest/Stimulus:ev_reopen+' => '',
|
||||
'Class:UserRequest/Stimulus:ev_wait_for_approval' => 'Aguardar por aprovação',
|
||||
'Class:UserRequest/Stimulus:ev_wait_for_approval+' => '',
|
||||
'Class:UserRequest/Error:CannotAssignParentRequestIdToSelf' => 'Não é possível atribuir a solicitação principal para si mesmo',
|
||||
));
|
||||
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Portal:TitleDetailsFor_Request' => 'Detalhes da solicitação',
|
||||
'Portal:ButtonUpdate' => 'Atualizado',
|
||||
'Portal:ButtonClose' => 'Fechado',
|
||||
'Portal:ButtonReopen' => 'Re-aberto',
|
||||
'Portal:ShowServices' => 'Catálogo dos serviços',
|
||||
'Portal:SelectRequestType' => 'Selecione um tipo de solicitação',
|
||||
'Portal:SelectServiceElementFrom_Service' => 'Selecione um serviço para %1$s',
|
||||
'Portal:SelectRequestTemplate' => 'Selecione um modelo para %1$s',
|
||||
'Portal:ListServices' => 'Lista dos serviços',
|
||||
'Portal:TitleDetailsFor_Service' => 'Detalhes dos serviços',
|
||||
'Portal:Button:CreateRequestFromService' => 'Criar uma solicitação para esse serviço',
|
||||
'Portal:ListOpenRequests' => 'Lista solicitações abertas',
|
||||
'Portal:UserRequest:MoreInfo' => 'Mais informações',
|
||||
'Portal:Details-Service-Element' => 'Elementos do Serviço',
|
||||
'Portal:NoClosedTicket' => 'Nenhuma solicitação fechada',
|
||||
'Portal:NoService' => '',
|
||||
'Portal:ListOpenProblems' => 'Problemas em curso',
|
||||
'Portal:ShowProblem' => 'Problemas',
|
||||
'Portal:ShowFaqs' => 'FAQs',
|
||||
'Portal:NoOpenProblem' => 'Nenhum problema aberto',
|
||||
'Portal:SelectLanguage' => "Alterar sua linguagem",
|
||||
'Portal:LanguageChangedTo_Lang' => 'Linguagem alterada para',
|
||||
'Portal:ChooseYourFavoriteLanguage' => 'Escolha sua linguagem favorita',
|
||||
));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,531 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Menu:ServiceManagement' => 'Gerenciamento Serviços',
|
||||
'Menu:ServiceManagement+' => 'Gerenciamento Serviços',
|
||||
'Menu:Service:Overview' => 'Visão geral',
|
||||
'Menu:Service:Overview+' => '',
|
||||
'UI-ServiceManagementMenu-ContractsBySrvLevel' => 'Contratos por nível serviço',
|
||||
'UI-ServiceManagementMenu-ContractsByStatus' => 'Contratos por status',
|
||||
'UI-ServiceManagementMenu-ContractsEndingIn30Days' => 'Contratos terminando em menos de 30 dias',
|
||||
|
||||
'Menu:ServiceType' => 'Tipos serviços',
|
||||
'Menu:ServiceType+' => 'Tipos serviços',
|
||||
'Menu:ProviderContract' => 'Contratos Provedores(as)',
|
||||
'Menu:ProviderContract+' => 'Contratos Provedores(as)',
|
||||
'Menu:CustomerContract' => 'Contratos Clientes',
|
||||
'Menu:CustomerContract+' => 'Contratos Clientes',
|
||||
'Menu:ServiceSubcategory' => 'Sub-categorias serviços',
|
||||
'Menu:ServiceSubcategory+' => 'Sub-categorias serviços',
|
||||
'Menu:Service' => 'Serviços',
|
||||
'Menu:Service+' => 'Serviços',
|
||||
'Menu:ServiceElement' => 'Elementos seviços',
|
||||
'Menu:ServiceElement+' => 'Elementos seviços',
|
||||
'Menu:SLA' => 'SLAs',
|
||||
'Menu:SLA+' => 'Lista Nível de Serviço Acordados',
|
||||
'Menu:SLT' => 'SLTs',
|
||||
'Menu:SLT+' => 'Lista Nível de Metas de Serviço',
|
||||
'Menu:DeliveryModel' => 'Modelos entrega',
|
||||
'Menu:DeliveryModel+' => 'Modelos entrega',
|
||||
|
||||
));
|
||||
|
||||
|
||||
/*
|
||||
'UI:ServiceManagementMenu' => 'Gestion des Services',
|
||||
'UI:ServiceManagementMenu+' => 'Gestion des Services',
|
||||
'UI:ServiceManagementMenu:Title' => 'Résumé des services & contrats',
|
||||
'UI-ServiceManagementMenu-ContractsBySrvLevel' => 'Contrats par niveau de service',
|
||||
'UI-ServiceManagementMenu-ContractsByStatus' => 'Contrats par état',
|
||||
'UI-ServiceManagementMenu-ContractsEndingIn30Days' => 'Contrats se terminant dans moins de 30 jours',
|
||||
*/
|
||||
|
||||
//
|
||||
// Class: Organization
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:Organization/Attribute:deliverymodel_id' => 'Modelo entrega',
|
||||
'Class:Organization/Attribute:deliverymodel_id+' => '',
|
||||
'Class:Organization/Attribute:deliverymodel_name' => 'Nome modelo entrega',
|
||||
'Class:Organization/Attribute:deliverymodel_name+' => '',
|
||||
));
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Class: ContractType
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:ContractType' => 'Tipo contrato',
|
||||
'Class:ContractType+' => '',
|
||||
));
|
||||
|
||||
|
||||
//
|
||||
// Class: Contract
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:Contract' => 'Contrato',
|
||||
'Class:Contract+' => '',
|
||||
'Class:Contract/Attribute:name' => 'Nome',
|
||||
'Class:Contract/Attribute:name+' => '',
|
||||
'Class:Contract/Attribute:org_id' => 'Organização',
|
||||
'Class:Contract/Attribute:org_id+' => '',
|
||||
'Class:Contract/Attribute:organization_name' => 'Nome organização',
|
||||
'Class:Contract/Attribute:organization_name+' => 'Nome comum',
|
||||
'Class:Contract/Attribute:contacts_list' => 'Contatos',
|
||||
'Class:Contract/Attribute:contacts_list+' => 'Todos os contatos para este contrato com o cliente',
|
||||
'Class:Contract/Attribute:documents_list' => 'Documentos',
|
||||
'Class:Contract/Attribute:documents_list+' => 'Todos os documentos para este contrato com o cliente',
|
||||
'Class:Contract/Attribute:description' => 'Descrição',
|
||||
'Class:Contract/Attribute:description+' => '',
|
||||
'Class:Contract/Attribute:start_date' => 'Data início',
|
||||
'Class:Contract/Attribute:start_date+' => '',
|
||||
'Class:Contract/Attribute:end_date' => 'Data final',
|
||||
'Class:Contract/Attribute:end_date+' => '',
|
||||
'Class:Contract/Attribute:cost' => 'Valor',
|
||||
'Class:Contract/Attribute:cost+' => '',
|
||||
'Class:Contract/Attribute:cost_currency' => 'Valor atual',
|
||||
'Class:Contract/Attribute:cost_currency+' => '',
|
||||
'Class:Contract/Attribute:cost_currency/Value:dollars' => 'Dólares',
|
||||
'Class:Contract/Attribute:cost_currency/Value:dollars+' => '',
|
||||
'Class:Contract/Attribute:cost_currency/Value:euros' => 'Euros',
|
||||
'Class:Contract/Attribute:cost_currency/Value:euros+' => '',
|
||||
'Class:Contract/Attribute:contracttype_id' => 'Tipo contrato',
|
||||
'Class:Contract/Attribute:contracttype_id+' => '',
|
||||
'Class:Contract/Attribute:contracttype_name' => 'Nome tipo contrato',
|
||||
'Class:Contract/Attribute:contracttype_name+' => '',
|
||||
'Class:Contract/Attribute:billing_frequency' => 'Frequência pagamento',
|
||||
'Class:Contract/Attribute:billing_frequency+' => '',
|
||||
'Class:Contract/Attribute:cost_unit' => 'Valor unitário',
|
||||
'Class:Contract/Attribute:cost_unit+' => '',
|
||||
'Class:Contract/Attribute:provider_id' => 'Provedor(a)',
|
||||
'Class:Contract/Attribute:provider_id+' => '',
|
||||
'Class:Contract/Attribute:provider_name' => 'Nome provedor(a)',
|
||||
'Class:Contract/Attribute:provider_name+' => '',
|
||||
'Class:Contract/Attribute:status' => 'Estado',
|
||||
'Class:Contract/Attribute:status+' => '',
|
||||
'Class:Contract/Attribute:status/Value:implementation' => 'Implementação',
|
||||
'Class:Contract/Attribute:status/Value:implementation+' => 'Implementação',
|
||||
'Class:Contract/Attribute:status/Value:obsolete' => 'Obsoleto',
|
||||
'Class:Contract/Attribute:status/Value:obsolete+' => 'Obsoleto',
|
||||
'Class:Contract/Attribute:status/Value:production' => 'Produção',
|
||||
'Class:Contract/Attribute:status/Value:production+' => 'Produção',
|
||||
'Class:Contract/Attribute:finalclass' => 'Tipo contrato',
|
||||
'Class:Contract/Attribute:finalclass+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: CustomerContract
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:CustomerContract' => 'Contrato cliente',
|
||||
'Class:CustomerContract+' => '',
|
||||
'Class:CustomerContract/Attribute:services_list' => 'Serviços',
|
||||
'Class:CustomerContract/Attribute:services_list+' => 'Todos os serviços contratados para o presente contrato',
|
||||
'Class:CustomerContract/Attribute:functionalcis_list' => 'CIs',
|
||||
'Class:CustomerContract/Attribute:functionalcis_list+' => 'Todos os itens de configuração que são utilizados para a prestação deste serviço',
|
||||
'Class:CustomerContract/Attribute:providercontracts_list' => 'Contrato provedor(a)',
|
||||
'Class:CustomerContract/Attribute:providercontracts_list+' => 'Todos contratos para suporte para esse serviço',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ProviderContract
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:ProviderContract' => 'Contrato provedor(a)',
|
||||
'Class:ProviderContract+' => '',
|
||||
'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs',
|
||||
'Class:ProviderContract/Attribute:functionalcis_list+' => 'Todos os itens de configuração abrangidos para esse contrato',
|
||||
'Class:ProviderContract/Attribute:sla' => 'SLA',
|
||||
'Class:ProviderContract/Attribute:sla+' => 'SLA',
|
||||
'Class:ProviderContract/Attribute:coverage' => 'Horas de serviço',
|
||||
'Class:ProviderContract/Attribute:coverage+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkContactToContract
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkContactToContract' => 'Link Contato / Contrato',
|
||||
'Class:lnkContactToContract+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contract_id' => 'Contrato',
|
||||
'Class:lnkContactToContract/Attribute:contract_id+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contract_name' => 'Nome contrato',
|
||||
'Class:lnkContactToContract/Attribute:contract_name+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contact_id' => 'Contato',
|
||||
'Class:lnkContactToContract/Attribute:contact_id+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contact_name' => 'Nome contato',
|
||||
'Class:lnkContactToContract/Attribute:contact_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkContractToDocument
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkContractToDocument' => 'Link Contrato / Documento',
|
||||
'Class:lnkContractToDocument+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:contract_id' => 'Contrato',
|
||||
'Class:lnkContractToDocument/Attribute:contract_id+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:contract_name' => 'Nome contrato',
|
||||
'Class:lnkContractToDocument/Attribute:contract_name+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:document_id' => 'Documento',
|
||||
'Class:lnkContractToDocument/Attribute:document_id+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:document_name' => 'Nome documento',
|
||||
'Class:lnkContractToDocument/Attribute:document_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkFunctionalCIToProviderContract
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkFunctionalCIToProviderContract' => 'Link CI / Contrato provedor(a)',
|
||||
'Class:lnkFunctionalCIToProviderContract+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id' => 'Contrato provedor(a)',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name' => 'Nome contrato provedor(a)',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id' => 'CIs',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name' => 'Nome CI',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ServiceFamily
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:ServiceFamily' => 'Família serviços',
|
||||
'Class:ServiceFamily+' => '',
|
||||
'Class:ServiceFamily/Attribute:id' => 'Id',
|
||||
'Class:ServiceFamily/Attribute:id+' => '',
|
||||
'Class:ServiceFamily+' => '',
|
||||
'Class:ServiceFamily/Attribute:name' => 'Nome',
|
||||
'Class:ServiceFamily/Attribute:name+' => '',
|
||||
'Class:ServiceFamily/Attribute:services_list' => 'Serviços',
|
||||
'Class:ServiceFamily/Attribute:services_list+' => 'Todos os serviços para essa categoria',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: Service
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:Service' => 'Serviço',
|
||||
'Class:Service+' => '',
|
||||
'Class:Service/Attribute:name' => 'Nome',
|
||||
'Class:Service/Attribute:name+' => '',
|
||||
'Class:Service/Attribute:org_id' => 'Organização',
|
||||
'Class:Service/Attribute:org_id+' => '',
|
||||
'Class:Service/Attribute:organization_name' => 'Nome',
|
||||
'Class:Service/Attribute:organization_name+' => 'Nome comum',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Família serviço',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome família serviço',
|
||||
'Class:Service/Attribute:servicefamily_name+' => 'Nome família serviço',
|
||||
'Class:Service/Attribute:description' => 'Descrição',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documentos',
|
||||
'Class:Service/Attribute:documents_list+' => 'Todos documentos vinculados com o serviço',
|
||||
'Class:Service/Attribute:contacts_list' => 'Contatos',
|
||||
'Class:Service/Attribute:contacts_list+' => 'Todos contatos com o serviço',
|
||||
'Class:Service/Attribute:status' => 'Estado',
|
||||
'Class:Service/Attribute:status+' => '',
|
||||
'Class:Service/Attribute:status/Value:implementation' => 'Implementação',
|
||||
'Class:Service/Attribute:status/Value:implementation+' => 'Implementação',
|
||||
'Class:Service/Attribute:status/Value:obsolete' => 'Obsoleto',
|
||||
'Class:Service/Attribute:status/Value:obsolete+' => '',
|
||||
'Class:Service/Attribute:status/Value:production' => 'Produção',
|
||||
'Class:Service/Attribute:status/Value:production+' => '',
|
||||
'Class:Service/Attribute:customercontracts_list' => 'Contratos clientes',
|
||||
'Class:Service/Attribute:customercontracts_list+' => 'Todos contratos de clientes que contrataram esse serviço',
|
||||
'Class:Service/Attribute:servicesubcategories_list' => 'Sub-categorias serviço',
|
||||
'Class:Service/Attribute:servicesubcategories_list+' => 'Todas as sub-categorias para esse serviço',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkDocumentToService
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkDocumentToService' => 'Link Documento / Serviço',
|
||||
'Class:lnkDocumentToService+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:service_id' => 'Serviço',
|
||||
'Class:lnkDocumentToService/Attribute:service_id+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:lnkDocumentToService/Attribute:service_name+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:document_id' => 'Documento',
|
||||
'Class:lnkDocumentToService/Attribute:document_id+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:document_name' => 'Nome documento',
|
||||
'Class:lnkDocumentToService/Attribute:document_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkContactToService
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkContactToService' => 'Link Contato / Serviço',
|
||||
'Class:lnkContactToService+' => '',
|
||||
'Class:lnkContactToService/Attribute:service_id' => 'Serviço',
|
||||
'Class:lnkContactToService/Attribute:service_id+' => '',
|
||||
'Class:lnkContactToService/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:lnkContactToService/Attribute:service_name+' => '',
|
||||
'Class:lnkContactToService/Attribute:contact_id' => 'Contato',
|
||||
'Class:lnkContactToService/Attribute:contact_id+' => '',
|
||||
'Class:lnkContactToService/Attribute:contact_name' => 'Nome contato',
|
||||
'Class:lnkContactToService/Attribute:contact_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ServiceSubcategory
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:ServiceSubcategory' => 'Sub-categoria serviço',
|
||||
'Class:ServiceSubcategory+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:name' => 'Nome',
|
||||
'Class:ServiceSubcategory/Attribute:name+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:description' => 'Descrição',
|
||||
'Class:ServiceSubcategory/Attribute:description+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:service_id' => 'Serviço',
|
||||
'Class:ServiceSubcategory/Attribute:service_id+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:ServiceSubcategory/Attribute:service_name+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status' => 'Estado',
|
||||
'Class:ServiceSubcategory/Attribute:status+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:implementation' => 'Implementação',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:implementation+' => 'Implementação',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:obsolete' => 'Obsoleto',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:obsolete+' => 'Obsoleto',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:production' => 'Produção',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:production+' => 'Produção',
|
||||
'Class:ServiceSubcategory/Attribute:request_type' => 'Tipo solicitação',
|
||||
'Class:ServiceSubcategory/Attribute:request_type+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:incident' => 'Incidente',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:incident+' => 'Incidente',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:service_request' => 'Solicitação serviço',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:service_request+' => 'Solicitação serviço',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: SLA
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:SLA' => 'SLA',
|
||||
'Class:SLA+' => '',
|
||||
'Class:SLA/Attribute:name' => 'Nome',
|
||||
'Class:SLA/Attribute:name+' => '',
|
||||
'Class:SLA/Attribute:description' => 'Descrição',
|
||||
'Class:SLA/Attribute:description+' => '',
|
||||
'Class:SLA/Attribute:org_id' => 'Organização',
|
||||
'Class:SLA/Attribute:org_id+' => '',
|
||||
'Class:SLA/Attribute:organization_name' => 'Nome organização',
|
||||
'Class:SLA/Attribute:organization_name+' => '',
|
||||
'Class:SLA/Attribute:slts_list' => 'SLTs',
|
||||
'Class:SLA/Attribute:slts_list+' => 'Todos os SLTs para essa SLA',
|
||||
'Class:SLA/Attribute:customercontracts_list' => 'Contratos clientes',
|
||||
'Class:SLA/Attribute:customercontracts_list+' => 'Todos os contratos de clientes utilizando essa SLA',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: SLT
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:SLT' => 'SLT',
|
||||
'Class:SLT+' => '',
|
||||
'Class:SLT/Attribute:name' => 'Nome',
|
||||
'Class:SLT/Attribute:name+' => '',
|
||||
'Class:SLT/Attribute:priority' => 'Prioridade',
|
||||
'Class:SLT/Attribute:priority+' => '',
|
||||
'Class:SLT/Attribute:priority/Value:1' => 'Crítica',
|
||||
'Class:SLT/Attribute:priority/Value:1+' => 'Crítica',
|
||||
'Class:SLT/Attribute:priority/Value:2' => 'Alta',
|
||||
'Class:SLT/Attribute:priority/Value:2+' => 'Alta',
|
||||
'Class:SLT/Attribute:priority/Value:3' => 'Média',
|
||||
'Class:SLT/Attribute:priority/Value:3+' => 'Média',
|
||||
'Class:SLT/Attribute:priority/Value:4' => 'Baixa',
|
||||
'Class:SLT/Attribute:priority/Value:4+' => 'Baixa',
|
||||
'Class:SLT/Attribute:request_type' => 'Tipo solicitação',
|
||||
'Class:SLT/Attribute:request_type+' => '',
|
||||
'Class:SLT/Attribute:request_type/Value:incident' => 'Incidente',
|
||||
'Class:SLT/Attribute:request_type/Value:incident+' => 'Incidente',
|
||||
'Class:SLT/Attribute:request_type/Value:service_request' => 'Solicitação serviço',
|
||||
'Class:SLT/Attribute:request_type/Value:service_request+' => 'Solicitação serviço',
|
||||
'Class:SLT/Attribute:metric' => 'Métrica',
|
||||
'Class:SLT/Attribute:metric+' => '',
|
||||
'Class:SLT/Attribute:metric/Value:tto' => 'TTO',
|
||||
'Class:SLT/Attribute:metric/Value:tto+' => 'TTO',
|
||||
'Class:SLT/Attribute:metric/Value:ttr' => 'TTR',
|
||||
'Class:SLT/Attribute:metric/Value:ttr+' => 'TTR',
|
||||
'Class:SLT/Attribute:value' => 'Valor',
|
||||
'Class:SLT/Attribute:value+' => '',
|
||||
'Class:SLT/Attribute:unit' => 'Unidade',
|
||||
'Class:SLT/Attribute:unit+' => '',
|
||||
'Class:SLT/Attribute:unit/Value:hours' => 'Horas',
|
||||
'Class:SLT/Attribute:unit/Value:hours+' => 'Horas',
|
||||
'Class:SLT/Attribute:unit/Value:minutes' => 'Minutos',
|
||||
'Class:SLT/Attribute:unit/Value:minutes+' => 'Minutos',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkSLAToSLT
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkSLAToSLT' => 'Link SLA / SLT',
|
||||
'Class:lnkSLAToSLT+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_id' => 'SLA',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_id+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_name' => 'Nome SLA',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_name+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_id' => 'SLT',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_id+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_name' => 'Nome SLT',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkCustomerContractToService
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkCustomerContractToService' => 'Link Contrato cliente / Serviço',
|
||||
'Class:lnkCustomerContractToService+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_id' => 'Contrato cliente',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_name' => 'Nome contrato cliente',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_name+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_id' => 'Serviço',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_name' => 'Nome serviço',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_name+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_id' => 'SLA',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_name' => 'Nome SLA',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkCustomerContractToProviderContract
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkCustomerContractToProviderContract' => 'Link Contrato cliente / Contrato provedor(a)',
|
||||
'Class:lnkCustomerContractToProviderContract+' => '',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:customercontract_id' => 'Contrato cliente',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:customercontract_id+' => '',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:customercontract_name' => 'Nome contrato cliente',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:customercontract_name+' => '',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:providercontract_id' => 'Contrato provedor(a)',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:providercontract_id+' => '',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:providercontract_name' => 'Nome contrato provedor(a)',
|
||||
'Class:lnkCustomerContractToProviderContract/Attribute:providercontract_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkCustomerContractToFunctionalCI
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkCustomerContractToFunctionalCI' => 'Link Contrato cliente / CI',
|
||||
'Class:lnkCustomerContractToFunctionalCI+' => '',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:customercontract_id' => 'Contrato cliente',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:customercontract_id+' => '',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:customercontract_name' => 'Nome contrato cliente',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:customercontract_name+' => '',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:functionalci_id' => 'CIs',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:functionalci_name' => 'Nome CI',
|
||||
'Class:lnkCustomerContractToFunctionalCI/Attribute:functionalci_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: DeliveryModel
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:DeliveryModel' => 'Modelo entrega',
|
||||
'Class:DeliveryModel+' => '',
|
||||
'Class:DeliveryModel/Attribute:name' => 'Nome',
|
||||
'Class:DeliveryModel/Attribute:name+' => '',
|
||||
'Class:DeliveryModel/Attribute:org_id' => 'Organização',
|
||||
'Class:DeliveryModel/Attribute:org_id+' => '',
|
||||
'Class:DeliveryModel/Attribute:organization_name' => 'Nome organização',
|
||||
'Class:DeliveryModel/Attribute:organization_name+' => '',
|
||||
'Class:DeliveryModel/Attribute:description' => 'Descrição',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contatos',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Todos os contatos (Equipe e Pessoa) para esse Modelo entrega',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Clientes',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'Todos os clientes com esse Modelo entrega',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkDeliveryModelToContact
|
||||
//
|
||||
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:lnkDeliveryModelToContact' => 'Link Modelo entrega / Contato',
|
||||
'Class:lnkDeliveryModelToContact+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id' => 'Modelo entrega',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_name' => 'Nome Modelo entrega',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_name+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_id' => 'Contato',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_name' => 'Nome contato',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_name+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_id' => 'Regra',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_name' => 'Nome regra',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_name+' => '',
|
||||
));
|
||||
|
||||
?>
|
||||
@@ -1,271 +1,110 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Organization/Attribute:deliverymodel_id' => 'Модель доставки~~',
|
||||
'Menu:ServiceManagement' => 'Управление услугами',
|
||||
'Menu:ServiceManagement+' => 'Управление услугами',
|
||||
'Menu:Service:Overview' => 'Обзор',
|
||||
'Menu:Service:Overview+' => '',
|
||||
'UI-ServiceManagementMenu-ContractsBySrvLevel' => 'Договоры по уровню услуг',
|
||||
'UI-ServiceManagementMenu-ContractsByStatus' => 'Договоры по статусу',
|
||||
'UI-ServiceManagementMenu-ContractsEndingIn30Days' => 'Договоры, оканчивающиеся в течение 30-ти дней',
|
||||
|
||||
'Menu:ServiceType' => 'Типы услуг',
|
||||
'Menu:ServiceType+' => 'Типы услуг',
|
||||
'Menu:ProviderContract' => 'Договоры с поставщиками',
|
||||
'Menu:ProviderContract+' => 'Договоры с поставщиками',
|
||||
'Menu:CustomerContract' => 'Договоры с заказчиками',
|
||||
'Menu:CustomerContract+' => 'Договоры с заказчиками',
|
||||
'Menu:ServiceSubcategory' => 'Подкатегории услуг',
|
||||
'Menu:ServiceSubcategory+' => 'Подкатегории услуг',
|
||||
'Menu:Service' => 'Услуги',
|
||||
'Menu:Service+' => 'Услуги',
|
||||
'Menu:ServiceElement' => 'Элементы услуг',
|
||||
'Menu:ServiceElement+' => 'Элементы услуг',
|
||||
'Menu:SLA' => 'SLA',
|
||||
'Menu:SLA+' => 'Соглашения об уровне услуг',
|
||||
'Menu:SLT' => 'SLT',
|
||||
'Menu:SLT+' => 'Целевые показатели уровня услуг',
|
||||
'Menu:DeliveryModel' => 'Модели предоставления услуг',
|
||||
'Menu:DeliveryModel+' => 'Модели предоставления услуг (Delivery models)',
|
||||
'Menu:ServiceFamily' => 'Пакеты услуг',
|
||||
'Menu:ServiceFamily+' => 'Пакеты услуг',
|
||||
'Menu:Procedure' => 'Каталог процедур',
|
||||
'Menu:Procedure+' => 'Каталог процедур',
|
||||
|
||||
|
||||
|
||||
));
|
||||
|
||||
//
|
||||
// Class: Organization
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Organization/Attribute:deliverymodel_id' => 'Delivery model',
|
||||
'Class:Organization/Attribute:deliverymodel_id+' => '',
|
||||
'Class:Organization/Attribute:deliverymodel_name' => 'Delivery model name~~',
|
||||
'Class:Organization/Attribute:deliverymodel_name+' => '',
|
||||
'Class:ContractType' => 'Contract Type~~',
|
||||
'Class:Organization/Attribute:deliverymodel_name' => 'Delivery model name',
|
||||
|
||||
));
|
||||
|
||||
|
||||
//
|
||||
// Class: ContractType
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:ContractType' => 'Тип договора',
|
||||
'Class:ContractType+' => '',
|
||||
'Class:CustomerContract' => 'Договора с клиентами',
|
||||
'Class:CustomerContract+' => '',
|
||||
'Class:CustomerContract/Attribute:services_list' => 'Services~~',
|
||||
'Class:CustomerContract/Attribute:services_list+' => '',
|
||||
'Class:ProviderContract' => 'Договора с поставщиками',
|
||||
'Class:ProviderContract+' => '',
|
||||
'Class:ProviderContract/Attribute:functionalcis_list' => 'CIs~~',
|
||||
'Class:ProviderContract/Attribute:functionalcis_list+' => '',
|
||||
'Class:ProviderContract/Attribute:sla' => 'SLA',
|
||||
'Class:ProviderContract/Attribute:sla+' => 'Договор об уровне сервиса',
|
||||
'Class:ProviderContract/Attribute:coverage' => 'Время работы',
|
||||
'Class:ProviderContract/Attribute:coverage+' => '',
|
||||
'Class:lnkContactToContract' => 'Link Contact / Contract~~',
|
||||
'Class:lnkContactToContract+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contract_id' => 'Contract~~',
|
||||
'Class:lnkContactToContract/Attribute:contract_id+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contact_id' => 'Contact~~',
|
||||
'Class:lnkContactToContract/Attribute:contact_id+' => '',
|
||||
'Class:lnkContractToDocument' => 'Link Contract / Document~~',
|
||||
'Class:lnkContractToDocument+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:contract_id' => 'Contract~~',
|
||||
'Class:lnkContractToDocument/Attribute:contract_id+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:document_id' => 'Document~~',
|
||||
'Class:lnkContractToDocument/Attribute:document_id+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract' => 'Link FunctionalCI / ProviderContract~~',
|
||||
'Class:lnkFunctionalCIToProviderContract+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id' => 'Provider contract~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id+' => '',
|
||||
'Class:ServiceFamily' => 'Service Familly~~',
|
||||
'Class:ServiceFamily+' => '',
|
||||
'Class:ServiceFamily/Attribute:name' => 'Name~~',
|
||||
'Class:ServiceFamily/Attribute:name+' => '',
|
||||
'Class:ServiceFamily/Attribute:services_list' => 'Services~~',
|
||||
'Class:ServiceFamily/Attribute:services_list+' => '',
|
||||
'Class:Service' => 'Услуга',
|
||||
'Class:Service+' => '',
|
||||
'Class:Service/Attribute:name' => 'Название',
|
||||
'Class:Service/Attribute:name+' => '',
|
||||
'Class:Service/Attribute:org_id' => 'Поставщик',
|
||||
'Class:Service/Attribute:org_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:description' => 'Описание',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents~~',
|
||||
'Class:Service/Attribute:documents_list+' => '',
|
||||
'Class:Service/Attribute:contacts_list' => 'Contacts~~',
|
||||
'Class:Service/Attribute:contacts_list+' => '',
|
||||
'Class:Service/Attribute:status' => 'Статус',
|
||||
'Class:Service/Attribute:status+' => '',
|
||||
'Class:Service/Attribute:status/Value:implementation' => 'implementation~~',
|
||||
'Class:Service/Attribute:status/Value:implementation+' => '',
|
||||
'Class:Service/Attribute:status/Value:obsolete' => 'Устаревший',
|
||||
'Class:Service/Attribute:status/Value:obsolete+' => '',
|
||||
'Class:Service/Attribute:status/Value:production' => 'Производство',
|
||||
'Class:Service/Attribute:status/Value:production+' => '',
|
||||
'Class:Service/Attribute:customercontracts_list' => 'Customer contracts~~',
|
||||
'Class:Service/Attribute:customercontracts_list+' => '',
|
||||
'Class:Service/Attribute:providercontracts_list' => 'Provider contracts~~',
|
||||
'Class:Service/Attribute:providercontracts_list+' => '',
|
||||
'Class:Service/Attribute:functionalcis_list' => 'Depends on CIs~~',
|
||||
'Class:Service/Attribute:functionalcis_list+' => '',
|
||||
'Class:Service/Attribute:servicesubcategories_list' => 'Service sub categories~~',
|
||||
'Class:Service/Attribute:servicesubcategories_list+' => '',
|
||||
'Class:lnkDocumentToService' => 'Link Document / Service~~',
|
||||
'Class:lnkDocumentToService+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:service_id' => 'Service~~',
|
||||
'Class:lnkDocumentToService/Attribute:service_id+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:document_id' => 'Document~~',
|
||||
'Class:lnkDocumentToService/Attribute:document_id+' => '',
|
||||
'Class:lnkContactToService' => 'Link Contact / Service~~',
|
||||
'Class:lnkContactToService+' => '',
|
||||
'Class:lnkContactToService/Attribute:service_id' => 'Service~~',
|
||||
'Class:lnkContactToService/Attribute:service_id+' => '',
|
||||
'Class:lnkContactToService/Attribute:contact_id' => 'Contact~~',
|
||||
'Class:lnkContactToService/Attribute:contact_id+' => '',
|
||||
'Class:ServiceSubcategory' => 'Подкатегории услуг',
|
||||
'Class:ServiceSubcategory+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:name' => 'Название',
|
||||
'Class:ServiceSubcategory/Attribute:name+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:description' => 'Описание',
|
||||
'Class:ServiceSubcategory/Attribute:description+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:service_id' => 'Услуга',
|
||||
'Class:ServiceSubcategory/Attribute:service_id+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:request_type' => 'Request type~~',
|
||||
'Class:ServiceSubcategory/Attribute:request_type+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:incident' => 'incident~~',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:incident+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:service_request' => 'service request~~',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:service_request+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status' => 'Status~~',
|
||||
'Class:ServiceSubcategory/Attribute:status+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:implementation' => 'implementation~~',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:implementation+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:obsolete' => 'obsolete~~',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:obsolete+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:production' => 'production~~',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:production+' => '',
|
||||
'Class:SLA' => 'SLA',
|
||||
'Class:SLA+' => '',
|
||||
'Class:SLA/Attribute:name' => 'Название',
|
||||
'Class:SLA/Attribute:name+' => '',
|
||||
'Class:SLA/Attribute:description' => 'description~~',
|
||||
'Class:SLA/Attribute:description+' => '',
|
||||
'Class:SLA/Attribute:org_id' => 'Provider~~',
|
||||
'Class:SLA/Attribute:org_id+' => '',
|
||||
'Class:SLA/Attribute:slts_list' => 'SLTs~~',
|
||||
'Class:SLA/Attribute:slts_list+' => '',
|
||||
'Class:SLA/Attribute:customercontracts_list' => 'Customer contracts~~',
|
||||
'Class:SLA/Attribute:customercontracts_list+' => '',
|
||||
'Class:SLT' => 'SLT',
|
||||
'Class:SLT+' => 'Порог уровня услуги',
|
||||
'Class:SLT/Attribute:name' => 'Название',
|
||||
'Class:SLT/Attribute:name+' => '',
|
||||
'Class:SLT/Attribute:priority' => 'Priority~~',
|
||||
'Class:SLT/Attribute:priority+' => '',
|
||||
'Class:SLT/Attribute:priority/Value:1' => 'critical~~',
|
||||
'Class:SLT/Attribute:priority/Value:1+' => '',
|
||||
'Class:SLT/Attribute:priority/Value:2' => 'high~~',
|
||||
'Class:SLT/Attribute:priority/Value:2+' => '',
|
||||
'Class:SLT/Attribute:priority/Value:3' => 'medium~~',
|
||||
'Class:SLT/Attribute:priority/Value:3+' => '',
|
||||
'Class:SLT/Attribute:priority/Value:4' => 'low~~',
|
||||
'Class:SLT/Attribute:priority/Value:4+' => '',
|
||||
'Class:SLT/Attribute:request_type' => 'Request type~~',
|
||||
'Class:SLT/Attribute:request_type+' => '',
|
||||
'Class:SLT/Attribute:request_type/Value:incident' => 'incident~~',
|
||||
'Class:SLT/Attribute:request_type/Value:incident+' => '',
|
||||
'Class:SLT/Attribute:request_type/Value:service_request' => 'service request~~',
|
||||
'Class:SLT/Attribute:request_type/Value:service_request+' => '',
|
||||
'Class:SLT/Attribute:metric' => 'Метрика',
|
||||
'Class:SLT/Attribute:metric+' => '',
|
||||
'Class:SLT/Attribute:metric/Value:tto' => 'TTO~~',
|
||||
'Class:SLT/Attribute:metric/Value:tto+' => '',
|
||||
'Class:SLT/Attribute:metric/Value:ttr' => 'TTR~~',
|
||||
'Class:SLT/Attribute:metric/Value:ttr+' => '',
|
||||
'Class:SLT/Attribute:value' => 'Значение',
|
||||
'Class:SLT/Attribute:value+' => '',
|
||||
'Class:SLT/Attribute:unit' => 'Unit~~',
|
||||
'Class:SLT/Attribute:unit+' => '',
|
||||
'Class:SLT/Attribute:unit/Value:hours' => 'hours~~',
|
||||
'Class:SLT/Attribute:unit/Value:hours+' => '',
|
||||
'Class:SLT/Attribute:unit/Value:minutes' => 'minutes~~',
|
||||
'Class:SLT/Attribute:unit/Value:minutes+' => '',
|
||||
'Class:lnkSLAToSLT' => 'Link SLA / SLT~~',
|
||||
'Class:lnkSLAToSLT+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_id' => 'SLA~~',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_id+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_id' => 'SLT~~',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_id+' => '',
|
||||
'Class:lnkCustomerContractToService' => 'Link Customer Contract / Service~~',
|
||||
'Class:lnkCustomerContractToService+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_id' => 'Customer contract~~',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_id' => 'Service~~',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_id' => 'SLA~~',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_id+' => '',
|
||||
'Class:lnkProviderContractToService' => 'Link Provider Contract / Service~~',
|
||||
'Class:lnkProviderContractToService+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:service_id' => 'Service~~',
|
||||
'Class:lnkProviderContractToService/Attribute:service_id+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_id' => 'Provider contract~~',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_id+' => '',
|
||||
'Class:lnkFunctionalCIToService' => 'Link FunctionalCI / Service~~',
|
||||
'Class:lnkFunctionalCIToService+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Service~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id+' => '',
|
||||
'Class:DeliveryModel' => 'Delivery Model~~',
|
||||
'Class:DeliveryModel+' => '',
|
||||
'Class:DeliveryModel/Attribute:name' => 'Name~~',
|
||||
'Class:DeliveryModel/Attribute:name+' => '',
|
||||
'Class:DeliveryModel/Attribute:org_id' => 'Organization~~',
|
||||
'Class:DeliveryModel/Attribute:org_id+' => '',
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description~~',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => '',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => '',
|
||||
'Class:lnkDeliveryModelToContact' => 'Link Delivery Model / Contact~~',
|
||||
'Class:lnkDeliveryModelToContact+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id' => 'Delivery model~~',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_id' => 'Contact~~',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_id' => 'Role~~',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_id+' => '',
|
||||
'Menu:ServiceManagement' => 'Управление сервисами',
|
||||
'Menu:ServiceManagement+' => 'Обзор управление сервисами',
|
||||
'Menu:Service:Overview' => 'Обзор',
|
||||
'Menu:Service:Overview+' => '',
|
||||
'UI-ServiceManagementMenu-ContractsBySrvLevel' => 'Договоры по уровню сервиса',
|
||||
'UI-ServiceManagementMenu-ContractsByStatus' => 'Договоры по статусу',
|
||||
'UI-ServiceManagementMenu-ContractsEndingIn30Days' => 'Договоры заканчивающиеся в течении 30-ти ней',
|
||||
'Menu:ServiceType' => 'Типы сервисов',
|
||||
'Menu:ServiceType+' => 'Типы сервисов',
|
||||
'Menu:ProviderContract' => 'Договоры с поставщиками',
|
||||
'Menu:ProviderContract+' => 'Договоры с поставщиками',
|
||||
'Menu:CustomerContract' => 'Договоры с клиентами',
|
||||
'Menu:CustomerContract+' => 'Договоры с клиентами',
|
||||
'Menu:ServiceSubcategory' => 'Подкатегории сервисов',
|
||||
'Menu:ServiceSubcategory+' => 'Подкатегории сервисов',
|
||||
'Menu:Service' => 'Сервисы',
|
||||
'Menu:Service+' => 'Сервисы',
|
||||
'Menu:ServiceElement' => 'Sevice elements~~',
|
||||
'Menu:ServiceElement+' => '',
|
||||
'Menu:SLA' => 'SLAs',
|
||||
'Menu:SLA+' => 'Соглашения об уровне обслуживания',
|
||||
'Menu:SLT' => 'SLTs',
|
||||
'Menu:SLT+' => 'Цели уровня обслуживания',
|
||||
'Menu:RequestTemplate' => 'Request Templates~~',
|
||||
'Menu:RequestTemplate+' => '',
|
||||
'Menu:DeliveryModel' => 'Delivery models~~',
|
||||
'Menu:DeliveryModel+' => '',
|
||||
'Menu:ServiceFamily' => 'Service families~~',
|
||||
'Menu:ServiceFamily+' => '',
|
||||
'Menu:Procedure' => 'Procedures catalog~~',
|
||||
'Menu:Procedure+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: Contract
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Contract' => 'Договор',
|
||||
'Class:Contract+' => '',
|
||||
'Class:Contract/Attribute:name' => 'Название',
|
||||
'Class:Contract/Attribute:name+' => '',
|
||||
'Class:Contract/Attribute:org_id' => 'Customer~~',
|
||||
'Class:Contract/Attribute:org_id' => 'Заказчик',
|
||||
'Class:Contract/Attribute:org_id+' => '',
|
||||
'Class:Contract/Attribute:organization_name' => 'Customer Name~~',
|
||||
'Class:Contract/Attribute:organization_name+' => '',
|
||||
'Class:Contract/Attribute:contacts_list' => 'Contacts~~',
|
||||
'Class:Contract/Attribute:contacts_list+' => '',
|
||||
'Class:Contract/Attribute:documents_list' => 'Documents~~',
|
||||
'Class:Contract/Attribute:documents_list+' => '',
|
||||
'Class:Contract/Attribute:description' => 'Орисание',
|
||||
'Class:Contract/Attribute:organization_name' => 'Имя заказчика',
|
||||
'Class:Contract/Attribute:organization_name+' => 'Common name',
|
||||
'Class:Contract/Attribute:contacts_list' => 'Контакты',
|
||||
'Class:Contract/Attribute:contacts_list+' => 'Связанные контакты',
|
||||
'Class:Contract/Attribute:documents_list' => 'Документы',
|
||||
'Class:Contract/Attribute:documents_list+' => 'Связанные документы',
|
||||
'Class:Contract/Attribute:description' => 'Описание',
|
||||
'Class:Contract/Attribute:description+' => '',
|
||||
'Class:Contract/Attribute:start_date' => 'Дата начала',
|
||||
'Class:Contract/Attribute:start_date+' => '',
|
||||
@@ -279,85 +118,404 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Contract/Attribute:cost_currency/Value:dollars+' => '',
|
||||
'Class:Contract/Attribute:cost_currency/Value:euros' => 'Евро',
|
||||
'Class:Contract/Attribute:cost_currency/Value:euros+' => '',
|
||||
'Class:Contract/Attribute:contracttype_id' => 'Contract type~~',
|
||||
'Class:Contract/Attribute:contracttype_id' => 'Тип договора',
|
||||
'Class:Contract/Attribute:contracttype_id+' => '',
|
||||
'Class:Contract/Attribute:contracttype_name' => 'Contract type Name~~',
|
||||
'Class:Contract/Attribute:contracttype_name' => 'Имя типа договора',
|
||||
'Class:Contract/Attribute:contracttype_name+' => '',
|
||||
'Class:Contract/Attribute:billing_frequency' => 'Частота платежей',
|
||||
'Class:Contract/Attribute:billing_frequency+' => '',
|
||||
'Class:Contract/Attribute:cost_unit' => 'Единица стоимости',
|
||||
'Class:Contract/Attribute:cost_unit+' => '',
|
||||
'Class:Contract/Attribute:provider_id' => 'Provider~~',
|
||||
'Class:Contract/Attribute:provider_id' => 'Поставщик',
|
||||
'Class:Contract/Attribute:provider_id+' => '',
|
||||
'Class:Contract/Attribute:provider_name' => 'Provider Name~~',
|
||||
'Class:Contract/Attribute:provider_name+' => '',
|
||||
'Class:Contract/Attribute:status' => 'Status~~',
|
||||
'Class:Contract/Attribute:provider_name' => 'Имя поставщика',
|
||||
'Class:Contract/Attribute:provider_name+' => 'Common name',
|
||||
'Class:Contract/Attribute:status' => 'Статус',
|
||||
'Class:Contract/Attribute:status+' => '',
|
||||
'Class:Contract/Attribute:status/Value:implementation' => 'implementation~~',
|
||||
'Class:Contract/Attribute:status/Value:implementation+' => '',
|
||||
'Class:Contract/Attribute:status/Value:obsolete' => 'obsolete~~',
|
||||
'Class:Contract/Attribute:status/Value:obsolete+' => '',
|
||||
'Class:Contract/Attribute:status/Value:production' => 'production~~',
|
||||
'Class:Contract/Attribute:status/Value:production+' => '',
|
||||
'Class:Contract/Attribute:finalclass' => 'Тип',
|
||||
'Class:Contract/Attribute:status/Value:implementation' => 'Внедрение',
|
||||
'Class:Contract/Attribute:status/Value:implementation+' => 'implementation',
|
||||
'Class:Contract/Attribute:status/Value:obsolete' => 'Устаревшее',
|
||||
'Class:Contract/Attribute:status/Value:obsolete+' => 'obsolete',
|
||||
'Class:Contract/Attribute:status/Value:production' => 'Производство',
|
||||
'Class:Contract/Attribute:status/Value:production+' => 'production',
|
||||
'Class:Contract/Attribute:finalclass' => 'Тип договора',
|
||||
'Class:Contract/Attribute:finalclass+' => '',
|
||||
'Class:ProviderContract/Attribute:contracttype_id' => 'Contract type~~',
|
||||
));
|
||||
//
|
||||
// Class: CustomerContract
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:CustomerContract' => 'Договор с заказчиком',
|
||||
'Class:CustomerContract+' => '',
|
||||
'Class:CustomerContract/Attribute:services_list' => 'Услуги',
|
||||
'Class:CustomerContract/Attribute:services_list+' => 'Связанные услуги',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ProviderContract
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:ProviderContract' => 'Договор с поставщиком',
|
||||
'Class:ProviderContract+' => '',
|
||||
'Class:ProviderContract/Attribute:functionalcis_list' => 'КЕ',
|
||||
'Class:ProviderContract/Attribute:functionalcis_list+' => 'Связанные конфигурационные единицы',
|
||||
'Class:ProviderContract/Attribute:sla' => 'SLA',
|
||||
'Class:ProviderContract/Attribute:sla+' => 'Соглашение об уровне услуги (Service Level Agreement)',
|
||||
'Class:ProviderContract/Attribute:coverage' => 'Время работы',
|
||||
'Class:ProviderContract/Attribute:coverage+' => '',
|
||||
'Class:ProviderContract/Attribute:contracttype_id' => 'Тип договора',
|
||||
'Class:ProviderContract/Attribute:contracttype_id+' => '',
|
||||
'Class:ProviderContract/Attribute:contracttype_name' => 'Contract type name~~',
|
||||
'Class:ProviderContract/Attribute:contracttype_name' => 'Имя типа договора',
|
||||
'Class:ProviderContract/Attribute:contracttype_name+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contract_name' => 'Contract Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkContactToContract
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkContactToContract' => 'Связь Контакт/Договор',
|
||||
'Class:lnkContactToContract+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contract_id' => 'Договор',
|
||||
'Class:lnkContactToContract/Attribute:contract_id+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contract_name' => 'Имя договора',
|
||||
'Class:lnkContactToContract/Attribute:contract_name+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contact_name' => 'Contact Name~~',
|
||||
'Class:lnkContactToContract/Attribute:contact_id' => 'Контакт',
|
||||
'Class:lnkContactToContract/Attribute:contact_id+' => '',
|
||||
'Class:lnkContactToContract/Attribute:contact_name' => 'Контактное лицо',
|
||||
'Class:lnkContactToContract/Attribute:contact_name+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:contract_name' => 'Contract Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkContractToDocument
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkContractToDocument' => 'Связь Договор/Документ',
|
||||
'Class:lnkContractToDocument+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:contract_id' => 'Договор',
|
||||
'Class:lnkContractToDocument/Attribute:contract_id+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:contract_name' => 'Имя договора',
|
||||
'Class:lnkContractToDocument/Attribute:contract_name+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:document_name' => 'Document Name~~',
|
||||
'Class:lnkContractToDocument/Attribute:document_id' => 'Документ',
|
||||
'Class:lnkContractToDocument/Attribute:document_id+' => '',
|
||||
'Class:lnkContractToDocument/Attribute:document_name' => 'Имя документа',
|
||||
'Class:lnkContractToDocument/Attribute:document_name+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name' => 'Provider contract Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkFunctionalCIToProviderContract
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkFunctionalCIToProviderContract' => 'Связь Функциональная КЕ/Договор с поставщиком',
|
||||
'Class:lnkFunctionalCIToProviderContract+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id' => 'Договор с поставщиком',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name' => 'Имя договора поставщика',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name' => 'CI Name~~',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id' => 'КЕ',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name' => 'Имя КЕ',
|
||||
'Class:lnkFunctionalCIToProviderContract/Attribute:functionalci_name+' => '',
|
||||
'Class:Service/Attribute:organization_name' => 'Provider Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ServiceFamily
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:ServiceFamily' => 'Пакет услуг',
|
||||
'Class:ServiceFamily+' => '',
|
||||
'Class:ServiceFamily/Attribute:name' => 'Название',
|
||||
'Class:ServiceFamily/Attribute:name+' => '',
|
||||
'Class:ServiceFamily/Attribute:services_list' => 'Услуги',
|
||||
'Class:ServiceFamily/Attribute:services_list+' => 'Связанные услуги',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: Service
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Service' => 'Услуга',
|
||||
'Class:Service+' => '',
|
||||
'Class:Service/Attribute:name' => 'Название',
|
||||
'Class:Service/Attribute:name+' => '',
|
||||
'Class:Service/Attribute:org_id' => 'Поставщик',
|
||||
'Class:Service/Attribute:org_id+' => '',
|
||||
'Class:Service/Attribute:organization_name' => 'Имя поставщика',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Имя пакета услуг',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:service_name' => 'Service Name~~',
|
||||
'Class:Service/Attribute:description' => 'Описание',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Документы',
|
||||
'Class:Service/Attribute:documents_list+' => 'Связанные документы',
|
||||
'Class:Service/Attribute:contacts_list' => 'Контакты',
|
||||
'Class:Service/Attribute:contacts_list+' => 'Связанные контакты',
|
||||
'Class:Service/Attribute:status' => 'Статус',
|
||||
'Class:Service/Attribute:status+' => '',
|
||||
'Class:Service/Attribute:status/Value:implementation' => 'Внедрение',
|
||||
'Class:Service/Attribute:status/Value:implementation+' => '',
|
||||
'Class:Service/Attribute:status/Value:obsolete' => 'Устаревшее',
|
||||
'Class:Service/Attribute:status/Value:obsolete+' => '',
|
||||
'Class:Service/Attribute:status/Value:production' => 'Производство',
|
||||
'Class:Service/Attribute:status/Value:production+' => '',
|
||||
'Class:Service/Attribute:customercontracts_list' => 'Договоры с заказчиками',
|
||||
'Class:Service/Attribute:customercontracts_list+' => 'Договоры с заказчиками',
|
||||
'Class:Service/Attribute:providercontracts_list' => 'Договоры с поставщиками',
|
||||
'Class:Service/Attribute:providercontracts_list+' => 'Договоры с поставщиками',
|
||||
'Class:Service/Attribute:functionalcis_list' => 'Зависимость от КЕ',
|
||||
'Class:Service/Attribute:functionalcis_list+' => 'Зависимость услуги от конфигурационных единиц',
|
||||
'Class:Service/Attribute:servicesubcategories_list' => 'Подкатегории услуги',
|
||||
'Class:Service/Attribute:servicesubcategories_list+' => 'Подкатегории услуги',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkDocumentToService
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkDocumentToService' => 'Связь Документ/Услуга',
|
||||
'Class:lnkDocumentToService+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:service_id' => 'Услуга',
|
||||
'Class:lnkDocumentToService/Attribute:service_id+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:service_name' => 'Имя услуги',
|
||||
'Class:lnkDocumentToService/Attribute:service_name+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:document_name' => 'Document Name~~',
|
||||
'Class:lnkDocumentToService/Attribute:document_id' => 'Документ',
|
||||
'Class:lnkDocumentToService/Attribute:document_id+' => '',
|
||||
'Class:lnkDocumentToService/Attribute:document_name' => 'Имя документа',
|
||||
'Class:lnkDocumentToService/Attribute:document_name+' => '',
|
||||
'Class:lnkContactToService/Attribute:service_name' => 'Service Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkContactToService
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkContactToService' => 'Связь Контакт/Услуга',
|
||||
'Class:lnkContactToService+' => '',
|
||||
'Class:lnkContactToService/Attribute:service_id' => 'Услуга',
|
||||
'Class:lnkContactToService/Attribute:service_id+' => '',
|
||||
'Class:lnkContactToService/Attribute:service_name' => 'Имя услуги',
|
||||
'Class:lnkContactToService/Attribute:service_name+' => '',
|
||||
'Class:lnkContactToService/Attribute:contact_name' => 'Contact Name~~',
|
||||
'Class:lnkContactToService/Attribute:contact_id' => 'Контакт',
|
||||
'Class:lnkContactToService/Attribute:contact_id+' => '',
|
||||
'Class:lnkContactToService/Attribute:contact_name' => 'Контактное лицо',
|
||||
'Class:lnkContactToService/Attribute:contact_name+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: ServiceSubcategory
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:ServiceSubcategory' => 'Подкатегория услуги',
|
||||
'Class:ServiceSubcategory+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:name' => 'Название',
|
||||
'Class:ServiceSubcategory/Attribute:name+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:description' => 'Описание',
|
||||
'Class:ServiceSubcategory/Attribute:description+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:service_id' => 'Услуга',
|
||||
'Class:ServiceSubcategory/Attribute:service_id+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:service_name' => 'Услуга',
|
||||
'Class:ServiceSubcategory/Attribute:service_name+' => '',
|
||||
'Class:SLA/Attribute:organization_name' => 'Provider Name~~',
|
||||
'Class:SLA/Attribute:organization_name+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_name' => 'SLA Name~~',
|
||||
'Class:ServiceSubcategory/Attribute:request_type' => 'Тип запроса',
|
||||
'Class:ServiceSubcategory/Attribute:request_type+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:incident' => 'Инцидент',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:incident+' => 'incident',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:service_request' => 'Запрос на обслуживание',
|
||||
'Class:ServiceSubcategory/Attribute:request_type/Value:service_request+' => 'service request',
|
||||
'Class:ServiceSubcategory/Attribute:status' => 'Статус',
|
||||
'Class:ServiceSubcategory/Attribute:status+' => '',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:implementation' => 'Внедрение',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:implementation+' => 'implementation',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:obsolete' => 'Устаревшее',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:obsolete+' => 'obsolete',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:production' => 'Производство',
|
||||
'Class:ServiceSubcategory/Attribute:status/Value:production+' => 'production',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: SLA
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:SLA' => 'SLA',
|
||||
'Class:SLA+' => '',
|
||||
'Class:SLA/Attribute:name' => 'Название',
|
||||
'Class:SLA/Attribute:name+' => '',
|
||||
'Class:SLA/Attribute:description' => 'Описание',
|
||||
'Class:SLA/Attribute:description+' => '',
|
||||
'Class:SLA/Attribute:org_id' => 'Поставщик',
|
||||
'Class:SLA/Attribute:org_id+' => '',
|
||||
'Class:SLA/Attribute:organization_name' => 'Имя поставщика',
|
||||
'Class:SLA/Attribute:organization_name+' => 'Common name',
|
||||
'Class:SLA/Attribute:slts_list' => 'SLT',
|
||||
'Class:SLA/Attribute:slts_list+' => 'Целевой показатель уровня услуги (Service Level Target)',
|
||||
'Class:SLA/Attribute:customercontracts_list' => 'Договоры с заказчиками',
|
||||
'Class:SLA/Attribute:customercontracts_list+' => 'Договоры с заказчиками',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: SLT
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:SLT' => 'SLT',
|
||||
'Class:SLT+' => '',
|
||||
'Class:SLT/Attribute:name' => 'Название',
|
||||
'Class:SLT/Attribute:name+' => '',
|
||||
'Class:SLT/Attribute:priority' => 'Приоритет',
|
||||
'Class:SLT/Attribute:priority+' => '',
|
||||
'Class:SLT/Attribute:priority/Value:1' => 'Критический',
|
||||
'Class:SLT/Attribute:priority/Value:1+' => 'critical',
|
||||
'Class:SLT/Attribute:priority/Value:2' => 'Высокий',
|
||||
'Class:SLT/Attribute:priority/Value:2+' => 'high',
|
||||
'Class:SLT/Attribute:priority/Value:3' => 'Средний',
|
||||
'Class:SLT/Attribute:priority/Value:3+' => 'medium',
|
||||
'Class:SLT/Attribute:priority/Value:4' => 'Низкий',
|
||||
'Class:SLT/Attribute:priority/Value:4+' => 'low',
|
||||
'Class:SLT/Attribute:request_type' => 'Тип запроса',
|
||||
'Class:SLT/Attribute:request_type+' => '',
|
||||
'Class:SLT/Attribute:request_type/Value:incident' => 'Инцидент',
|
||||
'Class:SLT/Attribute:request_type/Value:incident+' => 'incident',
|
||||
'Class:SLT/Attribute:request_type/Value:service_request' => 'service request',
|
||||
'Class:SLT/Attribute:request_type/Value:service_request+' => 'service request',
|
||||
'Class:SLT/Attribute:metric' => 'Метрика',
|
||||
'Class:SLT/Attribute:metric+' => '',
|
||||
'Class:SLT/Attribute:metric/Value:tto' => 'TTO',
|
||||
'Class:SLT/Attribute:metric/Value:tto+' => 'TTO',
|
||||
'Class:SLT/Attribute:metric/Value:ttr' => 'TTR',
|
||||
'Class:SLT/Attribute:metric/Value:ttr+' => 'TTR',
|
||||
'Class:SLT/Attribute:value' => 'Значение',
|
||||
'Class:SLT/Attribute:value+' => '',
|
||||
'Class:SLT/Attribute:unit' => 'Единицы',
|
||||
'Class:SLT/Attribute:unit+' => '',
|
||||
'Class:SLT/Attribute:unit/Value:hours' => 'Часы',
|
||||
'Class:SLT/Attribute:unit/Value:hours+' => 'часов',
|
||||
'Class:SLT/Attribute:unit/Value:minutes' => 'Минуты',
|
||||
'Class:SLT/Attribute:unit/Value:minutes+' => 'минут',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkSLAToSLT
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkSLAToSLT' => 'Связь SLA/SLT',
|
||||
'Class:lnkSLAToSLT+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_id' => 'SLA',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_id+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_name' => 'Название SLA',
|
||||
'Class:lnkSLAToSLT/Attribute:sla_name+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_name' => 'SLT Name~~',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_id' => 'SLT',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_id+' => '',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_name' => 'Название SLT',
|
||||
'Class:lnkSLAToSLT/Attribute:slt_name+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_name' => 'Customer contract Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkCustomerContractToService
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkCustomerContractToService' => 'Связь Договор с заказчиком/Услуга',
|
||||
'Class:lnkCustomerContractToService+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_id' => 'Договор с заказчиком',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_name' => 'Контактное лицо клиента',
|
||||
'Class:lnkCustomerContractToService/Attribute:customercontract_name+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_name' => 'Service Name~~',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_id' => 'Услуга',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_name' => 'Имя услуги',
|
||||
'Class:lnkCustomerContractToService/Attribute:service_name+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_name' => 'SLA Name~~',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_id' => 'SLA',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_id+' => '',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_name' => 'Название SLA',
|
||||
'Class:lnkCustomerContractToService/Attribute:sla_name+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:service_name' => 'Service Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkProviderContractToService
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkProviderContractToService' => 'Связь Договор с поставщиком/Услуга',
|
||||
'Class:lnkProviderContractToService+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:service_id' => 'Услуга',
|
||||
'Class:lnkProviderContractToService/Attribute:service_id+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:service_name' => 'Имя услуги',
|
||||
'Class:lnkProviderContractToService/Attribute:service_name+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_name' => 'Provider contract Name~~',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_id' => 'Договор с поставщиком',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_id+' => '',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_name' => 'Имя договора поставщика',
|
||||
'Class:lnkProviderContractToService/Attribute:providercontract_name+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Service Name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkFunctionalCIToService
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkFunctionalCIToService' => 'Связь Функциональная КЕ/Услуга',
|
||||
'Class:lnkFunctionalCIToService+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Услуга',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_id+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Имя услуги',
|
||||
'Class:lnkFunctionalCIToService/Attribute:service_name+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_name' => 'CI Name~~',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id' => 'КЕ',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_name' => 'Имя КЕ',
|
||||
'Class:lnkFunctionalCIToService/Attribute:functionalci_name+' => '',
|
||||
'Class:DeliveryModel/Attribute:organization_name' => 'Organization Name~~',
|
||||
'Class:DeliveryModel/Attribute:organization_name+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_name' => 'Delivery model name~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: DeliveryModel
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:DeliveryModel' => 'Модель предоставления услуг',
|
||||
'Class:DeliveryModel+' => '',
|
||||
'Class:DeliveryModel/Attribute:name' => 'Название',
|
||||
'Class:DeliveryModel/Attribute:name+' => '',
|
||||
'Class:DeliveryModel/Attribute:org_id' => 'Организация',
|
||||
'Class:DeliveryModel/Attribute:org_id+' => '',
|
||||
'Class:DeliveryModel/Attribute:organization_name' => 'Название организации',
|
||||
'Class:DeliveryModel/Attribute:organization_name+' => 'Common name',
|
||||
'Class:DeliveryModel/Attribute:description' => 'Описание',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Контакты',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Связанные контакты',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Заказчики',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'Связанные заказчик',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkDeliveryModelToContact
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkDeliveryModelToContact' => 'Связь Модель предоставления услуг/Контакт',
|
||||
'Class:lnkDeliveryModelToContact+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id' => 'Модель предоставления услуг',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_name' => 'Название модели предоставления услуг',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:deliverymodel_name+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_name' => 'Contact name~~',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_id' => 'Контакт',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_name' => 'Контактное лицо',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:contact_name+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_name' => 'Role name~~',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_id' => 'Роль',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_id+' => '',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_name' => 'Должность',
|
||||
'Class:lnkDeliveryModelToContact/Attribute:role_name+' => '',
|
||||
));
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010 Combodo SARL
|
||||
// Copyright (C) 2010-2014 Combodo SARL
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +14,16 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
/**
|
||||
* Module providing advanced CIs for modeling storage: SAN, Volumes...
|
||||
*
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'itop-storage-mgmt/2.0.0',
|
||||
array(
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
|
||||
<constants>
|
||||
<constant id="RESPONSE_TICKET_SLT_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT SLT AS slt JOIN lnkSLAToSLT AS l1 ON l1.slt_id=slt.id JOIN SLA AS sla ON l1.sla_id=sla.id JOIN lnkCustomerContractToService AS l2 ON l2.sla_id=sla.id JOIN CustomerContract AS sc ON l2.customercontract_id=sc.id WHERE slt.metric = :metric AND l2.service_id = :this->service_id AND sc.org_id = :this->org_id AND slt.request_type = :request_type AND slt.priority = :this->priority]]></constant>
|
||||
<constant id="PORTAL_POWER_USER_PROFILE" xsi:type="string" _delta="define"><![CDATA[Portal power user]]></constant>
|
||||
<constant id="PORTAL_SERVICECATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_SERVICE_SUBCATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT ServiceSubcategory WHERE service_id = :svc_id AND ServiceSubcategory.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_VALIDATE_SERVICECATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.id = :id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_VALIDATE_SERVICESUBCATEGORY_QUERY" xsi:type="string" _delta="define"><![CDATA[SELECT ServiceSubcategory AS Sub JOIN Service AS Svc ON Sub.service_id = Svc.id WHERE Sub.id=:id AND Sub.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_ALL_PARAMS" xsi:type="string" _delta="define"><![CDATA[from_service_id,org_id,caller_id,service_id,servicesubcategory_id,title,description,impact,emergency,moreinfo,caller_id,start_date,end_date,duration,impact_duration]]></constant>
|
||||
<constant id="PORTAL_SET_TYPE_FROM" xsi:type="string" _delta="define"><![CDATA[request_type]]></constant>
|
||||
<constant id="PORTAL_TYPE_TO_CLASS" xsi:type="string" _delta="define"><![CDATA[]]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_CRITERIA" xsi:type="string" _delta="define"><![CDATA[ref,start_date,close_date,service_id,caller_id]]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_FILTER_service_id" xsi:type="string" _delta="define"><![CDATA[SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = :org_id AND s.status != 'obsolete']]></constant>
|
||||
<constant id="PORTAL_TICKETS_SEARCH_FILTER_caller_id" xsi:type="string" _delta="define"><![CDATA[SELECT Person WHERE org_id = :org_id]]></constant>
|
||||
</constants>
|
||||
<classes>
|
||||
<class id="Ticket" _delta="define">
|
||||
@@ -37,7 +48,7 @@
|
||||
<field id="ref" xsi:type="AttributeString">
|
||||
<sql>ref</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="org_id" xsi:type="AttributeExternalKey">
|
||||
<sql>org_id</sql>
|
||||
@@ -153,37 +164,53 @@
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ public function DBInsertNoReload()
|
||||
<code><![CDATA[
|
||||
public function DBInsertNoReload()
|
||||
{
|
||||
$oMutex = new iTopMutex('ticket_insert');
|
||||
$oMutex->Lock();
|
||||
$iKey = parent::DBInsertNoReload();
|
||||
$oMutex->Unlock();
|
||||
return $iKey;
|
||||
$oMutex = new iTopMutex('ticket_insert');
|
||||
$oMutex->Lock();
|
||||
$iNextId = MetaModel::GetNextKey(get_class($this));
|
||||
$sRef = $this->MakeTicketRef($iNextId);
|
||||
$this->Set('ref', $sRef);
|
||||
$iKey = parent::DBInsertNoReload();
|
||||
$oMutex->Unlock();
|
||||
return $iKey;
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="DBInsertTracked_Internal">
|
||||
<method id="MakeTicketRef">
|
||||
<static>false</static>
|
||||
<access>protected</access>
|
||||
<type>Overload-DBObject</type>
|
||||
<code><![CDATA[ protected function DBInsertTracked_Internal($bDoNotReload = false)
|
||||
{
|
||||
// Beware !!!
|
||||
// Compensate the fact that CMDBObject::DBInsertTracked_Internal does NOT call the derived version of DBInsertNoReload
|
||||
// when performing an INsert with "no reload" but actually calls it (followed by Reload) when doing an Insert with reload !!
|
||||
if ($bDoNotReload)
|
||||
{
|
||||
$oMutex = new iTopMutex('ticket_insert');
|
||||
$oMutex->Lock();
|
||||
}
|
||||
$ret = parent::DBInsertTracked_Internal($bDoNotReload);
|
||||
if ($bDoNotReload)
|
||||
{
|
||||
$oMutex->Unlock();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
<code><![CDATA[
|
||||
protected function MakeTicketRef($iNextId)
|
||||
{
|
||||
switch(get_class($this))
|
||||
{
|
||||
case 'UserRequest':
|
||||
$sFormat = 'R-%06d';
|
||||
break;
|
||||
|
||||
case 'Incident':
|
||||
$sFormat = 'I-%06d';
|
||||
break;
|
||||
|
||||
case 'Change':
|
||||
case 'RoutineChange':
|
||||
case 'EmergencyChange':
|
||||
case 'NormalChange':
|
||||
$sFormat = 'C-%06d';
|
||||
break;
|
||||
|
||||
case 'Problem':
|
||||
$sFormat = 'P-%06d';
|
||||
break;
|
||||
|
||||
default:
|
||||
$sFormat = 'T-%06d';
|
||||
}
|
||||
return sprintf($sFormat, $iNextId);
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
|
||||
@@ -1,138 +1,186 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// iTop is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
/**
|
||||
* @author Vladimir Shilov <shilow@ukr.net>
|
||||
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
* Локализация интерфейса Combodo iTop подготовлена сообществом iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* Инструкция по установке
|
||||
*
|
||||
* Процесс установки заключается в замене имеющихся локализационных файлов полученными и последующем запуске процедуры обновления iTop для перекомпиляции кода.
|
||||
* 1. Скопируйте с заменой два полученных файла из "itop-rus/dictionaries" в "путь/до/вашего/itop/dictionaries".
|
||||
* 2. Скопируйте с заменой полученные файлы "itop-rus/datamodels/2.x/название-модуля/ru.dict.название-модуля.php" в "путь/до/вашего/itop/datamodels/2.x/название-модуля".
|
||||
* 3. Перейдите по адресу "http://адрес/вашего/itop/setup", при этом файл "путь/до/вашего/itop/conf/production/config-itop.php" должен быть доступен для записи.
|
||||
* 4. На второй странице установщика выберите "Upgrade an existing iTop instance" и следуйте дальнейшим инструкциям установщика.
|
||||
*
|
||||
* Ответы на вопросы по установке и использованию переводов, а также на любые другие вопросы по iTop всегда можно получить на сайте сообщества iTop по-русски http://community.itop-itsm.ru.
|
||||
*
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
|
||||
//
|
||||
// Class: Ticket
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:Ticket' => 'Тикеи',
|
||||
'Class:Ticket' => 'Тикет',
|
||||
'Class:Ticket+' => '',
|
||||
'Class:Ticket/Attribute:ref' => 'Ссылка',
|
||||
'Class:Ticket/Attribute:ref' => 'Номер',
|
||||
'Class:Ticket/Attribute:ref+' => '',
|
||||
'Class:Ticket/Attribute:org_id' => 'Organization~~',
|
||||
'Class:Ticket/Attribute:org_id' => 'Организация',
|
||||
'Class:Ticket/Attribute:org_id+' => '',
|
||||
'Class:Ticket/Attribute:caller_id' => 'Caller~~',
|
||||
'Class:Ticket/Attribute:org_name' => 'Имя организации',
|
||||
'Class:Ticket/Attribute:org_name+' => '',
|
||||
'Class:Ticket/Attribute:caller_id' => 'Инициатор',
|
||||
'Class:Ticket/Attribute:caller_id+' => '',
|
||||
'Class:Ticket/Attribute:team_id' => 'Team~~',
|
||||
'Class:Ticket/Attribute:caller_name' => 'Имя заявителя',
|
||||
'Class:Ticket/Attribute:caller_name+' => '',
|
||||
'Class:Ticket/Attribute:team_id' => 'Команда',
|
||||
'Class:Ticket/Attribute:team_id+' => '',
|
||||
'Class:Ticket/Attribute:agent_id' => 'Agent~~',
|
||||
'Class:Ticket/Attribute:team_name' => 'Имя команды',
|
||||
'Class:Ticket/Attribute:team_name+' => '',
|
||||
'Class:Ticket/Attribute:agent_id' => 'Агент',
|
||||
'Class:Ticket/Attribute:agent_id+' => '',
|
||||
'Class:Ticket/Attribute:agent_name' => 'Имя агента',
|
||||
'Class:Ticket/Attribute:agent_name+' => '',
|
||||
'Class:Ticket/Attribute:title' => 'Название',
|
||||
'Class:Ticket/Attribute:title+' => '',
|
||||
'Class:Ticket/Attribute:description' => 'Описание',
|
||||
'Class:Ticket/Attribute:description+' => '',
|
||||
'Class:Ticket/Attribute:start_date' => 'Начат',
|
||||
'Class:Ticket/Attribute:start_date' => 'Начало',
|
||||
'Class:Ticket/Attribute:start_date+' => '',
|
||||
'Class:Ticket/Attribute:end_date' => 'End date~~',
|
||||
'Class:Ticket/Attribute:end_date' => 'Окончание',
|
||||
'Class:Ticket/Attribute:end_date+' => '',
|
||||
'Class:Ticket/Attribute:last_update' => 'Last update~~',
|
||||
'Class:Ticket/Attribute:last_update' => 'Обновление',
|
||||
'Class:Ticket/Attribute:last_update+' => '',
|
||||
'Class:Ticket/Attribute:close_date' => 'Close date~~',
|
||||
'Class:Ticket/Attribute:close_date' => 'Закрытие',
|
||||
'Class:Ticket/Attribute:close_date+' => '',
|
||||
'Class:Ticket/Attribute:private_log' => 'Private log~~',
|
||||
'Class:Ticket/Attribute:private_log+' => '',
|
||||
'Class:Ticket/Attribute:contacts_list' => 'Contacts~~',
|
||||
'Class:Ticket/Attribute:contacts_list+' => '',
|
||||
'Class:Ticket/Attribute:functionalcis_list' => 'CIs~~',
|
||||
'Class:Ticket/Attribute:functionalcis_list+' => '',
|
||||
'Class:Ticket/Attribute:workorders_list' => 'Work orders~~',
|
||||
'Class:Ticket/Attribute:workorders_list+' => '',
|
||||
'Class:Ticket/Attribute:private_log' => 'Внутренний журнал',
|
||||
'Class:Ticket/Attribute:private_log+' => 'Информация внутреннего журнала пользователям портала недоступна',
|
||||
'Class:Ticket/Attribute:contacts_list' => 'Контакты',
|
||||
'Class:Ticket/Attribute:contacts_list+' => 'Все контакты, связанные с этим тикетом',
|
||||
'Class:Ticket/Attribute:functionalcis_list' => 'КЕ',
|
||||
'Class:Ticket/Attribute:functionalcis_list+' => 'Все конфигурационные единицы, на которые влияет этот тикет',
|
||||
'Class:Ticket/Attribute:workorders_list' => 'Наряды на работу',
|
||||
'Class:Ticket/Attribute:workorders_list+' => 'Наряды на работу',
|
||||
'Class:Ticket/Attribute:finalclass' => 'Тип',
|
||||
'Class:Ticket/Attribute:finalclass+' => '',
|
||||
'Class:lnkContactToTicket' => 'Link Contact / Ticket~~',
|
||||
'Class:lnkContactToTicket+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_id' => 'Ticket~~',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_id+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:contact_id' => 'Contact~~',
|
||||
'Class:lnkContactToTicket/Attribute:contact_id+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:role' => 'Role~~',
|
||||
'Class:lnkContactToTicket/Attribute:role+' => '',
|
||||
'Class:lnkFunctionalCIToTicket' => 'Link FunctionalCI / Ticket~~',
|
||||
'Class:lnkFunctionalCIToTicket+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Ticket~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id' => 'CI~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact' => 'Impact~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact+' => '',
|
||||
'Class:WorkOrder' => 'Work Order~~',
|
||||
'Class:WorkOrder+' => '',
|
||||
'Class:WorkOrder/Attribute:name' => 'Name~~',
|
||||
'Class:WorkOrder/Attribute:name+' => '',
|
||||
'Class:WorkOrder/Attribute:status' => 'Status~~',
|
||||
'Class:WorkOrder/Attribute:status+' => '',
|
||||
'Class:WorkOrder/Attribute:status/Value:open' => 'open~~',
|
||||
'Class:WorkOrder/Attribute:status/Value:open+' => '',
|
||||
'Class:WorkOrder/Attribute:status/Value:closed' => 'closed~~',
|
||||
'Class:WorkOrder/Attribute:status/Value:closed+' => '',
|
||||
'Class:WorkOrder/Attribute:description' => 'Description~~',
|
||||
'Class:WorkOrder/Attribute:description+' => '',
|
||||
'Class:WorkOrder/Attribute:ticket_id' => 'Ticket~~',
|
||||
'Class:WorkOrder/Attribute:ticket_id+' => '',
|
||||
'Class:WorkOrder/Attribute:team_id' => 'Team~~',
|
||||
'Class:WorkOrder/Attribute:team_id+' => '',
|
||||
'Class:WorkOrder/Attribute:agent_id' => 'Agent~~',
|
||||
'Class:WorkOrder/Attribute:agent_id+' => '',
|
||||
'Class:WorkOrder/Attribute:start_date' => 'Start date~~',
|
||||
'Class:WorkOrder/Attribute:start_date+' => '',
|
||||
'Class:WorkOrder/Attribute:end_date' => 'End date~~',
|
||||
'Class:WorkOrder/Attribute:end_date+' => '',
|
||||
'Class:WorkOrder/Attribute:log' => 'Log~~',
|
||||
'Class:WorkOrder/Attribute:log+' => '',
|
||||
'Class:WorkOrder/Stimulus:ev_close' => 'Close~~',
|
||||
'Class:WorkOrder/Stimulus:ev_close+' => '',
|
||||
'Class:Ticket/Attribute:org_name' => 'Organization Name~~',
|
||||
'Class:Ticket/Attribute:org_name+' => '',
|
||||
'Class:Ticket/Attribute:caller_name' => 'Caller Name~~',
|
||||
'Class:Ticket/Attribute:caller_name+' => '',
|
||||
'Class:Ticket/Attribute:team_name' => 'Team Name~~',
|
||||
'Class:Ticket/Attribute:team_name+' => '',
|
||||
'Class:Ticket/Attribute:agent_name' => 'Agent Name~~',
|
||||
'Class:Ticket/Attribute:agent_name+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_ref' => 'Ref~~',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_ref+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:contact_email' => 'Contact Email~~',
|
||||
'Class:lnkContactToTicket/Attribute:contact_email+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Ref~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name' => 'CI Name~~',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name+' => '',
|
||||
'Class:WorkOrder/Attribute:ticket_ref' => 'Ticket ref~~',
|
||||
'Class:WorkOrder/Attribute:ticket_ref+' => '',
|
||||
'Class:WorkOrder/Attribute:team_name' => 'Team Name~~',
|
||||
'Class:WorkOrder/Attribute:team_name+' => '',
|
||||
'Class:WorkOrder/Attribute:agent_email' => 'Agent email~~',
|
||||
'Class:WorkOrder/Attribute:agent_email+' => '',
|
||||
'Ticket:baseinfo' => 'General Information~~',
|
||||
'Ticket:date' => 'Dates~~',
|
||||
'Ticket:contact' => 'Contacts~~',
|
||||
'Ticket:moreinfo' => 'More Information~~',
|
||||
'Ticket:relation' => 'Relations~~',
|
||||
'Ticket:log' => 'Communications~~',
|
||||
'Ticket:Type' => 'Qualification~~',
|
||||
'Ticket:support' => 'Support~~',
|
||||
'Ticket:resolution' => 'Resolution~~',
|
||||
'Ticket:SLA' => 'SLA report~~',
|
||||
'WorkOrder:Details' => 'Details~~',
|
||||
'WorkOrder:Moreinfo' => 'More informations~~',
|
||||
));
|
||||
?>
|
||||
|
||||
|
||||
//
|
||||
// Class: lnkContactToTicket
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkContactToTicket' => 'Связь Контакт/Тикет',
|
||||
'Class:lnkContactToTicket+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_id' => 'Тикет',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_id+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_ref' => 'Связь',
|
||||
'Class:lnkContactToTicket/Attribute:ticket_ref+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:contact_id' => 'Контакт',
|
||||
'Class:lnkContactToTicket/Attribute:contact_id+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:contact_email' => 'Email контакта',
|
||||
'Class:lnkContactToTicket/Attribute:contact_email+' => '',
|
||||
'Class:lnkContactToTicket/Attribute:role' => 'Роль',
|
||||
'Class:lnkContactToTicket/Attribute:role+' => '',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: lnkFunctionalCIToTicket
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:lnkFunctionalCIToTicket' => 'Связь Функциональная КЕ/Тикет',
|
||||
'Class:lnkFunctionalCIToTicket+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Тикет',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Связь',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id' => 'КЕ',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name' => 'Имя КЕ',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name+' => '',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact' => 'Влияние',
|
||||
'Class:lnkFunctionalCIToTicket/Attribute:impact+' => '',
|
||||
));
|
||||
|
||||
|
||||
//
|
||||
// Class: WorkOrder
|
||||
//
|
||||
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:WorkOrder' => 'Наряд на работу',
|
||||
'Class:WorkOrder+' => '',
|
||||
'Class:WorkOrder/Attribute:name' => 'Название',
|
||||
'Class:WorkOrder/Attribute:name+' => '',
|
||||
'Class:WorkOrder/Attribute:status' => 'Статус',
|
||||
'Class:WorkOrder/Attribute:status+' => '',
|
||||
'Class:WorkOrder/Attribute:status/Value:open' => 'Открыт',
|
||||
'Class:WorkOrder/Attribute:status/Value:open+' => '',
|
||||
'Class:WorkOrder/Attribute:status/Value:closed' => 'Закрыт',
|
||||
'Class:WorkOrder/Attribute:status/Value:closed+' => '',
|
||||
'Class:WorkOrder/Attribute:description' => 'Описание',
|
||||
'Class:WorkOrder/Attribute:description+' => '',
|
||||
'Class:WorkOrder/Attribute:ticket_id' => 'Тикет',
|
||||
'Class:WorkOrder/Attribute:ticket_id+' => '',
|
||||
'Class:WorkOrder/Attribute:ticket_ref' => 'Связь тикета',
|
||||
'Class:WorkOrder/Attribute:ticket_ref+' => '',
|
||||
'Class:WorkOrder/Attribute:team_id' => 'Команда',
|
||||
'Class:WorkOrder/Attribute:team_id+' => '',
|
||||
'Class:WorkOrder/Attribute:team_name' => 'Имя тикета',
|
||||
'Class:WorkOrder/Attribute:team_name+' => '',
|
||||
'Class:WorkOrder/Attribute:agent_id' => 'Агент',
|
||||
'Class:WorkOrder/Attribute:agent_id+' => '',
|
||||
'Class:WorkOrder/Attribute:agent_email' => 'Email агента',
|
||||
'Class:WorkOrder/Attribute:agent_email+' => '',
|
||||
'Class:WorkOrder/Attribute:start_date' => 'Дата начала',
|
||||
'Class:WorkOrder/Attribute:start_date+' => '',
|
||||
'Class:WorkOrder/Attribute:end_date' => 'Дата окончания',
|
||||
'Class:WorkOrder/Attribute:end_date+' => '',
|
||||
'Class:WorkOrder/Attribute:log' => 'Журнал',
|
||||
'Class:WorkOrder/Attribute:log+' => '',
|
||||
'Class:WorkOrder/Stimulus:ev_close' => 'Закрыть',
|
||||
'Class:WorkOrder/Stimulus:ev_close+' => '',
|
||||
));
|
||||
|
||||
|
||||
// Fieldset translation
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
|
||||
'Ticket:baseinfo' => 'Общая информация',
|
||||
'Ticket:date' => 'Даты',
|
||||
'Ticket:contact' => 'Контакты',
|
||||
'Ticket:moreinfo' => 'Дополнительная информация',
|
||||
'Ticket:relation' => 'Зависимость',
|
||||
'Ticket:log' => 'Журнал',
|
||||
'Ticket:Type' => 'Приоритет',
|
||||
'Ticket:support' => 'Поддержка',
|
||||
'Ticket:resolution' => 'Решение',
|
||||
'Ticket:SLA' => 'Отчёт SLA',
|
||||
'WorkOrder:Details' => 'Детали',
|
||||
'WorkOrder:Moreinfo' => 'Дополнительная информация',
|
||||
|
||||
));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -214,6 +214,9 @@
|
||||
<item id="org_id">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>25</rank>
|
||||
</item>
|
||||
<item id="business_criticity">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
@@ -364,6 +367,9 @@
|
||||
<item id="org_id">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>25</rank>
|
||||
</item>
|
||||
<item id="server_id">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
@@ -515,6 +521,9 @@
|
||||
<item id="org_id">
|
||||
<rank>20</rank>
|
||||
</item>
|
||||
<item id="status">
|
||||
<rank>25</rank>
|
||||
</item>
|
||||
<item id="business_criticity">
|
||||
<rank>30</rank>
|
||||
</item>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* @author Erwan Taloc <erwan.taloc@combodo.com>
|
||||
* @author Romain Quetiez <romain.quetiez@combodo.com>
|
||||
* @author Denis Flaven <denis.flaven@combodo.com>
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
|
||||
@@ -59,7 +59,7 @@ class ItopWelcome extends ModuleHandlerAPI
|
||||
new WebPageMenuNode('NotificationsMenu', utils::GetAbsoluteUrlAppRoot().'pages/notifications.php', $oAdminMenu->GetIndex(), 3 /* fRank */);
|
||||
new OQLMenuNode('AuditCategories', 'SELECT AuditCategory', $oAdminMenu->GetIndex(), 4 /* fRank */);
|
||||
new WebPageMenuNode('RunQueriesMenu', utils::GetAbsoluteUrlAppRoot().'pages/run_query.php', $oAdminMenu->GetIndex(), 8 /* fRank */);
|
||||
new OQLMenuNode('QueryMenu', 'SELECT Query', $oAdminMenu->GetIndex(), 8.5 /* fRank */);
|
||||
new OQLMenuNode('QueryMenu', 'SELECT Query', $oAdminMenu->GetIndex(), 8.5 /* fRank */, true);
|
||||
new WebPageMenuNode('ExportMenu', utils::GetAbsoluteUrlAppRoot().'webservices/export.php', $oAdminMenu->GetIndex(), 9 /* fRank */);
|
||||
new WebPageMenuNode('DataModelMenu', utils::GetAbsoluteUrlAppRoot().'pages/schema.php', $oAdminMenu->GetIndex(), 10 /* fRank */);
|
||||
new WebPageMenuNode('UniversalSearchMenu', utils::GetAbsoluteUrlAppRoot().'pages/UniversalSearch.php', $oAdminMenu->GetIndex(), 11 /* fRank */);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<information>
|
||||
<version>2.0.2</version>
|
||||
<version>2.0.3</version>
|
||||
</information>
|
||||
|
||||
@@ -810,6 +810,7 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm
|
||||
'Portal:AddAttachment' => ' Attachment hinzufügen',
|
||||
'Portal:RemoveAttachment' => 'Attachment entfernen',
|
||||
'Portal:Attachment_No_To_Ticket_Name' => 'Attachment #%1$d an %2$s (%3$s)',
|
||||
'Portal:SelectRequestTemplate' => 'Wählen Sie eine Template für %1$s',
|
||||
'Enum:Undefined' => 'Nicht definiert',
|
||||
'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s Tage %2$s Stunden %3$s Minuten %4$s Sekunden',
|
||||
'UI:ModifyAllPageTitle' => 'Alle modifizieren',
|
||||
|
||||
@@ -482,6 +482,10 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:TriggerOnObject+' => 'Trigger on a given class of objects',
|
||||
'Class:TriggerOnObject/Attribute:target_class' => 'Target class',
|
||||
'Class:TriggerOnObject/Attribute:target_class+' => '',
|
||||
'Class:TriggerOnObject/Attribute:filter' => 'Filter',
|
||||
'Class:TriggerOnObject/Attribute:filter+' => '',
|
||||
'TriggerOnObject:WrongFilterQuery' => 'Wrong filter query: %1$s',
|
||||
'TriggerOnObject:WrongFilterClass' => 'The filter query must return objects of class "%1$s"',
|
||||
));
|
||||
|
||||
//
|
||||
|
||||
@@ -134,6 +134,9 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
|
||||
'Class:User/Error:LoginMustBeUnique' => 'Login must be unique - "%1s" is already being used.',
|
||||
'Class:User/Error:AtLeastOneProfileIsNeeded' => 'At least one profile must be assigned to this user.',
|
||||
|
||||
'Class:UserInternal' => 'User Internal',
|
||||
'Class:UserInternal+' => 'User defined within iTop',
|
||||
));
|
||||
|
||||
//
|
||||
@@ -576,6 +579,7 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'UI:CSVImport:HeaderMappings' => 'Mappings',
|
||||
'UI:CSVImport:HeaderSearch' => 'Search?',
|
||||
'UI:CSVImport:AlertIncompleteMapping' => 'Please select a mapping for every field.',
|
||||
'UI:CSVImport:AlertMultipleMapping' => 'Please make sure that a target field is mapped only once.',
|
||||
'UI:CSVImport:AlertNoSearchCriteria' => 'Please select at least one search criteria',
|
||||
'UI:CSVImport:Encoding' => 'Character encoding',
|
||||
'UI:UniversalSearchTitle' => 'iTop - Universal Search',
|
||||
@@ -762,6 +766,9 @@ Dict::Add('EN US', 'English', 'English', array(
|
||||
'UI:ObjectDoesNotExist' => 'Sorry, this object does not exist (or you are not allowed to view it).',
|
||||
'UI:SearchResultsPageTitle' => 'iTop - Search Results',
|
||||
'UI:Search:NoSearch' => 'Nothing to search for',
|
||||
'UI:Search:NeedleTooShort' => 'The search string "%1$s" is too short. Please type at least %2$d characters.',
|
||||
'UI:Search:Ongoing' => 'Searching for "%1$s"',
|
||||
'UI:Search:Enlarge' => 'Broaden the search',
|
||||
'UI:FullTextSearchTitle_Text' => 'Results for "%1$s":',
|
||||
'UI:Search:Count_ObjectsOf_Class_Found' => '%1$d object(s) of class %2$s found.',
|
||||
'UI:Search:NoObjectFound' => 'No object found.',
|
||||
@@ -996,6 +1003,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'Portal:AddAttachment' => ' Add Attachment ',
|
||||
'Portal:RemoveAttachment' => ' Remove Attachment ',
|
||||
'Portal:Attachment_No_To_Ticket_Name' => 'Attachment #%1$d to %2$s (%3$s)',
|
||||
'Portal:SelectRequestTemplate' => 'Select a template for %1$s',
|
||||
'Enum:Undefined' => 'Undefined',
|
||||
'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s Days %2$s Hours %3$s Minutes %4$s Seconds',
|
||||
'UI:ModifyAllPageTitle' => 'Modify All',
|
||||
|
||||
@@ -995,6 +995,7 @@ Cuando se asocien con un disparador, cada acción recibe un número de "orden",
|
||||
'Portal:AddAttachment' => 'Agregar Anexo',
|
||||
'Portal:RemoveAttachment' => 'Borrar Anexo',
|
||||
'Portal:Attachment_No_To_Ticket_Name' => 'Anexo #%1$d to %2$s (%3$s)',
|
||||
'Portal:SelectRequestTemplate' => 'Seleccione una Plantilla para %1$s',
|
||||
'Enum:Undefined' => 'No Definido',
|
||||
'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s Días %2$s Hrs. %3$s Mins. %4$s Segs.',
|
||||
'UI:ModifyAllPageTitle' => 'Modificar Todos',
|
||||
|
||||
@@ -544,11 +544,15 @@ Opérateurs :<br/>
|
||||
'Class:Trigger/Attribute:action_list+' => '',
|
||||
'Class:Trigger/Attribute:finalclass' => 'Type',
|
||||
'Class:Trigger/Attribute:finalclass+' => '',
|
||||
'Class:TriggerOnObject' => 'Trigger on a class of objects',
|
||||
'Class:TriggerOnObject' => 'Déclencheur sur modification de données',
|
||||
'Class:TriggerOnObject+' => '',
|
||||
'Class:TriggerOnObject/Attribute:target_class' => 'Classe cible',
|
||||
'Class:TriggerOnObject/Attribute:target_class+' => 'label',
|
||||
'Class:TriggerOnStateChange' => 'Trigger on object state change',
|
||||
'Class:TriggerOnObject/Attribute:filter' => 'Filtre',
|
||||
'Class:TriggerOnObject/Attribute:filter+' => '',
|
||||
'TriggerOnObject:WrongFilterQuery' => 'Requête de filtrage incorrecte: %1$s',
|
||||
'TriggerOnObject:WrongFilterClass' => 'La requête de filtrage doit retourner des objets de la classe "%1$s"',
|
||||
'Class:TriggerOnStateChange' => 'Déclencheur sur changement d\'état',
|
||||
'Class:TriggerOnStateChange+' => '',
|
||||
'Class:TriggerOnStateChange/Attribute:state' => 'Etat',
|
||||
'Class:TriggerOnStateChange/Attribute:state+' => 'label',
|
||||
|
||||
@@ -158,6 +158,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:User/Attribute:allowed_org_list+' => 'L\'utilisateur a le droit de voir les données des organisations listées ici. Si aucune organisation n\'est spécifiée, alors aucune restriction ne s\'applique.',
|
||||
'Class:User/Error:LoginMustBeUnique' => 'Le login doit être unique - "%1s" est déjà utilisé.',
|
||||
'Class:User/Error:AtLeastOneProfileIsNeeded' => 'L\'utilisateur doit avoir au moins un profil.',
|
||||
'Class:UserInternal' => 'Utilisateur interne',
|
||||
'Class:UserInternal+' => 'Utilisateur défini dans iTop',
|
||||
'Class:URP_Dimensions' => 'Dimension',
|
||||
'Class:URP_Dimensions+' => 'Dimension applicative (défini des silos)',
|
||||
'Class:URP_Dimensions/Attribute:name' => 'Nom',
|
||||
@@ -449,7 +451,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'UI:CSVImport:HeaderFields' => 'Champs',
|
||||
'UI:CSVImport:HeaderMappings' => 'Correspondance',
|
||||
'UI:CSVImport:HeaderSearch' => 'Recherche ?',
|
||||
'UI:CSVImport:AlertIncompleteMapping' => 'Veuillez choisir le correspondance de chacun des champs.',
|
||||
'UI:CSVImport:AlertIncompleteMapping' => 'Veuillez choisir la correspondance pour chacun des champs.',
|
||||
'UI:CSVImport:AlertMultipleMapping' => 'Veuillez vous assurer que chaque champ cible est sélectionné une seule fois.',
|
||||
'UI:CSVImport:AlertNoSearchCriteria' => 'Veuillez choisir au moins une clef de recherche.',
|
||||
'UI:CSVImport:Encoding' => 'Encodage des caractères',
|
||||
|
||||
@@ -633,6 +636,9 @@ Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'UI:ObjectDoesNotExist' => 'Désolé cet objet n\'existe pas (où vous n\'êtes pas autorisé à l\'afficher).',
|
||||
'UI:SearchResultsPageTitle' => 'iTop - Résultats de la recherche',
|
||||
'UI:Search:NoSearch' => 'Rien à rechercher',
|
||||
'UI:Search:NeedleTooShort' => 'La clé de recherche "%1$s" est trop courte. Veuillez saisir au moins %2$d caractères.',
|
||||
'UI:Search:Ongoing' => 'Recherche de "%1$s"',
|
||||
'UI:Search:Enlarge' => 'Elargir la recherche',
|
||||
'UI:FullTextSearchTitle_Text' => 'Résultats pour "%1$s" :',
|
||||
'UI:Search:Count_ObjectsOf_Class_Found' => 'Trouvé %1$d objet(s) de type %2$s.',
|
||||
'UI:Search:NoObjectFound' => 'Aucun objet trouvé.',
|
||||
@@ -839,6 +845,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'Portal:AddAttachment' => ' Ajouter une pièce jointe ',
|
||||
'Portal:RemoveAttachment' => ' Enlever la pièce jointe ',
|
||||
'Portal:Attachment_No_To_Ticket_Name' => 'Pièce jointe #%1$d à %2$s (%3$s)',
|
||||
'Portal:SelectRequestTemplate' => 'Sélectionnez un modèle de requête pour %1$s',
|
||||
'Enum:Undefined' => 'Non défini',
|
||||
'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s J %2$s H %3$s min %4$s s',
|
||||
'UI:ModifyAllPageTitle' => 'Modification par lots',
|
||||
|
||||
@@ -816,6 +816,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Portal:AddAttachment' => ' 添付を追加 ',
|
||||
'Portal:RemoveAttachment' => ' 添付を削除 ',
|
||||
'Portal:Attachment_No_To_Ticket_Name' => '$2$s ($3$s)への添付 #%1$d',
|
||||
'Portal:SelectRequestTemplate' => 'Select a template for %1$s のテンプレートを選択',
|
||||
'Enum:Undefined' => '未定義',
|
||||
'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s 日 %2$s 時 %3$s 分 %4$s 秒',
|
||||
'UI:ModifyAllPageTitle' => '全てを修正',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -131,12 +131,12 @@ jQuery.extend(
|
||||
jQuery.handleError(s, xml, null, e);
|
||||
}
|
||||
|
||||
}, 100)
|
||||
}, 100);
|
||||
|
||||
xml = null
|
||||
xml = null;
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
// Timeout checker
|
||||
if ( s.timeout > 0 )
|
||||
{
|
||||
@@ -197,7 +197,9 @@ jQuery.extend({
|
||||
s.error( xhr, status, e );
|
||||
// If we have some XML response text (e.g. from an AJAX call) then log it in the console
|
||||
else if(xhr.responseText)
|
||||
console.log(xhr.responseText);
|
||||
{
|
||||
//console.log(xhr.responseText);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -546,6 +546,11 @@ function ExtKeyWidget(id, sTargetClass, sFilter, sTitle, bSelectMode, oWizHelper
|
||||
$('#'+me.id).trigger('extkeychange');
|
||||
$('#'+me.id).trigger('change');
|
||||
}
|
||||
if ( $('#'+me.id).hasClass('multiselect'))
|
||||
{
|
||||
$('#'+me.id+' option').each(function() { this.selected = ($(this).attr('value') == iObjectId); });
|
||||
$('#'+me.id).multiselect('refresh');
|
||||
}
|
||||
$('#label_'+me.id).focus();
|
||||
me.ajax_request = null;
|
||||
},
|
||||
|
||||
@@ -162,6 +162,10 @@ $(function()
|
||||
}
|
||||
this._refresh();
|
||||
},
|
||||
get_post_upload_to: function()
|
||||
{
|
||||
return this.options.post_upload_to;
|
||||
},
|
||||
_upload_dlg: function()
|
||||
{
|
||||
var me = this;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user