mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-19 02:14:10 +01:00
Compare commits
13 Commits
9010_Fix_f
...
feature/90
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13c8609508 | ||
|
|
ac8937105d | ||
|
|
fb6f892244 | ||
|
|
0a04c83c7b | ||
|
|
cc8252bebf | ||
|
|
3e879c64a7 | ||
|
|
5c6369b9b8 | ||
|
|
154fb5c737 | ||
|
|
efb1bd765b | ||
|
|
b39af74d07 | ||
|
|
904cd0b518 | ||
|
|
4c1ad0f4f2 | ||
|
|
3955b4eb22 |
16
.phpstorm.meta.php
Normal file
16
.phpstorm.meta.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace PHPSTORM_META
|
||||
{
|
||||
override(\MetaModel::NewObject(0), map([
|
||||
'' => '@',
|
||||
]));
|
||||
override(\MetaModel::GetObject(0), map([
|
||||
'' => '@',
|
||||
]));
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://www.combodo.com/itop-schema/3.3"
|
||||
version="3.3">
|
||||
<classes>
|
||||
<class id="AbstractResource" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
<properties>
|
||||
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generaly controlled using UR_ACTION_MODIFY access right. */</comment>
|
||||
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generally controlled using UR_ACTION_MODIFY access right. */</comment>
|
||||
<abstract>true</abstract>
|
||||
</properties>
|
||||
<presentation/>
|
||||
@@ -552,7 +554,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
<description><![CDATA[Inform the listeners about the connection states]]></description>
|
||||
<event_data>
|
||||
<event_datum id="code">
|
||||
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>
|
||||
<description>The login step result code (LoginWebPage::EXIT_CODE_...)</description>
|
||||
<type>integer</type>
|
||||
</event_datum>
|
||||
<event_datum id="state">
|
||||
@@ -849,5 +851,168 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
</methods>
|
||||
</class>
|
||||
</classes>
|
||||
<property_types _delta="define">
|
||||
<property_type id="Dashlet" xsi:type="Combodo-AbstractPropertyType"/>
|
||||
<property_type id="DashletGroupBy" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<label>UI:DashletGroupBy:Title</label>
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletGroupBy:Prop-Title</label>
|
||||
</node>
|
||||
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||
<label>UI:DashletGroupBy:Prop-Query</label>
|
||||
</node>
|
||||
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttributeGroupBy">
|
||||
<label>UI:DashletGroupBy:Prop-GroupBy</label>
|
||||
<class>{{query.selected_class}}</class>
|
||||
</node>
|
||||
<node id="style" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
|
||||
<label>UI:DashletGroupBy:Prop-Style</label>
|
||||
<values>
|
||||
<value id="bars">
|
||||
<label>UI:DashletGroupByBars:Label</label>
|
||||
</value>
|
||||
<value id="pie">
|
||||
<label>UI:DashletGroupByPie:Label</label>
|
||||
</value>
|
||||
<value id="table">
|
||||
<label>UI:DashletGroupByTable:Label</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="aggregation_function" xsi:type="Combodo-ValueType-AggregateFunction">
|
||||
<label>UI:DashletGroupBy:Prop-Function</label>
|
||||
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
|
||||
</node>
|
||||
<node id="aggregation_attribute" xsi:type="Combodo-ValueType-ClassAttribute">
|
||||
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
|
||||
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
|
||||
<class>{{query.selected_class}}</class>
|
||||
<category>numeric</category>
|
||||
</node>
|
||||
<node id="order_by" xsi:type="Combodo-ValueType-ChoiceFromInput">
|
||||
<label>UI:DashletGroupBy:Prop-OrderField</label>
|
||||
<values>
|
||||
<value id="attribute">
|
||||
<label>{{aggregation_attribute.label}}</label>
|
||||
</value>
|
||||
<value id="function">
|
||||
<label>{{aggregation_function.label}}</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="limit" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>UI:DashletGroupBy:Prop-Limit</label>
|
||||
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
|
||||
</node>
|
||||
<node id="order_direction" xsi:type="Combodo-ValueType-Choice">
|
||||
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
|
||||
<values>
|
||||
<value id="asc">
|
||||
<label>UI:DashletGroupBy:Order:asc</label>
|
||||
</value>
|
||||
<value id="desc">
|
||||
<label>UI:DashletGroupBy:Order:desc</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletBadge" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<nodes>
|
||||
<node id="class" xsi:type="Combodo-ValueType-Class">
|
||||
<label>UI:DashletBadge:Prop-Class</label>
|
||||
<categories-csv>bizmodel</categories-csv>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletHeaderDynamic" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<label>UI:DashletHeaderDynamic:Title</label>
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletHeaderDynamic:Prop-Title</label>
|
||||
</node>
|
||||
<node id="icon" xsi:type="Combodo-ValueType-Icon">
|
||||
<label>UI:DashletHeaderDynamic:Prop-Icon</label>
|
||||
</node>
|
||||
<node id="subtitle" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletHeaderDynamic:Prop-Subtitle</label>
|
||||
</node>
|
||||
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||
<label>UI:DashletHeaderDynamic:Prop-Query</label>
|
||||
</node>
|
||||
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttribute">
|
||||
<label>UI:DashletHeaderDynamic:Prop-GroupBy</label>
|
||||
<class>{{query.selected_class}}</class>
|
||||
<category>enum</category>
|
||||
</node>
|
||||
<node id="values" xsi:type="Combodo-ValueType-CollectionOfValues">
|
||||
<label>UI:DashletHeaderDynamic:Prop-Values</label>
|
||||
<xml-format xsi:type="Combodo-XMLFormat-CSV"/>
|
||||
<value-type xsi:type="Combodo-ValueType-ClassAttributeValue">
|
||||
<class>{{query.selected_class}}</class>
|
||||
<attribute>{{group_by.attribute}}</attribute>
|
||||
</value-type>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletHeaderStatic" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletHeaderStatic:Prop-Title</label>
|
||||
</node>
|
||||
<node id="icon" xsi:type="Combodo-ValueType-Icon">
|
||||
<label>UI:DashletHeaderStatic:Prop-Icon</label>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletObjectList" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletObjectList:Prop-Title</label>
|
||||
</node>
|
||||
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||
<label>UI:DashletObjectList:Prop-Query</label>
|
||||
</node>
|
||||
<node id="menu" xsi:type="Combodo-ValueType-Boolean">
|
||||
<label>UI:DashletObjectList:Prop-Menu</label>
|
||||
<on>
|
||||
<!-- not so cute, but matches exactly 3.2 implementation of boolean fields -->
|
||||
<label>UI:UserManagement:ActionAllowed:Yes</label>
|
||||
<value>true</value>
|
||||
</on>
|
||||
<off>
|
||||
<label>UI:UserManagement:ActionAllowed:No</label>
|
||||
<value>false</value>
|
||||
</off>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletPlainText" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<nodes>
|
||||
<node id="text" xsi:type="Combodo-ValueType-Text">
|
||||
<label>UI:DashletPlainText:Prop-Text</label>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
</property_types>
|
||||
</meta>
|
||||
</itop_design>
|
||||
|
||||
@@ -1900,6 +1900,12 @@ SQL;
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function QuoteForPHP(string $sValue): string
|
||||
{
|
||||
$sEscaped = str_replace(['\\', "'"], ['\\\\', "\\'"], $sValue);
|
||||
return "'$sEscaped'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a standard list of character sets
|
||||
*
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"symfony/mailer": "^6.4",
|
||||
"symfony/security-csrf": "^6.4",
|
||||
"symfony/twig-bundle": "~6.4.0",
|
||||
"symfony/validator" : "^6.4",
|
||||
"symfony/yaml": "~6.4.0",
|
||||
"tecnickcom/tcpdf": "^6.6.0",
|
||||
"thenetworg/oauth2-azure": "^2.0"
|
||||
|
||||
103
composer.lock
generated
103
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "26fa7aa920057d080bcc0948bf052fda",
|
||||
"content-hash" : "3e627286597661542dd598499c2bcc36",
|
||||
"packages": [
|
||||
{
|
||||
"name": "apereo/phpcas",
|
||||
@@ -4984,6 +4984,107 @@
|
||||
"time": "2025-07-10T08:14:14+00:00"
|
||||
},
|
||||
{
|
||||
"name" : "symfony/validator",
|
||||
"version" : "v6.4.29",
|
||||
"source" : {
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/symfony/validator.git",
|
||||
"reference" : "99df8a769e64e399f510166141ea74f450e8dd1d"
|
||||
},
|
||||
"dist" : {
|
||||
"type" : "zip",
|
||||
"url" : "https://api.github.com/repos/symfony/validator/zipball/99df8a769e64e399f510166141ea74f450e8dd1d",
|
||||
"reference" : "99df8a769e64e399f510166141ea74f450e8dd1d",
|
||||
"shasum" : ""
|
||||
},
|
||||
"require" : {
|
||||
"php" : ">=8.1",
|
||||
"symfony/deprecation-contracts" : "^2.5|^3",
|
||||
"symfony/polyfill-ctype" : "~1.8",
|
||||
"symfony/polyfill-mbstring" : "~1.0",
|
||||
"symfony/polyfill-php83" : "^1.27",
|
||||
"symfony/translation-contracts" : "^2.5|^3"
|
||||
},
|
||||
"conflict" : {
|
||||
"doctrine/annotations" : "<1.13",
|
||||
"doctrine/lexer" : "<1.1",
|
||||
"symfony/dependency-injection" : "<5.4",
|
||||
"symfony/expression-language" : "<5.4",
|
||||
"symfony/http-kernel" : "<5.4",
|
||||
"symfony/intl" : "<5.4",
|
||||
"symfony/property-info" : "<5.4",
|
||||
"symfony/translation" : "<5.4.35|>=6.0,<6.3.12|>=6.4,<6.4.3|>=7.0,<7.0.3",
|
||||
"symfony/yaml" : "<5.4"
|
||||
},
|
||||
"require-dev" : {
|
||||
"doctrine/annotations" : "^1.13|^2",
|
||||
"egulias/email-validator" : "^2.1.10|^3|^4",
|
||||
"symfony/cache" : "^5.4|^6.0|^7.0",
|
||||
"symfony/config" : "^5.4|^6.0|^7.0",
|
||||
"symfony/console" : "^5.4|^6.0|^7.0",
|
||||
"symfony/dependency-injection" : "^5.4|^6.0|^7.0",
|
||||
"symfony/expression-language" : "^5.4|^6.0|^7.0",
|
||||
"symfony/finder" : "^5.4|^6.0|^7.0",
|
||||
"symfony/http-client" : "^5.4|^6.0|^7.0",
|
||||
"symfony/http-foundation" : "^5.4|^6.0|^7.0",
|
||||
"symfony/http-kernel" : "^5.4|^6.0|^7.0",
|
||||
"symfony/intl" : "^5.4|^6.0|^7.0",
|
||||
"symfony/mime" : "^5.4|^6.0|^7.0",
|
||||
"symfony/property-access" : "^5.4|^6.0|^7.0",
|
||||
"symfony/property-info" : "^5.4|^6.0|^7.0",
|
||||
"symfony/translation" : "^5.4.35|~6.3.12|^6.4.3|^7.0.3",
|
||||
"symfony/yaml" : "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"type" : "library",
|
||||
"autoload" : {
|
||||
"psr-4" : {
|
||||
"Symfony\\Component\\Validator\\" : ""
|
||||
},
|
||||
"exclude-from-classmap" : [
|
||||
"/Tests/",
|
||||
"/Resources/bin/"
|
||||
]
|
||||
},
|
||||
"notification-url" : "https://packagist.org/downloads/",
|
||||
"license" : [
|
||||
"MIT"
|
||||
],
|
||||
"authors" : [
|
||||
{
|
||||
"name" : "Fabien Potencier",
|
||||
"email" : "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name" : "Symfony Community",
|
||||
"homepage" : "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description" : "Provides tools to validate values",
|
||||
"homepage" : "https://symfony.com",
|
||||
"support" : {
|
||||
"source" : "https://github.com/symfony/validator/tree/v6.4.29"
|
||||
},
|
||||
"funding" : [
|
||||
{
|
||||
"url" : "https://symfony.com/sponsor",
|
||||
"type" : "custom"
|
||||
},
|
||||
{
|
||||
"url" : "https://github.com/fabpot",
|
||||
"type" : "github"
|
||||
},
|
||||
{
|
||||
"url" : "https://github.com/nicolas-grekas",
|
||||
"type" : "github"
|
||||
},
|
||||
{
|
||||
"url" : "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type" : "tidelift"
|
||||
}
|
||||
],
|
||||
"time" : "2025-11-06T20:26:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v6.4.26",
|
||||
"source": {
|
||||
|
||||
@@ -41,7 +41,7 @@ use utils;
|
||||
/**
|
||||
* Class \Combodo\iTop\DesignDocument
|
||||
*
|
||||
* A design document is the DOM tree that modelize behaviors. One of its
|
||||
* A design document is the DOM tree that models behaviors. One of its
|
||||
* characteristics is that it can be altered by the mean of the same kind of document.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -691,6 +691,28 @@ abstract class LogAPI
|
||||
static::$m_oMockMetaModelConfig = $oMetaModelConfig;
|
||||
}
|
||||
|
||||
public static function Exception(string $sMessage, throwable $oException, string $sChannel = null, array $aContext = []): void
|
||||
{
|
||||
$aErrorLogs = [];
|
||||
$aErrorLogs[] = static::PrepareErrorLog($sMessage, $oException, $aContext);
|
||||
$oException = $oException->getPrevious();
|
||||
while ($oException !== null) {
|
||||
$aErrorLogs[] = static::PrepareErrorLog($oException->getMessage(), $oException, $aContext, true);
|
||||
$oException = $oException->getPrevious();
|
||||
}
|
||||
$aErrorLogs = array_reverse($aErrorLogs);
|
||||
foreach ($aErrorLogs as $aErrorLog) {
|
||||
static::Error($aErrorLog['message'], $sChannel, $aErrorLog['context']);
|
||||
}
|
||||
}
|
||||
|
||||
private static function PrepareErrorLog(string $sMessage, throwable $oException, array $aContext, bool $isPrevious = false): array
|
||||
{
|
||||
$aContext['Error Message'] = $oException->getMessage();
|
||||
$aContext['Stack Trace'] = $oException->getTraceAsString();
|
||||
return ['message' => ($isPrevious ? "Previous " : '')."Exception: $sMessage", 'context' => $aContext];
|
||||
}
|
||||
|
||||
public static function Error($sMessage, $sChannel = null, $aContext = [])
|
||||
{
|
||||
static::Log(self::LEVEL_ERROR, $sMessage, $sChannel, $aContext);
|
||||
|
||||
@@ -55,6 +55,11 @@ abstract class ModelReflection
|
||||
abstract public function GetFiltersList($sClass);
|
||||
abstract public function IsValidFilterCode($sClass, $sFilterCode);
|
||||
|
||||
/**
|
||||
* @since 3.3.0
|
||||
*/
|
||||
abstract public function IsAbstract($sClass): bool;
|
||||
|
||||
/**
|
||||
* @param string $sOQL
|
||||
*
|
||||
@@ -148,7 +153,7 @@ class ModelReflectionRuntime extends ModelReflection
|
||||
$sAttributeClass = get_class($oAttDef);
|
||||
if ($aScope != null) {
|
||||
foreach ($aScope as $sScopeClass) {
|
||||
if (($sAttributeClass == $sScopeClass) || is_subclass_of($sAttributeClass, $sScopeClass)) {
|
||||
if (is_a($sAttributeClass, $sScopeClass, true)) {
|
||||
$aAttributes[$sAttCode] = $sAttributeClass;
|
||||
break;
|
||||
}
|
||||
@@ -230,6 +235,11 @@ class ModelReflectionRuntime extends ModelReflection
|
||||
return MetaModel::IsValidFilterCode($sClass, $sFilterCode);
|
||||
}
|
||||
|
||||
public function IsAbstract($sClass): bool
|
||||
{
|
||||
return MetaModel::IsAbstract($sClass);
|
||||
}
|
||||
|
||||
public function GetQuery($sOQL)
|
||||
{
|
||||
return new QueryReflectionRuntime($sOQL, $this);
|
||||
|
||||
@@ -2103,12 +2103,18 @@ class VariableExpression extends UnaryExpression
|
||||
|
||||
/**
|
||||
* Evaluate the value of the expression
|
||||
*
|
||||
* @param array $aArgs
|
||||
* @throws \Exception if terms cannot be evaluated as scalars
|
||||
*/
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \MissingQueryArgument
|
||||
*/
|
||||
public function Evaluate(array $aArgs)
|
||||
{
|
||||
throw new Exception('not implemented yet');
|
||||
if (!isset($aArgs[$this->m_sName])) {
|
||||
throw new MissingQueryArgument('Missing variable expression argument', array('expecting'=>$this->m_sName));
|
||||
}
|
||||
return $aArgs[$this->m_sName];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -72,9 +72,15 @@ class OQLException extends CoreException
|
||||
}
|
||||
else
|
||||
{
|
||||
$sExpectations = '{'.implode(', ', $this->m_aExpecting).'}';
|
||||
$sMessage = "$sIssue - found '{$this->m_sUnexpected}' at $iCol in '$sInput'";
|
||||
if (count($this->m_aExpecting) < 30) {
|
||||
$sExpectations = '{'.implode(', ', $this->m_aExpecting).'}';
|
||||
$sMessage .= ', expecting '.json_encode($sExpectations);
|
||||
}
|
||||
$sSuggest = self::FindClosestString($this->m_sUnexpected, $this->m_aExpecting);
|
||||
$sMessage = "$sIssue - found '{$this->m_sUnexpected}' at $iCol in '$sInput', expecting $sExpectations, I would suggest to use '$sSuggest'";
|
||||
if (strlen($sSuggest) > 0) {
|
||||
$sMessage .= ", I would suggest to use ".json_encode($sSuggest);
|
||||
}
|
||||
}
|
||||
|
||||
// make sure everything is assigned properly
|
||||
@@ -155,5 +161,3 @@ class OQLException extends CoreException
|
||||
return $sRet;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -57,15 +57,15 @@ class OqlName
|
||||
{
|
||||
return $this->m_iPos;
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->m_sValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Store hexadecimal values as strings so that we can support 64-bit values
|
||||
*
|
||||
*/
|
||||
@@ -77,12 +77,12 @@ class OqlHexValue
|
||||
{
|
||||
$this->m_sValue = $sValue;
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->m_sValue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class OqlJoinSpec
|
||||
@@ -109,6 +109,7 @@ class OqlJoinSpec
|
||||
{
|
||||
return $this->m_oClass->GetValue();
|
||||
}
|
||||
|
||||
public function GetClassAlias()
|
||||
{
|
||||
return $this->m_oClassAlias->GetValue();
|
||||
@@ -118,6 +119,7 @@ class OqlJoinSpec
|
||||
{
|
||||
return $this->m_oClass;
|
||||
}
|
||||
|
||||
public function GetClassAliasDetails()
|
||||
{
|
||||
return $this->m_oClassAlias;
|
||||
@@ -127,10 +129,12 @@ class OqlJoinSpec
|
||||
{
|
||||
return $this->m_oLeftField;
|
||||
}
|
||||
|
||||
public function GetRightField()
|
||||
{
|
||||
return $this->m_oRightField;
|
||||
}
|
||||
|
||||
public function GetOperator()
|
||||
{
|
||||
return $this->m_sOperator;
|
||||
@@ -146,8 +150,9 @@ interface CheckableExpression
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
* @param array $aAliases Aliases to class names (for the current query)
|
||||
* @param string $sSourceQuery For the reporting
|
||||
*
|
||||
* @throws OqlNormalizeException
|
||||
*/
|
||||
*/
|
||||
public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuery);
|
||||
}
|
||||
|
||||
@@ -168,13 +173,11 @@ class MatchOqlExpression extends MatchExpression implements CheckableExpression
|
||||
$this->m_oRightExpr->Check($oModelReflection, $aAliases, $sSourceQuery);
|
||||
|
||||
// Only field MATCHES scalar is allowed
|
||||
if (!$this->m_oLeftExpr instanceof FieldExpression)
|
||||
{
|
||||
if (!$this->m_oLeftExpr instanceof FieldExpression) {
|
||||
throw new OqlNormalizeException('Only "field MATCHES string" syntax is allowed', $sSourceQuery, new OqlName($this->m_oLeftExpr->RenderExpression(true), 0));
|
||||
}
|
||||
// Only field MATCHES scalar is allowed
|
||||
if (!$this->m_oRightExpr instanceof ScalarExpression && !$this->m_oRightExpr instanceof VariableOqlExpression)
|
||||
{
|
||||
if (!$this->m_oRightExpr instanceof ScalarExpression && !$this->m_oRightExpr instanceof VariableOqlExpression) {
|
||||
throw new OqlNormalizeException('Only "field MATCHES string" syntax is allowed', $sSourceQuery, new OqlName($this->m_oRightExpr->RenderExpression(true), 0));
|
||||
}
|
||||
}
|
||||
@@ -198,7 +201,7 @@ class NestedQueryOqlExpression extends NestedQueryExpression implements Checkabl
|
||||
*
|
||||
* @param OQLObjectQuery $oOQLObjectQuery
|
||||
*/
|
||||
public function __construct($oOQLObjectQuery )
|
||||
public function __construct($oOQLObjectQuery)
|
||||
{
|
||||
parent::__construct($oOQLObjectQuery->ToDBSearch(""));
|
||||
$this->m_oOQLObjectQuery = $oOQLObjectQuery;
|
||||
@@ -232,8 +235,7 @@ class FieldOqlExpression extends FieldExpression implements CheckableExpression
|
||||
|
||||
public function __construct($oName, $oParent = null)
|
||||
{
|
||||
if (is_null($oParent))
|
||||
{
|
||||
if (is_null($oParent)) {
|
||||
$oParent = new OqlName('', 0);
|
||||
}
|
||||
$this->m_oParent = $oParent;
|
||||
@@ -256,37 +258,28 @@ class FieldOqlExpression extends FieldExpression implements CheckableExpression
|
||||
{
|
||||
$sClassAlias = $this->GetParent();
|
||||
$sFltCode = $this->GetName();
|
||||
if (empty($sClassAlias))
|
||||
{
|
||||
if (empty($sClassAlias)) {
|
||||
// Try to find an alias
|
||||
// Build an array of field => array of aliases
|
||||
$aFieldClasses = array();
|
||||
foreach($aAliases as $sAlias => $sReal)
|
||||
{
|
||||
foreach($oModelReflection->GetFiltersList($sReal) as $sAnFltCode)
|
||||
{
|
||||
foreach ($aAliases as $sAlias => $sReal) {
|
||||
foreach ($oModelReflection->GetFiltersList($sReal) as $sAnFltCode) {
|
||||
$aFieldClasses[$sAnFltCode][] = $sAlias;
|
||||
}
|
||||
}
|
||||
if (!array_key_exists($sFltCode, $aFieldClasses))
|
||||
{
|
||||
if (!array_key_exists($sFltCode, $aFieldClasses)) {
|
||||
throw new OqlNormalizeException('Unknown filter code', $sSourceQuery, $this->GetNameDetails(), array_keys($aFieldClasses));
|
||||
}
|
||||
if (count($aFieldClasses[$sFltCode]) > 1)
|
||||
{
|
||||
if (count($aFieldClasses[$sFltCode]) > 1) {
|
||||
throw new OqlNormalizeException('Ambiguous filter code', $sSourceQuery, $this->GetNameDetails());
|
||||
}
|
||||
$sClassAlias = $aFieldClasses[$sFltCode][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!array_key_exists($sClassAlias, $aAliases))
|
||||
{
|
||||
} else {
|
||||
if (!array_key_exists($sClassAlias, $aAliases)) {
|
||||
throw new OqlNormalizeException('Unknown class [alias]', $sSourceQuery, $this->GetParentDetails(), array_keys($aAliases));
|
||||
}
|
||||
$sClass = $aAliases[$sClassAlias];
|
||||
if (!$oModelReflection->IsValidFilterCode($sClass, $sFltCode))
|
||||
{
|
||||
if (!$oModelReflection->IsValidFilterCode($sClass, $sFltCode)) {
|
||||
throw new OqlNormalizeException('Unknown filter code', $sSourceQuery, $this->GetNameDetails(), $oModelReflection->GetFiltersList($sClass));
|
||||
}
|
||||
}
|
||||
@@ -305,8 +298,7 @@ class ListOqlExpression extends ListExpression implements CheckableExpression
|
||||
{
|
||||
public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuery)
|
||||
{
|
||||
foreach ($this->GetItems() as $oItemExpression)
|
||||
{
|
||||
foreach ($this->GetItems() as $oItemExpression) {
|
||||
$oItemExpression->Check($oModelReflection, $aAliases, $sSourceQuery);
|
||||
}
|
||||
}
|
||||
@@ -316,8 +308,7 @@ class FunctionOqlExpression extends FunctionExpression implements CheckableExpre
|
||||
{
|
||||
public function Check(ModelReflection $oModelReflection, $aAliases, $sSourceQuery)
|
||||
{
|
||||
foreach ($this->GetArgs() as $oArgExpression)
|
||||
{
|
||||
foreach ($this->GetArgs() as $oArgExpression) {
|
||||
$oArgExpression->Check($oModelReflection, $aAliases, $sSourceQuery);
|
||||
}
|
||||
}
|
||||
@@ -350,6 +341,7 @@ abstract class OqlQuery
|
||||
* Determine the class
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -392,6 +384,7 @@ class OqlObjectQuery extends OqlQuery
|
||||
* Determine the class
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -415,6 +408,7 @@ class OqlObjectQuery extends OqlQuery
|
||||
{
|
||||
return $this->m_oClass;
|
||||
}
|
||||
|
||||
public function GetClassAliasDetails()
|
||||
{
|
||||
return $this->m_oClassAlias;
|
||||
@@ -424,6 +418,7 @@ class OqlObjectQuery extends OqlQuery
|
||||
{
|
||||
return $this->m_aJoins;
|
||||
}
|
||||
|
||||
public function GetCondition()
|
||||
{
|
||||
return $this->m_oCondition;
|
||||
@@ -432,44 +427,37 @@ class OqlObjectQuery extends OqlQuery
|
||||
/**
|
||||
* Recursively check the validity of the expression with regard to the data model
|
||||
* and the query in which it is used
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @throws OqlNormalizeException
|
||||
*/
|
||||
*/
|
||||
public function Check(ModelReflection $oModelReflection, $sSourceQuery, $aParentAliases = array())
|
||||
{
|
||||
$sClass = $this->GetClass($oModelReflection);
|
||||
$sClassAlias = $this->GetClassAlias();
|
||||
|
||||
if (!$oModelReflection->IsValidClass($sClass))
|
||||
{
|
||||
if (!$oModelReflection->IsValidClass($sClass)) {
|
||||
throw new UnknownClassOqlException($sSourceQuery, $this->GetClassDetails(), $oModelReflection->GetClasses());
|
||||
}
|
||||
|
||||
$aAliases = array_merge(array($sClassAlias => $sClass),$aParentAliases);
|
||||
$aAliases = array_merge(array($sClassAlias => $sClass), $aParentAliases);
|
||||
|
||||
$aJoinSpecs = $this->GetJoins();
|
||||
if (is_array($aJoinSpecs))
|
||||
{
|
||||
foreach ($aJoinSpecs as $oJoinSpec)
|
||||
{
|
||||
if (is_array($aJoinSpecs)) {
|
||||
foreach ($aJoinSpecs as $oJoinSpec) {
|
||||
$sJoinClass = $oJoinSpec->GetClass();
|
||||
$sJoinClassAlias = $oJoinSpec->GetClassAlias();
|
||||
if (!$oModelReflection->IsValidClass($sJoinClass))
|
||||
{
|
||||
if (!$oModelReflection->IsValidClass($sJoinClass)) {
|
||||
throw new UnknownClassOqlException($sSourceQuery, $oJoinSpec->GetClassDetails(), $oModelReflection->GetClasses());
|
||||
}
|
||||
if (array_key_exists($sJoinClassAlias, $aAliases))
|
||||
{
|
||||
if ($sJoinClassAlias != $sJoinClass)
|
||||
{
|
||||
if (array_key_exists($sJoinClassAlias, $aAliases)) {
|
||||
if ($sJoinClassAlias != $sJoinClass) {
|
||||
throw new OqlNormalizeException('Duplicate class alias', $sSourceQuery, $oJoinSpec->GetClassAliasDetails());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
throw new OqlNormalizeException('Duplicate class name', $sSourceQuery, $oJoinSpec->GetClassDetails());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assumption: ext key on the left only !!!
|
||||
// normalization should take care of this
|
||||
@@ -480,85 +468,74 @@ class OqlObjectQuery extends OqlQuery
|
||||
$oRightField = $oJoinSpec->GetRightField();
|
||||
$sToClass = $oRightField->GetParent();
|
||||
$sPKeyDescriptor = $oRightField->GetName();
|
||||
if ($sPKeyDescriptor != 'id')
|
||||
{
|
||||
if ($sPKeyDescriptor != 'id') {
|
||||
throw new OqlNormalizeException('Wrong format for Join clause (right hand), expecting an id', $sSourceQuery, $oRightField->GetNameDetails(), array('id'));
|
||||
}
|
||||
|
||||
$aAliases[$sJoinClassAlias] = $sJoinClass;
|
||||
|
||||
if (!array_key_exists($sFromClass, $aAliases))
|
||||
{
|
||||
if (!array_key_exists($sFromClass, $aAliases)) {
|
||||
throw new OqlNormalizeException('Unknown class in join condition (left expression)', $sSourceQuery, $oLeftField->GetParentDetails(), array_keys($aAliases));
|
||||
}
|
||||
if (!array_key_exists($sToClass, $aAliases))
|
||||
{
|
||||
if (!array_key_exists($sToClass, $aAliases)) {
|
||||
throw new OqlNormalizeException('Unknown class in join condition (right expression)', $sSourceQuery, $oRightField->GetParentDetails(), array_keys($aAliases));
|
||||
}
|
||||
$aExtKeys = $oModelReflection->ListAttributes($aAliases[$sFromClass], \Combodo\iTop\Core\AttributeDefinition\AttributeExternalKey::class);
|
||||
$aObjKeys = $oModelReflection->ListAttributes($aAliases[$sFromClass], \Combodo\iTop\Core\AttributeDefinition\AttributeObjectKey::class);
|
||||
$aAllKeys = array_merge($aExtKeys, $aObjKeys);
|
||||
if (!array_key_exists($sExtKeyAttCode, $aAllKeys))
|
||||
{
|
||||
if (!array_key_exists($sExtKeyAttCode, $aAllKeys)) {
|
||||
throw new OqlNormalizeException('Unknown key in join condition (left expression)', $sSourceQuery, $oLeftField->GetNameDetails(), array_keys($aAllKeys));
|
||||
}
|
||||
|
||||
if ($sFromClass == $sJoinClassAlias)
|
||||
{
|
||||
if ($sFromClass == $sJoinClassAlias) {
|
||||
if (array_key_exists($sExtKeyAttCode, $aExtKeys)) // Skip that check for object keys
|
||||
{
|
||||
$sTargetClass = $oModelReflection->GetAttributeProperty($aAliases[$sFromClass], $sExtKeyAttCode, 'targetclass');
|
||||
if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass))
|
||||
{
|
||||
if (!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass)) {
|
||||
throw new OqlNormalizeException("The joined class ($aAliases[$sFromClass]) is not compatible with the external key, which is pointing to $sTargetClass", $sSourceQuery, $oLeftField->GetNameDetails());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sOperator = $oJoinSpec->GetOperator();
|
||||
switch($sOperator)
|
||||
{
|
||||
switch ($sOperator) {
|
||||
case '=':
|
||||
$iOperatorCode = TREE_OPERATOR_EQUALS;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_EQUALS;
|
||||
break;
|
||||
case 'BELOW':
|
||||
$iOperatorCode = TREE_OPERATOR_BELOW;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_BELOW;
|
||||
break;
|
||||
case 'BELOW_STRICT':
|
||||
$iOperatorCode = TREE_OPERATOR_BELOW_STRICT;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_BELOW_STRICT;
|
||||
break;
|
||||
case 'NOT_BELOW':
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_BELOW;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_BELOW;
|
||||
break;
|
||||
case 'NOT_BELOW_STRICT':
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_BELOW_STRICT;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_BELOW_STRICT;
|
||||
break;
|
||||
case 'ABOVE':
|
||||
$iOperatorCode = TREE_OPERATOR_ABOVE;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_ABOVE;
|
||||
break;
|
||||
case 'ABOVE_STRICT':
|
||||
$iOperatorCode = TREE_OPERATOR_ABOVE_STRICT;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_ABOVE_STRICT;
|
||||
break;
|
||||
case 'NOT_ABOVE':
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_ABOVE;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_ABOVE;
|
||||
break;
|
||||
case 'NOT_ABOVE_STRICT':
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_ABOVE_STRICT;
|
||||
break;
|
||||
$iOperatorCode = TREE_OPERATOR_NOT_ABOVE_STRICT;
|
||||
break;
|
||||
}
|
||||
if (array_key_exists($sExtKeyAttCode, $aExtKeys)) // Skip that check for object keys
|
||||
{
|
||||
$sTargetClass = $oModelReflection->GetAttributeProperty($aAliases[$sFromClass], $sExtKeyAttCode, 'targetclass');
|
||||
if(!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass))
|
||||
{
|
||||
if (!$oModelReflection->IsSameFamilyBranch($aAliases[$sToClass], $sTargetClass)) {
|
||||
throw new OqlNormalizeException("The joined class ($aAliases[$sToClass]) is not compatible with the external key, which is pointing to $sTargetClass", $sSourceQuery, $oLeftField->GetNameDetails());
|
||||
}
|
||||
}
|
||||
$aAttList = $oModelReflection->ListAttributes($aAliases[$sFromClass]);
|
||||
$sAttType = $aAttList[$sExtKeyAttCode];
|
||||
if(($iOperatorCode != TREE_OPERATOR_EQUALS) && !is_subclass_of($sAttType, \Combodo\iTop\Core\AttributeDefinition\AttributeHierarchicalKey::class) && ($sAttType != \Combodo\iTop\Core\AttributeDefinition\AttributeHierarchicalKey::class))
|
||||
{
|
||||
if (($iOperatorCode != TREE_OPERATOR_EQUALS) && !is_a($sAttType, \Combodo\iTop\Core\AttributeDefinition\AttributeHierarchicalKey::class, true)) {
|
||||
throw new OqlNormalizeException("The specified tree operator $sOperator is not applicable to the key", $sSourceQuery, $oLeftField->GetNameDetails());
|
||||
}
|
||||
}
|
||||
@@ -567,26 +544,23 @@ class OqlObjectQuery extends OqlQuery
|
||||
|
||||
// Check the select information
|
||||
//
|
||||
foreach ($this->GetSelectedClasses() as $oClassDetails)
|
||||
{
|
||||
foreach ($this->GetSelectedClasses() as $oClassDetails) {
|
||||
$sClassToSelect = $oClassDetails->GetValue();
|
||||
if (!array_key_exists($sClassToSelect, $aAliases))
|
||||
{
|
||||
if (!array_key_exists($sClassToSelect, $aAliases)) {
|
||||
throw new OqlNormalizeException('Unknown class [alias]', $sSourceQuery, $oClassDetails, array_keys($aAliases));
|
||||
}
|
||||
}
|
||||
|
||||
// Check the condition tree
|
||||
//
|
||||
if ($this->m_oCondition instanceof Expression)
|
||||
{
|
||||
if ($this->m_oCondition instanceof Expression) {
|
||||
$this->m_oCondition->Check($oModelReflection, $aAliases, $sSourceQuery);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the relevant DBSearch instance (FromOQL)
|
||||
*/
|
||||
*/
|
||||
public function ToDBSearch($sQuery)
|
||||
{
|
||||
$sClass = $this->GetClass(new ModelReflectionRuntime());
|
||||
@@ -594,6 +568,7 @@ class OqlObjectQuery extends OqlQuery
|
||||
|
||||
$oSearch = new DBObjectSearch($sClass, $sClassAlias);
|
||||
$oSearch->InitFromOqlQuery($this, $sQuery);
|
||||
|
||||
return $oSearch;
|
||||
}
|
||||
}
|
||||
@@ -606,19 +581,15 @@ class OqlUnionQuery extends OqlQuery
|
||||
{
|
||||
parent::__construct();
|
||||
$this->aQueries[] = $oLeftQuery;
|
||||
if ($oRightQueryOrUnion instanceof OqlUnionQuery)
|
||||
{
|
||||
foreach ($oRightQueryOrUnion->GetQueries() as $oSingleQuery)
|
||||
{
|
||||
if ($oRightQueryOrUnion instanceof OqlUnionQuery) {
|
||||
foreach ($oRightQueryOrUnion->GetQueries() as $oSingleQuery) {
|
||||
$this->aQueries[] = $oSingleQuery;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$this->aQueries[] = $oRightQueryOrUnion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function GetQueries()
|
||||
{
|
||||
return $this->aQueries;
|
||||
@@ -627,66 +598,54 @@ class OqlUnionQuery extends OqlQuery
|
||||
/**
|
||||
* Check the validity of the expression with regard to the data model
|
||||
* and the query in which it is used
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @throws OqlNormalizeException
|
||||
*/
|
||||
*/
|
||||
public function Check(ModelReflection $oModelReflection, $sSourceQuery)
|
||||
{
|
||||
$aColumnToClasses = array();
|
||||
foreach ($this->aQueries as $iQuery => $oQuery)
|
||||
{
|
||||
foreach ($this->aQueries as $iQuery => $oQuery) {
|
||||
$oQuery->Check($oModelReflection, $sSourceQuery);
|
||||
|
||||
$aAliasToClass = array($oQuery->GetClassAlias() => $oQuery->GetClass($oModelReflection));
|
||||
$aJoinSpecs = $oQuery->GetJoins();
|
||||
if (is_array($aJoinSpecs))
|
||||
{
|
||||
foreach ($aJoinSpecs as $oJoinSpec)
|
||||
{
|
||||
if (is_array($aJoinSpecs)) {
|
||||
foreach ($aJoinSpecs as $oJoinSpec) {
|
||||
$aAliasToClass[$oJoinSpec->GetClassAlias()] = $oJoinSpec->GetClass();
|
||||
}
|
||||
}
|
||||
|
||||
$aSelectedClasses = $oQuery->GetSelectedClasses();
|
||||
if ($iQuery != 0)
|
||||
{
|
||||
if (count($aSelectedClasses) < count($aColumnToClasses))
|
||||
{
|
||||
if ($iQuery != 0) {
|
||||
if (count($aSelectedClasses) < count($aColumnToClasses)) {
|
||||
$oLastClass = end($aSelectedClasses);
|
||||
throw new OqlNormalizeException('Too few selected classes in the subquery', $sSourceQuery, $oLastClass);
|
||||
}
|
||||
if (count($aSelectedClasses) > count($aColumnToClasses))
|
||||
{
|
||||
if (count($aSelectedClasses) > count($aColumnToClasses)) {
|
||||
$oLastClass = end($aSelectedClasses);
|
||||
throw new OqlNormalizeException('Too many selected classes in the subquery', $sSourceQuery, $oLastClass);
|
||||
}
|
||||
}
|
||||
foreach ($aSelectedClasses as $iColumn => $oClassDetails)
|
||||
{
|
||||
foreach ($aSelectedClasses as $iColumn => $oClassDetails) {
|
||||
$sAlias = $oClassDetails->GetValue();
|
||||
$sClass = $aAliasToClass[$sAlias];
|
||||
$aColumnToClasses[$iColumn][] = array(
|
||||
'alias' => $sAlias,
|
||||
'class' => $sClass,
|
||||
'alias' => $sAlias,
|
||||
'class' => $sClass,
|
||||
'class_name' => $oClassDetails,
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach ($aColumnToClasses as $iColumn => $aClasses)
|
||||
{
|
||||
foreach ($aColumnToClasses as $iColumn => $aClasses) {
|
||||
$sRootClass = null;
|
||||
foreach ($aClasses as $iQuery => $aData)
|
||||
{
|
||||
if ($iQuery == 0)
|
||||
{
|
||||
foreach ($aClasses as $iQuery => $aData) {
|
||||
if ($iQuery == 0) {
|
||||
// Establish the reference
|
||||
$sRootClass = $oModelReflection->GetRootClass($aData['class']);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($oModelReflection->GetRootClass($aData['class']) != $sRootClass)
|
||||
{
|
||||
} else {
|
||||
if ($oModelReflection->GetRootClass($aData['class']) != $sRootClass) {
|
||||
$aSubclasses = $oModelReflection->EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_ALL);
|
||||
throw new OqlNormalizeException('Incompatible classes: could not find a common ancestor', $sSourceQuery, $aData['class_name'], $aSubclasses);
|
||||
}
|
||||
@@ -699,21 +658,21 @@ class OqlUnionQuery extends OqlQuery
|
||||
* Determine the class
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetClass(ModelReflection $oModelReflection)
|
||||
{
|
||||
$aFirstColClasses = array();
|
||||
foreach ($this->aQueries as $iQuery => $oQuery)
|
||||
{
|
||||
foreach ($this->aQueries as $iQuery => $oQuery) {
|
||||
$aFirstColClasses[] = $oQuery->GetClass($oModelReflection);
|
||||
}
|
||||
$sClass = self::GetLowestCommonAncestor($oModelReflection, $aFirstColClasses);
|
||||
if (is_null($sClass))
|
||||
{
|
||||
if (is_null($sClass)) {
|
||||
throw new Exception('Could not determine the class of the union query. This issue should have been detected earlier by calling OqlQuery::Check()');
|
||||
}
|
||||
|
||||
return $sClass;
|
||||
}
|
||||
|
||||
@@ -726,6 +685,7 @@ class OqlUnionQuery extends OqlQuery
|
||||
public function GetClassAlias()
|
||||
{
|
||||
$sAlias = $this->aQueries[0]->GetClassAlias();
|
||||
|
||||
return $sAlias;
|
||||
}
|
||||
|
||||
@@ -735,29 +695,25 @@ class OqlUnionQuery extends OqlQuery
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
* @param array $aClasses Flat list of classes
|
||||
*
|
||||
* @return string the lowest common ancestor amongst classes, null if none has been found
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function GetLowestCommonAncestor(ModelReflection $oModelReflection, $aClasses)
|
||||
{
|
||||
$sAncestor = null;
|
||||
foreach($aClasses as $sClass)
|
||||
{
|
||||
if (is_null($sAncestor))
|
||||
{
|
||||
foreach ($aClasses as $sClass) {
|
||||
if (is_null($sAncestor)) {
|
||||
// first loop
|
||||
$sAncestor = $sClass;
|
||||
}
|
||||
elseif ($oModelReflection->GetRootClass($sClass) != $oModelReflection->GetRootClass($sAncestor))
|
||||
{
|
||||
} elseif ($oModelReflection->GetRootClass($sClass) != $oModelReflection->GetRootClass($sAncestor)) {
|
||||
$sAncestor = null;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$sAncestor = self::LowestCommonAncestor($oModelReflection, $sAncestor, $sClass);
|
||||
}
|
||||
}
|
||||
|
||||
return $sAncestor;
|
||||
}
|
||||
|
||||
@@ -766,37 +722,32 @@ class OqlUnionQuery extends OqlQuery
|
||||
*/
|
||||
protected static function LowestCommonAncestor(ModelReflection $oModelReflection, $sClassA, $sClassB)
|
||||
{
|
||||
if ($sClassA == $sClassB)
|
||||
{
|
||||
if ($sClassA == $sClassB) {
|
||||
$sRet = $sClassA;
|
||||
}
|
||||
elseif (in_array($sClassA, $oModelReflection->EnumChildClasses($sClassB)))
|
||||
{
|
||||
} elseif (in_array($sClassA, $oModelReflection->EnumChildClasses($sClassB))) {
|
||||
$sRet = $sClassB;
|
||||
}
|
||||
elseif (in_array($sClassB, $oModelReflection->EnumChildClasses($sClassA)))
|
||||
{
|
||||
} elseif (in_array($sClassB, $oModelReflection->EnumChildClasses($sClassA))) {
|
||||
$sRet = $sClassA;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Recurse
|
||||
$sRet = self::LowestCommonAncestor($oModelReflection, $sClassA, $oModelReflection->GetParentClass($sClassB));
|
||||
}
|
||||
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the relevant DBSearch instance (FromOQL)
|
||||
*/
|
||||
*/
|
||||
public function ToDBSearch($sQuery)
|
||||
{
|
||||
$aSearches = array();
|
||||
foreach ($this->aQueries as $oQuery)
|
||||
{
|
||||
foreach ($this->aQueries as $oQuery) {
|
||||
$aSearches[] = $oQuery->ToDBSearch($sQuery);
|
||||
}
|
||||
|
||||
$oSearch = new DBUnionSearch($aSearches);
|
||||
|
||||
return $oSearch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,12 +415,7 @@ abstract class User extends cmdbAbstractObject
|
||||
$this->m_aCheckIssues[] = Dict::S('Class:User/Error:CurrentProfilesHaveInsufficientRights');
|
||||
}
|
||||
$oAddon->ResetCache();
|
||||
|
||||
if (is_null($aCurrentProfiles)) {
|
||||
Session::IsSet('profile_list');
|
||||
} else {
|
||||
Session::Set('profile_list', $aCurrentProfiles);
|
||||
}
|
||||
Session::Set('profile_list', $aCurrentProfiles);
|
||||
}
|
||||
// Prevent an administrator to remove their own admin profile
|
||||
if (UserRights::IsAdministrator($this)) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
$ibo-field--spacing-top--with-same-block: $ibo-spacing-500 !default;
|
||||
|
||||
.ibo-field + .ibo-field {
|
||||
.ibo-field + .ibo-field:not(:empty) {
|
||||
margin-top: $ibo-field--spacing-top--with-same-block;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,4 +6,72 @@
|
||||
.ibo-prop-header {
|
||||
@extend %ibo-font-size-150;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.help-text{
|
||||
padding: 1px 5px;
|
||||
background-color: #d7e3f8;
|
||||
border: 1px solid #c6e7f5;
|
||||
border-radius: 5px;
|
||||
margin: 5px 0;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.form-error ul{
|
||||
padding: 1px 5px;
|
||||
background-color: #f8d7da;
|
||||
border: 1px solid #f5c6cb;
|
||||
border-radius: 5px;
|
||||
margin: 5px 0;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.subform{
|
||||
background-color: #efefef;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.form-buttons{
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.form select{
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.form select option{
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.turbo-refreshing{
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.ibo-field legend{
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
collection-entry-element {
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
padding: 10px 10px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.ts-control{
|
||||
height: auto;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.ibo-form-actions > .ibo-button > span{
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.ibo-form textarea{
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
|
||||
3
css/backoffice/vendors/_tomselect.scss
vendored
Normal file
3
css/backoffice/vendors/_tomselect.scss
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
@import "../../../node_modules/tom-select/dist/scss/tom-select.scss";
|
||||
|
||||
$select-color-item-active-border: $ibo-input--focus--border-color;
|
||||
0
data/.compilation-symlinks
Normal file
0
data/.compilation-symlinks
Normal file
@@ -30,7 +30,7 @@ SetupWebPage::AddModule(
|
||||
// Identification
|
||||
//
|
||||
'label' => 'Database maintenance tools',
|
||||
'category' => 'business',
|
||||
'category' => 'Application management',
|
||||
|
||||
// Setup
|
||||
//
|
||||
|
||||
@@ -4403,6 +4403,17 @@
|
||||
<attribute id="osfamily_name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
<uniqueness_rules>
|
||||
<rule id="name_osfamily">
|
||||
<attributes>
|
||||
<attribute id="name"/>
|
||||
<attribute id="osfamily_id"/>
|
||||
</attributes>
|
||||
<filter><![CDATA[]]></filter>
|
||||
<disabled>false</disabled>
|
||||
<is_blocking>true</is_blocking>
|
||||
</rule>
|
||||
</uniqueness_rules>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="osfamily_id" xsi:type="AttributeExternalKey">
|
||||
@@ -4469,6 +4480,16 @@
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
<uniqueness_rules>
|
||||
<rule id="name">
|
||||
<attributes>
|
||||
<attribute id="name"/>
|
||||
</attributes>
|
||||
<filter><![CDATA[]]></filter>
|
||||
<disabled>false</disabled>
|
||||
<is_blocking>true</is_blocking>
|
||||
</rule>
|
||||
</uniqueness_rules>
|
||||
</properties>
|
||||
<fields/>
|
||||
<methods/>
|
||||
@@ -4862,6 +4883,15 @@
|
||||
<attribute id="brand_name"/>
|
||||
</attributes>
|
||||
</reconciliation>
|
||||
<uniqueness_rules>
|
||||
<rule id="name_brand">
|
||||
<attributes>
|
||||
<attribute id="name"/>
|
||||
<attribute id="brand_id"/>
|
||||
</attributes>
|
||||
<is_blocking>true</is_blocking>
|
||||
</rule>
|
||||
</uniqueness_rules>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="brand_id" xsi:type="AttributeExternalKey">
|
||||
|
||||
@@ -1055,6 +1055,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Název rodiny OS',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1064,6 +1066,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:OSFamily' => 'Rodina OS',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1161,6 +1165,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Název výrobce',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1054,6 +1054,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OS familienavn',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1063,6 +1065,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:OSFamily' => 'OS-Familie',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1160,6 +1164,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Mærkenavn',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1054,6 +1054,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OS-Familienname',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1063,6 +1065,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:OSFamily' => 'OS-Familie',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1160,6 +1164,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Markenname',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1073,6 +1073,8 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OS family name',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1082,6 +1084,8 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:OSFamily' => 'OS Family',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1179,6 +1183,8 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Brand name',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1073,6 +1073,8 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OS family name',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1082,6 +1084,8 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:OSFamily' => 'OS Family',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1179,6 +1183,8 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Brand name',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1051,6 +1051,8 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => 'Familia de SO',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Familia de SO',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => 'Familia de SO',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1060,6 +1062,8 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:OSFamily' => 'Familia de SO',
|
||||
'Class:OSFamily+' => 'Familia de SO',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1157,6 +1161,8 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => 'Marca',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Marca',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => 'Marca',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1203,6 +1203,8 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Nom Famille OS',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Le nom doit être unique au sein de cette famille d\'OS',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'cette version d\'OS existe déjà dans cette famille',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1212,6 +1214,8 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:OSFamily' => 'Famille OS',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Le nom doit être unique',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'cette famille d\'OS existe déjà',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1327,6 +1331,8 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Nom Marque',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Le nom doit être unique pour cette marque',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'cette version d\'IOS existe déja sur cette marque',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1052,7 +1052,9 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:OSVersion/Attribute:osfamily_id' => 'OS család',
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '~~',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OS család név',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '~~',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1061,7 +1063,9 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:OSFamily' => 'OS család',
|
||||
'Class:OSFamily+' => '~~',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1159,6 +1163,8 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '~~',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Gyártó név',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1052,7 +1052,9 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:OSVersion/Attribute:osfamily_id' => 'Famiglia del Sistema Operativo',
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '~~',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Nome della Famiglia del Sistema Operativo',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '~~',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1061,7 +1063,9 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:OSFamily' => 'Famiglia del Sistema Operativo',
|
||||
'Class:OSFamily+' => '~~',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1180,6 +1184,8 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '~~',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Nome della marca',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1053,6 +1053,8 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OSファミリ名',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1062,6 +1064,8 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:OSFamily' => 'OSファミリ',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1159,6 +1163,8 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'ブランド名',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1055,6 +1055,8 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Naam soort besturingssysteem',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1064,6 +1066,8 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:OSFamily' => 'Soort Besturingssysteem',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1161,6 +1165,8 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Naam merk',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1053,6 +1053,8 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Nazwa rodziny OS',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1062,6 +1064,8 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:OSFamily' => 'Rodzina OS',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1159,6 +1163,8 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Nazwa marki',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1053,6 +1053,8 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Nome da família do SO',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1062,6 +1064,8 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:OSFamily' => 'Família do OS',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1159,6 +1163,8 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Nome do fabricante',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1054,6 +1054,8 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Семейство ОС',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1063,6 +1065,8 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:OSFamily' => 'Семейство ОС',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1160,6 +1164,8 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Бренд',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1053,6 +1053,8 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '~~',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'Názov kategórie OS',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1062,6 +1064,8 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:OSFamily' => 'Kategória OS',
|
||||
'Class:OSFamily+' => '~~',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1159,6 +1163,8 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '~~',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Názov značky',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1054,6 +1054,8 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '~~',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => 'OS Aile Adı',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1063,6 +1065,8 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:OSFamily' => 'OS ailesi',
|
||||
'Class:OSFamily+' => '~~',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1160,6 +1164,8 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '~~',
|
||||
'Class:IOSVersion/Attribute:brand_name' => 'Marka Adı',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -1070,6 +1070,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:OSVersion/Attribute:osfamily_id+' => '',
|
||||
'Class:OSVersion/Attribute:osfamily_name' => '名称',
|
||||
'Class:OSVersion/Attribute:osfamily_name+' => '',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily+' => 'Name must be unique in the OS family~~',
|
||||
'Class:OSVersion/UniquenessRule:name_osfamily' => 'this OS version already exists within the OS family~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1079,6 +1081,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:OSFamily' => '操作系统家族',
|
||||
'Class:OSFamily+' => '',
|
||||
'Class:OSFamily/UniquenessRule:name+' => 'Name must be unique~~',
|
||||
'Class:OSFamily/UniquenessRule:name' => 'this OS family already exists~~',
|
||||
]);
|
||||
|
||||
//
|
||||
@@ -1176,6 +1180,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:IOSVersion/Attribute:brand_id+' => '',
|
||||
'Class:IOSVersion/Attribute:brand_name' => '名称',
|
||||
'Class:IOSVersion/Attribute:brand_name+' => '',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand+' => 'Name must be unique in the brand~~',
|
||||
'Class:IOSVersion/UniquenessRule:name_brand' => 'this IOS version already exists for this brand~~',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -28,6 +28,7 @@ class ConfigEditorController extends Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(MODULESROOT.static::MODULE_NAME.'/templates', static::MODULE_NAME);
|
||||
$this->SetDebugAllowed(false);
|
||||
}
|
||||
|
||||
public function OperationEdit(): void
|
||||
|
||||
@@ -30,7 +30,7 @@ SetupWebPage::AddModule(
|
||||
// Identification
|
||||
//
|
||||
'label' => 'iTop Core Update',
|
||||
'category' => 'business',
|
||||
'category' => 'Application management',
|
||||
|
||||
// Setup
|
||||
//
|
||||
|
||||
@@ -306,11 +306,8 @@
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
</field>
|
||||
<field id="servicesubcategory_id" xsi:type="AttributeExternalKey">
|
||||
<filter><![CDATA[SELECT ServiceSubcategory WHERE service_id = :this->service_id AND (ISNULL(:this->request_type) OR request_type = :this->request_type) AND status != 'obsolete']]></filter>
|
||||
<dependencies>
|
||||
<attribute id="service_id"/>
|
||||
<attribute id="request_type"/>
|
||||
</dependencies>
|
||||
<filter><![CDATA[SELECT ServiceSubcategory WHERE service_id = :this->service_id AND status != 'obsolete']]></filter>
|
||||
<dependencies/>
|
||||
<sql>servicesubcategory_id</sql>
|
||||
<target_class>ServiceSubcategory</target_class>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
@@ -1334,21 +1331,23 @@
|
||||
// Compute the priority of the ticket
|
||||
$this->Set('priority', $this->ComputePriority());
|
||||
|
||||
// Compute the request_type if not already defined (by the user)
|
||||
$sType = $this->Get('request_type');
|
||||
if (is_null($sType) || ($sType === ''))
|
||||
{
|
||||
$iSvcSubcat = $this->Get('servicesubcategory_id');
|
||||
if ($iSvcSubcat != 0)
|
||||
{
|
||||
$oSvcSubcat = MetaModel::GetObject(ServiceSubcategory::class, $iSvcSubcat, true, true);
|
||||
$this->Set('request_type', $oSvcSubcat->Get('request_type'));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::ComputeValues();
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="EvtComputeRequestType">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
<type>EventListener</type>
|
||||
<code><![CDATA[ public function EvtComputeRequestType(?Combodo\iTop\Service\Events\EventData $oEventData = null)
|
||||
{
|
||||
$iSvcSubcat = $this->Get('servicesubcategory_id');
|
||||
if ($iSvcSubcat != 0)
|
||||
{
|
||||
$oSvcSubcat = MetaModel::GetObject(ServiceSubcategory::class, $iSvcSubcat, true, true);
|
||||
$this->Set('request_type', $oSvcSubcat->Get('request_type'));
|
||||
}
|
||||
}]]></code>
|
||||
</method>
|
||||
<method id="DisplayBareRelations">
|
||||
<static>false</static>
|
||||
<access>public</access>
|
||||
@@ -1528,6 +1527,13 @@
|
||||
}]]></code>
|
||||
</method>
|
||||
</methods>
|
||||
<event_listeners>
|
||||
<event_listener id="EVENT_DB_BEFORE_WRITE">
|
||||
<event>EVENT_DB_BEFORE_WRITE</event>
|
||||
<callback>EvtComputeRequestType</callback>
|
||||
<rank>0</rank>
|
||||
</event_listener>
|
||||
</event_listeners>
|
||||
<presentation>
|
||||
<details>
|
||||
<items>
|
||||
|
||||
@@ -243,7 +243,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Balíček služeb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Název rodiny služeb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumenty',
|
||||
|
||||
@@ -242,7 +242,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:Service/Attribute:description' => 'Beskrivelse',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokument',
|
||||
@@ -500,7 +500,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Beskrivelse',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Kunde',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -242,7 +242,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:Service/Attribute:description' => 'Beschreibung',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumente',
|
||||
|
||||
@@ -268,7 +268,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents',
|
||||
@@ -526,7 +526,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -268,7 +268,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents',
|
||||
@@ -526,7 +526,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -239,7 +239,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:Service/Attribute:description' => 'Descripción',
|
||||
'Class:Service/Attribute:description+' => 'Descripción',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_name+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:documents_list' => 'Documentos',
|
||||
|
||||
@@ -247,7 +247,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Obligatoire pour que ce service soit visible dans le portal utilisateur',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents',
|
||||
@@ -511,7 +511,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Il doit y avoir au moins une équipe pour permettre l\'assignation des Tickets',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Clients',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:customers_list/UI:Links:Create:Button+' => 'Créer un %4$s',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:Service/Attribute:description' => 'Leírás',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Szolgáltatáscsalád',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Szolgáltatáscsalád név',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumentumok',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:Service/Attribute:description' => 'Descrizione',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome della Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Documenti',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:Service/Attribute:description' => '説明',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'サービスファミリ',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => '文書',
|
||||
@@ -499,7 +499,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:DeliveryModel/Attribute:description' => '説明',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => '連絡先',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => '顧客',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -243,7 +243,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:Service/Attribute:description' => 'Omschrijving',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Naam servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documenten',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:Service/Attribute:description' => 'Opis',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Rodzina usług',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nazwa rodziny usług',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumenty',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:Service/Attribute:description' => 'Descrição',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome da família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documentos',
|
||||
|
||||
@@ -242,7 +242,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:Service/Attribute:description' => 'Описание',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Документы',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Kategória služieb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumenty',
|
||||
@@ -499,7 +499,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Popis',
|
||||
'Class:DeliveryModel/Attribute:description+' => '~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:Service/Attribute:description' => 'Tanımlama',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name~~',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents~~',
|
||||
@@ -499,7 +499,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description~~',
|
||||
'Class:DeliveryModel/Attribute:description+' => '~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -264,7 +264,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:Service/Attribute:description' => '描述',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => '服务系列',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => '服务系列名称',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => '文档',
|
||||
|
||||
@@ -218,7 +218,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:Service/Attribute:organization_name' => 'Název poskytovatele',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Balíček služeb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Název rodiny služeb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
|
||||
@@ -217,7 +217,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:Service/Attribute:organization_name' => 'Leverandør navn',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Beskrivelse',
|
||||
@@ -463,7 +463,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Beskrivelse',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Kunde',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -217,7 +217,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:Service/Attribute:organization_name' => 'Provider-Name',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Beschreibung',
|
||||
|
||||
@@ -240,7 +240,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:Service/Attribute:organization_name' => 'Provider Name',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
@@ -486,7 +486,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -240,7 +240,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:Service/Attribute:organization_name' => 'Provider Name',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
@@ -486,7 +486,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -214,7 +214,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:Service/Attribute:organization_name' => 'Proveedor',
|
||||
'Class:Service/Attribute:organization_name+' => 'Proveedor',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_name+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:description' => 'Descripción',
|
||||
|
||||
@@ -214,7 +214,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nom fournisseur',
|
||||
'Class:Service/Attribute:organization_name+' => 'Nom commun',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Obligatoire pour que ce service soit visible dans le portal utilisateur',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:services_list/UI:Links:Create:Button+' => 'Créer un %4$s',
|
||||
@@ -478,7 +478,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Il doit y avoir au moins une équipe pour permettre l\'assignation des Tickets',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Clients',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:customers_list/UI:Links:Create:Button+' => 'Créer un %4$s',
|
||||
|
||||
@@ -216,7 +216,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:Service/Attribute:organization_name' => 'Szolgáltató név',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Szolgáltatáscsalád',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Szolgáltatáscsalád név',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Leírás',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nome del Fornitore',
|
||||
'Class:Service/Attribute:organization_name+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome della Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:description' => 'Descrizione',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:Service/Attribute:organization_name' => 'プロバイダー名',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'サービスファミリ',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => '説明',
|
||||
@@ -461,7 +461,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:DeliveryModel/Attribute:description' => '説明',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => '連絡先',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => '顧客',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -217,7 +217,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:Service/Attribute:organization_name' => 'Naam leverancier',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Naam servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Omschrijving',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nazwa dostawcy',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Rodzina usług',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nazwa rodziny usług',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Opis',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nome do provedor',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome da família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Descrição',
|
||||
|
||||
@@ -216,7 +216,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:Service/Attribute:organization_name' => 'Поставщик',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Описание',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:Service/Attribute:organization_name' => 'Meno poskytovateľa',
|
||||
'Class:Service/Attribute:organization_name+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Kategória služieb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
@@ -461,7 +461,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Popis',
|
||||
'Class:DeliveryModel/Attribute:description+' => '~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -216,7 +216,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:Service/Attribute:organization_name' => 'Sağlayıcı Adı',
|
||||
'Class:Service/Attribute:organization_name+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Servis Ailesi',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Servis Aile Adı',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:description' => 'Tanımlama',
|
||||
|
||||
@@ -236,7 +236,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:Service/Attribute:organization_name' => '供应商名称',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => '服务系列',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => '服务系列名称',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => '描述',
|
||||
|
||||
@@ -12,8 +12,7 @@ SetupWebPage::AddModule(
|
||||
// Setup
|
||||
//
|
||||
'dependencies' => [
|
||||
'itop-structure/2.7.1',
|
||||
'itop-portal/3.0.0', // module_design_itop_design->module_designs->itop-portal
|
||||
'itop-structure/2.7.1 || itop-portal/3.0.0', // itop-portal : module_design_itop_design->module_designs->itop-portal
|
||||
],
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
|
||||
@@ -708,6 +708,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Triger \'aktualizace objektu\'',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Spustit při aktualizaci objektu [podřízené třídy] dané třídy',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Cílová pole',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -707,6 +707,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -704,6 +704,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (bei Objektanpassung)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger bei Objektanpassung einer gegebenen Klasse oder Kindklasse',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Ziel-Felder',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -801,6 +801,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -1333,6 +1333,7 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'UI:DashletGroupBy:Prop-GroupBy:DayOfMonth' => 'Day of month for %1$s',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-Hour' => '%1$s (hour)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-Month' => '%1$s (month)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-Year' => '%1$s (year)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek' => '%1$s (day of week)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth' => '%1$s (day of month)',
|
||||
'UI:DashletGroupBy:MissingGroupBy' => 'Please select the field on which the objects will be grouped together',
|
||||
@@ -1653,6 +1654,8 @@ When associated with a trigger, each action is given an "order" number, specifyi
|
||||
'UI:Search:Criteria:Raw:FilteredOn' => 'Filtered on %1$s',
|
||||
|
||||
'UI:StateChanged' => 'State changed',
|
||||
|
||||
'UI:AddSubTree' => 'Add entry',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -784,6 +784,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -695,6 +695,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Disparador (actualizando un objecto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Disparador al actualizar un objeto de la clase dada [o una clase hija]',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos objetivo',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => 'Campos que serán monitorizados',
|
||||
]);
|
||||
|
||||
@@ -746,6 +746,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Déclencheur sur la modification d\'un objet',
|
||||
'Class:TriggerOnObjectUpdate+' => '',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'Ce filtre est appliqué après la sauvegarde en base de l\'objet modifié. Il restreint les objets qui vont déclencher les actions.',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Attributs cible',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -1279,6 +1279,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'UI:DashletGroupBy:Prop-GroupBy:DayOfMonth' => 'Jour du mois pour %1$s',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-Hour' => '%1$s (heure)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-Month' => '%1$s (mois)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-Year' => '%1$s (année)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek' => '%1$s (jour de la semaine)',
|
||||
'UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth' => '%1$s (jour du mois)',
|
||||
'UI:DashletGroupBy:MissingGroupBy' => 'Veuillez sélectionner le champ sur lequel les objets seront groupés',
|
||||
@@ -1544,7 +1545,8 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
|
||||
'UI:Search:Criteria:HierarchicalKey:ChildrenIncluded:Hint' => 'Les descendants des objets sélectionnés seront inclus.',
|
||||
'UI:Search:Criteria:Raw:Filtered' => 'Filtré',
|
||||
'UI:Search:Criteria:Raw:FilteredOn' => 'Filtré sur %1$s',
|
||||
'UI:StateChanged' => 'Etat modifié',
|
||||
'UI:StateChanged' => 'État modifié',
|
||||
'UI:AddSubTree' => 'Ajouter une entrée',
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
@@ -702,6 +702,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Eseményindító (objektum frissítéskor)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Az adott osztály [egy gyermekosztálya] objektumának frissítésekor elinduló eseményindító',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Célmezők',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -702,6 +702,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (alla modifica dell\'oggetto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger alla modifica dell\'oggetto di [una classe figlia della] classe specificata',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campi di destinazione',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -706,6 +706,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '~~',
|
||||
]);
|
||||
|
||||
@@ -704,6 +704,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (bij het aanpassen van een object)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger bij het aanpassen van een object van de opgegeven klasse (of subklasse ervan)',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Doelvelden',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -704,6 +704,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Wyzwalacz (przy aktualizacji obiektu)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Wyzwalanie przy aktualizacji obiektu [klasy potomnej] danej klasy',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Pola docelowe',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -702,6 +702,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Gatilho (na atualização do objeto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Gatilho na atualização de objeto de [uma classe filha] de uma determinada classe',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos de destino',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -707,6 +707,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Триггер на обновление объекта',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Триггер на обновление объекта данного или дочернего класса',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Отслеживаемые поля',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => 'Поля объекта, при обновлении которых сработает триггер',
|
||||
]);
|
||||
|
||||
@@ -720,6 +720,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '~~',
|
||||
]);
|
||||
|
||||
@@ -707,6 +707,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -19,8 +19,15 @@
|
||||
*/
|
||||
|
||||
// Input
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'UI:Component:Input:ChangeNotAllowed' => 'This change is not allowed',
|
||||
'UI:Component:Input:Password:DoesNotMatch' => 'Passwords do not match',
|
||||
'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s item(s) required',
|
||||
]);
|
||||
Dict::Add(
|
||||
'EN US',
|
||||
'English',
|
||||
'English',
|
||||
[
|
||||
'UI:Component:Input:ChangeNotAllowed' => 'This change is not allowed',
|
||||
'UI:Component:Input:Password:DoesNotMatch' => 'Passwords do not match',
|
||||
'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s item(s) required',
|
||||
|
||||
'UI:Component:Input:Select:Select_item' => 'Select an item...',
|
||||
]
|
||||
);
|
||||
|
||||
@@ -10,8 +10,15 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'UI:Component:Input:ChangeNotAllowed' => 'Cette modification n\'est pas autorisée',
|
||||
'UI:Component:Input:Password:DoesNotMatch' => 'Les mots de passe ne correspondent pas',
|
||||
'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s élément(s) requis',
|
||||
]);
|
||||
Dict::Add(
|
||||
'FR FR',
|
||||
'French',
|
||||
'Français',
|
||||
[
|
||||
'UI:Component:Input:ChangeNotAllowed' => 'Cette modification n\'est pas autorisée',
|
||||
'UI:Component:Input:Password:DoesNotMatch' => 'Les mots de passe ne correspondent pas',
|
||||
'UI:Component:Input:Set:MinimumItems' => 'Minimum %1$s élément(s) requis',
|
||||
|
||||
'UI:Component:Input:Select:Select_item' => 'Sélectionnez un élément...',
|
||||
]
|
||||
);
|
||||
|
||||
@@ -739,6 +739,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:TriggerOnObjectUpdate' => '触发器 (对象更新时)',
|
||||
'Class:TriggerOnObjectUpdate+' => '指定类型或子类型对象更新时的触发器',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => '目标字段',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
45
js/forms/choices_element.js
Normal file
45
js/forms/choices_element.js
Normal file
@@ -0,0 +1,45 @@
|
||||
class ChoicesElement extends HTMLSelectElement {
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
customElements.define('choices-element', ChoicesElement, {extends: 'select'});
|
||||
}
|
||||
|
||||
plugins = [];
|
||||
connectedCallback() {
|
||||
|
||||
if (this.tomselect) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getAttribute('multiple')) {
|
||||
this.plugins.push('remove_button');
|
||||
}
|
||||
|
||||
const options = {
|
||||
plugins: this.plugins,
|
||||
wrapperClass: 'ts-wrapper ibo-input-wrapper ibo-input-select-wrapper--with-buttons ibo-input-select-autocomplete-wrapper',
|
||||
controlClass: 'ts-control ibo-input ibo-input-select ibo-input-select-autocomplete',
|
||||
dropdownParent: 'body',
|
||||
render: {
|
||||
dropdown: function (data, escape) {
|
||||
return `<div class="selectize-dropdown"></div>`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (this.getAttribute('data-tom-select-disable-auto-complete')) {
|
||||
// options.controlInput = null;
|
||||
}
|
||||
if (this.getAttribute('data-tom-select-max-items-selected') && this.getAttribute('data-tom-select-max-items-selected') !== '') {
|
||||
options.maxItems = parseInt(this.getAttribute('data-tom-select-max-items-selected'));
|
||||
}
|
||||
if (this.getAttribute('data-tom-select-placehelder')) {
|
||||
options.placeholder = this.getAttribute('data-tom-select-placehelder');
|
||||
}
|
||||
|
||||
new TomSelect(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
39
js/forms/collection_element.js
Normal file
39
js/forms/collection_element.js
Normal file
@@ -0,0 +1,39 @@
|
||||
class CollectionElement extends HTMLElement {
|
||||
|
||||
#eBtnAdd;
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
customElements.define('collection-element', CollectionElement);
|
||||
}
|
||||
|
||||
addFormToCollection(e) {
|
||||
const collectionHolder = document.querySelector('.'+e.currentTarget.dataset.collectionHolderClass);
|
||||
const item = document.createElement('div');
|
||||
|
||||
const collectionHolderList = collectionHolder.querySelector('[role="list"]');
|
||||
|
||||
item.innerHTML = collectionHolder
|
||||
.dataset
|
||||
.prototype
|
||||
.replace(
|
||||
/__name__/g,
|
||||
collectionHolder.dataset.index
|
||||
);
|
||||
|
||||
collectionHolderList.appendChild(item.firstChild);
|
||||
collectionHolder.dataset.index++;
|
||||
|
||||
this.querySelectorAll('collection-entry-element').forEach((entry) => {
|
||||
console.log('test');
|
||||
entry.updateButtonStates();
|
||||
});
|
||||
}
|
||||
|
||||
/** connectedCallback **/
|
||||
connectedCallback() {
|
||||
this.#eBtnAdd = this.querySelector('.add_item_link');
|
||||
this.#eBtnAdd.addEventListener('click', this.addFormToCollection.bind(this));
|
||||
}
|
||||
|
||||
}
|
||||
112
js/forms/collection_entry_element.js
Normal file
112
js/forms/collection_entry_element.js
Normal file
@@ -0,0 +1,112 @@
|
||||
class CollectionEntryElement extends HTMLElement {
|
||||
|
||||
// Button elements
|
||||
#eBtnDelete;
|
||||
#eBtnMoveUp;
|
||||
#eBtnMoveDown;
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
customElements.define('collection-entry-element', CollectionEntryElement);
|
||||
}
|
||||
|
||||
/** connectedCallback **/
|
||||
connectedCallback() {
|
||||
|
||||
if ((this.dataset.new || this.dataset.allowDelete) && this.#eBtnDelete === undefined) {
|
||||
this.#eBtnDelete = this.#createButton('Remove', 'ibo-button ibo-is-regular ibo-is-danger');
|
||||
this.#eBtnDelete.addEventListener('click', this.#removeCollectionItem.bind(this));
|
||||
this.appendChild(this.#eBtnDelete);
|
||||
}
|
||||
|
||||
if (this.dataset.allowOrdering) {
|
||||
if (this.#eBtnMoveUp === undefined) {
|
||||
this.#eBtnMoveUp = this.#createButton('Move Up', 'ibo-button ibo-is-regular');
|
||||
this.#eBtnMoveUp.addEventListener('click', this.#moveUp.bind(this));
|
||||
this.appendChild(this.#eBtnMoveUp);
|
||||
}
|
||||
if (this.#eBtnMoveDown === undefined) {
|
||||
this.#eBtnMoveDown = this.#createButton('Move Down', 'ibo-button ibo-is-regular');
|
||||
this.#eBtnMoveDown.addEventListener('click', this.#moveDown.bind(this));
|
||||
this.appendChild(this.#eBtnMoveDown);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateButtonStates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state of the buttons (enabled/disabled).
|
||||
*
|
||||
*/
|
||||
updateButtonStates() {
|
||||
|
||||
if (this.dataset.allowOrdering) {
|
||||
|
||||
if (this.previousElementSibling === null) {
|
||||
this.#eBtnMoveUp.setAttribute('disabled', 'disabled');
|
||||
} else {
|
||||
this.#eBtnMoveUp.removeAttribute('disabled');
|
||||
}
|
||||
|
||||
if (this.nextElementSibling === null) {
|
||||
this.#eBtnMoveDown.setAttribute('disabled', 'disabled');
|
||||
} else {
|
||||
this.#eBtnMoveDown.removeAttribute('disabled');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a button element.
|
||||
*
|
||||
* @param label
|
||||
* @param className
|
||||
* @returns {HTMLButtonElement}
|
||||
*/
|
||||
#createButton(label, className) {
|
||||
|
||||
const btnElement = document.createElement('button');
|
||||
btnElement.type = 'button';
|
||||
btnElement.className = className;
|
||||
btnElement.textContent = label;
|
||||
|
||||
return btnElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this collection item up.
|
||||
*
|
||||
*/
|
||||
#moveUp() {
|
||||
const prev = this.previousElementSibling;
|
||||
if (prev) {
|
||||
this.parentNode.insertBefore(this, prev);
|
||||
this.updateButtonStates();
|
||||
prev.updateButtonStates();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this collection item down.
|
||||
*
|
||||
*/
|
||||
#moveDown() {
|
||||
const next = this.nextElementSibling;
|
||||
if (next) {
|
||||
this.parentNode.insertBefore(next, this);
|
||||
this.updateButtonStates();
|
||||
next.updateButtonStates();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this collection item.
|
||||
*
|
||||
*/
|
||||
#removeCollectionItem() {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
95
js/forms/form_element.js
Normal file
95
js/forms/form_element.js
Normal file
@@ -0,0 +1,95 @@
|
||||
class FormElement extends HTMLFormElement
|
||||
{
|
||||
static #TURBO_REFRESHING_CLASS = 'turbo-refreshing';
|
||||
static #TURBO_TRIGGER_FIELD = '_turbo_trigger';
|
||||
|
||||
#aFormBlockDataTransmittedData = {};
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
customElements.define('itop-form-element', FormElement, {extends: 'form'});
|
||||
}
|
||||
|
||||
TriggerTurbo(oElement) {
|
||||
|
||||
// Get the name and id of the element triggering turbo
|
||||
const sName = oElement.getAttribute('name');
|
||||
const sId = oElement.getAttribute('id');
|
||||
|
||||
if(FormElement.IsCheckbox(oElement) || this.#aFormBlockDataTransmittedData[sName] !== oElement.value) {
|
||||
|
||||
// Refresh UI
|
||||
this.#StartRefreshingUI(sId);
|
||||
|
||||
// Pre Submit
|
||||
this.#PreSubmitTurboForm(sName);
|
||||
|
||||
// Submit
|
||||
oElement.form.requestSubmit();
|
||||
|
||||
// Post Submit
|
||||
this.#PostSubmitTurboForm(sName)
|
||||
|
||||
this.#aFormBlockDataTransmittedData[sName] = oElement.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start refreshing UI.
|
||||
*
|
||||
* @param sId
|
||||
* @constructor
|
||||
*/
|
||||
#StartRefreshingUI(sId)
|
||||
{
|
||||
Array.from(this.querySelectorAll(`.ibo-content-block`)).forEach(block => {
|
||||
if(block.dataset.impactedBy !== undefined){
|
||||
const aImpactedBy = block.dataset.impactedBy.split(',');
|
||||
if(aImpactedBy.includes(sId)){
|
||||
block.classList.add(FormElement.#TURBO_REFRESHING_CLASS);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre submit the form.
|
||||
* Set the turbo trigger field in the form and disable validation
|
||||
*
|
||||
* @param sName
|
||||
* @constructor
|
||||
*/
|
||||
#PreSubmitTurboForm(sName)
|
||||
{
|
||||
this.querySelector(`[name="${this.getAttribute("name")}[${FormElement.#TURBO_TRIGGER_FIELD}]"]`).value = sName;
|
||||
this.setAttribute('novalidate', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post submit the form.
|
||||
* Reset the turbo trigger field and restore form validation.
|
||||
*
|
||||
* @param sName
|
||||
* @constructor
|
||||
*/
|
||||
#PostSubmitTurboForm(sName)
|
||||
{
|
||||
this.querySelector(`[name="${this.getAttribute("name")}[${FormElement.#TURBO_TRIGGER_FIELD}]"]`).value = null;
|
||||
this.removeAttribute('novalidate');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param oElement
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static IsCheckbox (oElement)
|
||||
{
|
||||
return oElement instanceof HTMLInputElement
|
||||
&& oElement.getAttribute('type') === 'checkbox'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
123
js/forms/oql_element.js
Normal file
123
js/forms/oql_element.js
Normal file
@@ -0,0 +1,123 @@
|
||||
class OqlElement extends HTMLTextAreaElement {
|
||||
|
||||
static #DEBONCE = 400;
|
||||
|
||||
// register the custom element
|
||||
static{
|
||||
customElements.define('oql-element', OqlElement, {extends: 'textarea'});
|
||||
}
|
||||
|
||||
// variables
|
||||
#url = '../pages/ajax.render.php?route=oql.validate_query';
|
||||
#iconValid = 'fa-check-double';
|
||||
#iconNotValid = 'fa-exclamation-triangle';
|
||||
#debounceTimer = null;
|
||||
#debounce = OqlElement.#DEBONCE;
|
||||
|
||||
/** connectedCallback **/
|
||||
connectedCallback() {
|
||||
this.addEventListener('input', this.#onInput.bind(this));
|
||||
this.#callValidateQuery();
|
||||
|
||||
this.addEventListener('focus', this.#onFocus.bind(this));
|
||||
|
||||
const oBtnBook = this.closest('.ibo-content-block').querySelector('[data-role="ibo-button"][data-action="book"]');
|
||||
oBtnBook.addEventListener('click', this.#search.bind(this))
|
||||
|
||||
const oBtnRun = this.closest('.ibo-content-block').querySelector('[data-role="ibo-button"][data-action="run"]');
|
||||
oBtnRun.addEventListener('click', this.#run.bind(this))
|
||||
}
|
||||
|
||||
/**
|
||||
* Call oql verification with debounce when input event is fired.
|
||||
*/
|
||||
#onInput() {
|
||||
if (this.#debounceTimer) clearTimeout(this.#debounceTimer);
|
||||
this.#debounceTimer = setTimeout(() => {
|
||||
this.#callValidateQuery(true);
|
||||
}, this.#debounce);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call oql verification with debounce when focus event is fired.
|
||||
*/
|
||||
#onFocus() {
|
||||
this.#callValidateQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the ajax to validate the query.
|
||||
*
|
||||
* @param fireChange flag to handle change event
|
||||
*/
|
||||
#callValidateQuery(fireChange = false) {
|
||||
|
||||
fetch(this.#url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Combodo-Ajax': true
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query: this.value
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
// fire change event only if the query is valid
|
||||
if (fireChange && response.is_valid){
|
||||
this.#fireChangeEvent();
|
||||
}
|
||||
// update the icon color
|
||||
const fieldEl = this.closest('.ibo-field');
|
||||
const marqueeEl = fieldEl.querySelector('[role="marquee"]');
|
||||
marqueeEl.style.color = response.is_valid ? 'green' : 'orange';
|
||||
marqueeEl.classList.toggle(this.#iconNotValid, !response.is_valid);
|
||||
marqueeEl.classList.toggle(this.#iconValid, response.is_valid);
|
||||
marqueeEl.setAttribute('title', response.is_valid ? Dict.S(this.dataset.validQueryText) : Dict.S(this.dataset.invalidQueryText));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire a change event.
|
||||
*/
|
||||
#fireChangeEvent() {
|
||||
const changeEvent = new Event('change', { bubbles: true, cancelable: true });
|
||||
this.dispatchEvent(changeEvent);
|
||||
}
|
||||
|
||||
#search(){
|
||||
const sId = this.getAttribute('id');
|
||||
const sDialogId = `ac_dlg_${sId}`;
|
||||
|
||||
const sModalTitle = Dict.S(this.dataset.modalTitleText);
|
||||
const sEmptyText = Dict.S(this.dataset.emptyText);
|
||||
|
||||
// Instance the widget
|
||||
const oACWidget = new ExtKeyWidget(sId, 'QueryOQL', 'SELECT QueryOQL WHERE is_template = \'yes\'', sModalTitle, true, null, null, true, true, 'oql');
|
||||
oACWidget.emptyHtml = `<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p><${sEmptyText}/p></div>`;
|
||||
|
||||
// Store in window to be accessible from dialog
|
||||
window[`oACWidget_${sId}`] = oACWidget;
|
||||
|
||||
// Open the dialog
|
||||
if ($(`#${sDialogId}`).length === 0)
|
||||
{
|
||||
$('body').append(`<div id="${sDialogId}"></div>`);
|
||||
$(`#${sDialogId}`).dialog({
|
||||
width: $(window).width()*0.8,
|
||||
height: $(window).height()*0.8,
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
resizeStop: oACWidget.UpdateSizes,
|
||||
});
|
||||
}
|
||||
|
||||
// Start searching
|
||||
oACWidget.Search();
|
||||
}
|
||||
|
||||
#run(){
|
||||
window.open('../pages/run_query.php?expression=' + encodeURI(this.value), '_blank');
|
||||
}
|
||||
}
|
||||
26
js/forms/turbo_stream_event_element.js
Normal file
26
js/forms/turbo_stream_event_element.js
Normal file
@@ -0,0 +1,26 @@
|
||||
class TurboStreamEvent extends HTMLElement {
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
customElements.define('turbo-stream-event', TurboStreamEvent);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.style.display = 'none';
|
||||
|
||||
const event = new CustomEvent("itop:TurboStreamEvent", {
|
||||
detail: {
|
||||
id: this.getAttribute('id'),
|
||||
form_id: this.dataset.formId,
|
||||
block_class: this.dataset.formBlockClass,
|
||||
view_data: this.dataset.viewData,
|
||||
valid: this.dataset.valid,
|
||||
},
|
||||
});
|
||||
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user