Compare commits

...

235 Commits

Author SHA1 Message Date
Eric Espie
8bd72409f1 N°6716 - High memory Consomption and performance issue 2023-09-14 15:16:11 +02:00
Eric Espie
3eb06f8ada N°6716 - High memory Consomption and performance issue 2023-09-14 14:38:17 +02:00
Eric Espie
44c189223e Merge branch 'support/3.1.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/unitary-tests/core/DBObjectTest.php
2023-09-14 14:31:29 +02:00
Eric Espie
7fdbb59c30 N°6716 - High memory Consomption and performance issue 2023-09-14 14:09:05 +02:00
Eric Espie
5acf38ac36 Fix unit tests for MariaDB
(cherry picked from commit 61a9a4ac65)
2023-09-14 14:09:05 +02:00
odain
3e258f32cc N°5491-fix redundant GetNonPublicStaticProperty 2023-09-13 10:30:56 +02:00
odain
3c51d6fb98 N°5491- fix dictionary test 2023-09-13 10:27:19 +02:00
odain
7cfe1389aa Merge branch 'support/3.0' into support/3.1 2023-09-13 10:20:38 +02:00
Stephen Abello
7292a8540b N°6547 - Disallow linkset edition when lnk attribute is readonly 2023-09-13 10:53:32 +02:00
odain
f65c690462 N°5491-fix test 2023-09-13 10:03:05 +02:00
odain
ecf8bc42fa Merge branch 'support/2.7' into support/3.0 2023-09-13 10:01:15 +02:00
odain-cbd
e76728b2bf N°5491 - Inconsistent dictionnary entries regarding arguments to pass to Dict::Format-test first (#545) 2023-09-13 12:02:49 +02:00
vdumas
faba812fc1 N°6646 - Wrong dictionary entry for FR - Lnk Contact / Contrat 2023-09-12 12:48:33 +02:00
vdumas
add433d702 N°6706 - Missing dictionary entry for DE - Lnk Provider Contract / Service 2023-09-12 12:24:56 +02:00
vdumas
9c99cb35e5 N°6706 - Wrong dictionary entry for FR - Lnk Provider Contract / Service 2023-09-12 12:21:25 +02:00
Pierre Goiffon
9d392ad167 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-09-07 14:53:02 +02:00
Pierre Goiffon
ea8509db1f N°6709 Use ItopTestCase::RequireOnceCurrentModuleFile in GetAppRoot 2023-09-07 14:47:36 +02:00
Pierre Goiffon
df25ce76b6 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-09-07 14:43:29 +02:00
Pierre Goiffon
e946fc65fc N°6709 New ItopTestCase::RequireOnceCurrentModuleFile 2023-09-07 14:38:19 +02:00
Pierre Goiffon
d203e075a8 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-09-06 09:09:37 +02:00
Pierre Goiffon
dbe2f66539 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-09-06 09:07:45 +02:00
Pierre Goiffon
0d8ff7bbac N°6629 Set commit tests back to Mysql
For now we have perf issues on Jenkins with MariaDB (see N°6694)
2023-09-04 10:25:41 +02:00
Eric Espie
48eb022824 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-09-01 14:15:06 +02:00
Stephen Abello
03c9ffc033 N°6560 - Fix unescaped backtick in friendlyname breaking details page scripts 2023-09-01 09:41:23 +02:00
Eric Espie
61a9a4ac65 Fix unit tests for MariaDB 2023-09-01 09:29:21 +02:00
acognet
38962e68ee Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	pages/ajax.render.php
2023-08-31 16:22:01 +02:00
Pierre Goiffon
483dbb4a5d N°6658 Remove useless annotations
See comment for ItopTestCase::$preserveGlobalState
2023-08-31 16:06:34 +02:00
acognet
1f4dcc4f9e N°5136 - Relations: Fix "Select All objects" adding obsolete objects even if "show obsolete data" param. not activated - Merge from support/2.7 2023-08-31 16:04:03 +02:00
acognet
e86309669e Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	pages/ajax.render.php
2023-08-31 15:56:16 +02:00
Pierre Goiffon
6d6f55acf7 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php
2023-08-31 15:40:56 +02:00
Pierre Goiffon
6ebcd44bb1 💡 N°6658 Add more comments and since tags 2023-08-31 15:34:44 +02:00
Anne-Catherine
f8fb51fea0 N°5145 - Fix attachments missing in new ticket when clone from an old ticket with object copier (#530) 2023-08-31 15:27:23 +02:00
Anne-Catherine
bf768311c2 N°5136 - "Select All objects" add obsolete objects even if the parameter show obsolete data is not activated (#467) 2023-08-31 15:13:20 +02:00
Anne-Catherine
d797436786 N°6555 - Add class description in tooltip of Dashlet badge (#504)
cheery pick from branch develop due to target branch error
2023-08-31 14:55:06 +02:00
Anne-Catherine
b508c0d983 N°6152 - Search: Criteria & object list loaded twice (#495) 2023-08-31 12:03:31 +02:00
Anne-Catherine
351893bbdd N°4494 - Fix auto-locking on log save and transition (#358) 2023-08-31 11:23:58 +02:00
vdumas
59e4bb028f N°6682 - Pbs with Audit classes and AccessRight 2023-08-29 16:41:27 +02:00
vdumas
6d895371ec N°6682 - AuditDomain XML meta declaration missing 2023-08-29 16:41:27 +02:00
Stephen Abello
ab91631e68 N°6677 - Ensure emails in test are never sent to cc'd and bcc'd addresses 2023-08-29 15:56:52 +02:00
Eric Espie
3366bae0ab N°6061 - Add tests on Expression evaluation 2023-08-18 15:34:06 +02:00
Romain Quetiez
03b484c349 Tests: fix test not working on MariaDB (unexpected coma tolerated by MySQL) 2023-08-18 12:13:11 +02:00
Molkobain
70081ecf33 N°6436 - Add unit test for API introduced in 3.1 (\iFieldRendererMappingsExtension) 2023-08-18 10:31:05 +02:00
Molkobain
575ba1cd7b Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	core/metamodel.class.php
2023-08-18 10:24:50 +02:00
Molkobain
d130959692 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	core/metamodel.class.php
2023-08-18 10:14:51 +02:00
Molkobain
a8c689c6c0 N°6436 - Add unit test to ensure that we don't lose an API during merge between branches 2023-08-18 09:55:45 +02:00
Molkobain
1990ccb5d8 N°6436 - Move interfaces enumeration from 1 line to 1 line / interface (and re-ordered them) for easier merges in newer branches 2023-08-18 09:52:55 +02:00
Molkobain
e107be56e4 N°6097 - Tests: Fix missing hook entry in PHPUnit XML file that led to compiled environment being re-build for each test case 2023-08-18 09:51:15 +02:00
Romain Quetiez
0f8e87e001 Tests: allow execution of RouterTest alone, fix tool to execute each test class separately 2023-08-18 08:44:54 +02:00
Molkobain
d92d2b5e9e Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	core/metamodel.class.php
2023-08-17 21:36:19 +02:00
Romain Quetiez
ebd0136773 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
2023-08-17 18:36:34 +02:00
Molkobain
f6653e1594 N°6436 - Restore 3.0 APIs lost during 6433678d merge 2023-08-17 17:47:46 +02:00
Romain Quetiez
65bb76b9e3 N°6658 - Boost PHPUnit tests execution 2023-08-17 17:27:55 +02:00
Molkobain
f238593966 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php
#	tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
2023-08-11 09:19:49 +02:00
Molkobain
d951d3b872 💚 Fix typo in extended class name 2023-08-11 09:05:30 +02:00
Molkobain
ccceb870e3 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php
#	tests/php-unit-tests/src/BaseTestCase/ItopTestCase.php
2023-08-10 15:53:05 +02:00
Molkobain
ed6df77cbb N°6097 - Tests: Optimize performances by creating custom env. only once and re-using it across test classes 2023-08-10 15:45:39 +02:00
Molkobain
1ad28312ec N°6097 - Tests: Introduce autoloader for "utility" classes and move them to a sub-folder for better organization as folder was still messy
Note that unittestautoload.php is now useless. We just keep for now until everything is migrated (projects / branches / modules)
2023-08-10 15:45:39 +02:00
Molkobain
f002aa04cd N°6097 - Tests: Enable PHP unit tests on a custom DataModel 2023-08-10 15:45:39 +02:00
Molkobain
b86d70623e N°6097 - Tests: Temporarily add test case for the new ItopCustomDatamodelTestCase class 2023-08-10 15:45:39 +02:00
Molkobain
fe3467309d N°6097 - Tests: Refactor base test classes for better extensibility 2023-08-10 15:45:39 +02:00
Molkobain
851ab9c356 N°6097 - Add \utils::GetDataPath() method to avoid duplicating manual path build 2023-08-10 15:45:39 +02:00
Molkobain
aef3c2e609 N°6097 - Fix \CMDBSource::DropDB() not resetting cache like \CMDBSource::DropTable() which can lead to errors when trying to re-create it afterwards 2023-08-10 15:45:39 +02:00
Pierre Goiffon
5212e15cc4 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-10 14:41:05 +02:00
Pierre Goiffon
f04fc546b5 N°6643 Fix TypeError in \CMDBSource::LogDeadLock 2023-08-10 14:34:09 +02:00
Lars Kaltefleiter
caf3076b12 N°3441 - Portal: Fix failure to open an object containing a link to an archived object (#523)
* N°3441 - Portal : cannot open an object containing a link to an archived object

* N°3441 - Display fa-archive icon in portal

* Update sources/Renderer/Bootstrap/FieldRenderer/BsSelectObjectFieldRenderer.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update sources/Renderer/Bootstrap/FieldRenderer/BsSelectObjectFieldRenderer.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

* Update sources/Renderer/Bootstrap/FieldRenderer/BsSelectObjectFieldRenderer.php

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2023-08-10 09:52:22 +02:00
Pierre Goiffon
c4c400d852 N°6638 💡 More explanations on CompiledDictionariesConsistencyTest::testImportCsvMessageStillOk 2023-08-09 14:54:19 +02:00
Pierre Goiffon
6cc4cc4fb6 📝 Version history : add 3.1.0-2 2023-08-09 10:20:27 +02:00
Pierre Goiffon
d7495af207 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-08 15:42:39 +02:00
Pierre Goiffon
13ad98b9b3 Add other integration tests in the beforeSetup group
All of those tests can be ran without a running iTop instance, and are blocking
2023-08-08 15:34:27 +02:00
Pierre Goiffon
4be54fdd65 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-08-08 15:33:36 +02:00
Pierre Goiffon
6d13397ba1 Add other integration tests in the beforeSetup group
All of those tests can be ran without a running iTop instance, and are blocking
2023-08-08 15:33:09 +02:00
Pierre Goiffon
48e7e0309a N°6638 Fix DictionariesConsistencyTest::testImportCsvMessageStillOk not run on Jenkins
Was contained in a class with a beforeSetup group annotation, whereas it tries to read files in env-production (!)
Plus the dataprovider was using APPROOT const + utils class, which aren't available by default :(
=> Fixed by moving in a dedicated class (CompiledDictionariesConsistencyTest) and removing the dataprovider
2023-08-08 15:30:01 +02:00
Pierre Goiffon
2ce9b2afaf Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-04 14:58:38 +02:00
Pierre Goiffon
d64a91d4ce Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	core/metamodel.class.php
2023-08-04 14:58:22 +02:00
Pierre Goiffon
c0c8a13864 💡 \MetaModel::GetObject : remove documented throw Exception 2023-08-04 14:55:38 +02:00
Pierre Goiffon
5ffa41bc16 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-03 11:09:14 +02:00
Pierre Goiffon
d2eef06276 AttributeURLTest : remove useless separateProcess annotations 2023-08-03 11:08:47 +02:00
Pierre Goiffon
77b14c516e Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-03 09:41:22 +02:00
Pierre Goiffon
880a824f2f N°6562 Replace new DOMText() by \DOMDocument::createTextNode
Because init using constructor outputs a read only node, see https://www.php.net/manual/en/domelement.construct.php
Thanks @Hipska
See conversation in 734a788
2023-08-03 09:40:39 +02:00
Molkobain
f7f1b5f399 Merge remote-tracking branch 'origin/support/3.1.0' into support/3.1 2023-08-02 15:27:17 +02:00
Molkobain
85f66f5e0c N°6618 - Router: Add protection against invalid routes cache 2023-08-02 11:44:20 +02:00
Molkobain
a5c980113b N°6618 - Router: Fix available routes cache being re-generated at each call 2023-08-02 11:44:20 +02:00
Pierre Goiffon
18efbfa803 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-02 10:39:51 +02:00
Pierre Goiffon
7aa478d6ff N°6562 💡 Fix comment
Thanks @Molkobain !
2023-08-02 10:35:30 +02:00
Pierre Goiffon
97700dbf15 N°6562 Re-enable failing tests
Conditional disabling was made in ea8e7c5
2023-08-01 14:27:57 +02:00
Pierre Goiffon
c25c69d746 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-08-01 14:27:41 +02:00
Pierre Goiffon
734a788340 N°6562 Fix DOMNode->textContent write
This attribute is read only
Causes layout issues on PHP 8.1.21 and 8.2.8
2023-08-01 14:22:56 +02:00
Eric Espie
eb1eb15791 N°6061 - Allow services to implement interfaces
N°6061 - allow local path from an arbitrary path

(cherry picked from commit 19e7fc9cb9)
(cherry picked from commit fb23bddeb2)
(cherry picked from commit 750ecd4804)
2023-07-28 10:46:06 +02:00
Pierre Goiffon
a84077782d N°4354 N°6587 Remove duplicated ItopDataTestCase::CreateContactlessUser method
Regression introduced by 26048150
2023-07-27 16:48:49 +02:00
Pierre Goiffon
26048150d3 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	tests/php-unit-tests/ItopDataTestCase.php
2023-07-27 16:44:02 +02:00
Pierre Goiffon
e5b6e2eb8c N°4354 N°6587 Add test to cover $oUser->Get('profile_list') VS security.hide_administrators config param 2023-07-27 16:42:56 +02:00
Pierre Goiffon
87b6ea4def 📝 Version history : add missing 3.1.0-beta 2023-07-27 14:55:55 +02:00
purplegrape
72873a3343 🌐 Improve zh-cn dict
Manual merge for #516
Translation by @purplegrape, many thanks !
2023-07-27 11:17:09 +02:00
Pierre Goiffon
5ef25ccb77 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-07-26 12:07:50 +02:00
Pierre Goiffon
1682a85cc0 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-07-26 12:07:35 +02:00
Pierre Goiffon
cd9beec313 Merge remote-tracking branch 'origin/support/2.6' into support/2.7 2023-07-26 12:07:09 +02:00
Pierre Goiffon
8295eaed90 Merge remote-tracking branch 'origin/support/2.5' into support/2.6 2023-07-26 12:06:32 +02:00
Eric Espie
86a7cefa68 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-07-25 17:56:12 +02:00
Eric Espie
829b648dd2 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-07-25 17:55:45 +02:00
Eric Espie
5475b9fbbe N°3454 - MoveToProd in 2 steps - fix utils::GetCurrentModuleName() 2023-07-25 17:44:43 +02:00
Eric Espie
6f8e7c7002 N°3454 - MoveToProd in 2 steps - fix utils::GetCurrentModuleUrl() 2023-07-25 17:20:37 +02:00
Pierre Goiffon
67ca554261 📝 Version history : add 3.1.0-1 2023-07-25 17:07:30 +02:00
Pierre Goiffon
f89953f39e Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-07-24 15:39:09 +02:00
Pierre Goiffon
772368ef8a 💡 PHPDoc for object list panels 2023-07-24 15:38:57 +02:00
Pierre Goiffon
2e049aa244 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-07-24 11:59:57 +02:00
Pierre Goiffon
a57b6471c9 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-07-24 11:59:40 +02:00
Pierre Goiffon
bc7c1b4744 N°6590 Fix DictionariesConsistencyTest for PL dict files 2023-07-24 11:14:37 +02:00
Eric Espie
12c78697f4 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-07-19 15:20:15 +02:00
Eric Espie
046e857768 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	core/config.class.inc.php
2023-07-19 15:19:06 +02:00
Eric Espie
4d8246c4d8 N°6436 - Integrate Performance Audit pre requisite in iTop Pro 2.7.9 (changed config variable name) 2023-07-19 15:13:43 +02:00
Eric Espie
5c61d725e1 N°6436 - Integrate Performance Audit pre requisite in iTop Pro 2.7.9 (changed config variable name) 2023-07-19 15:06:00 +02:00
Eric Espie
0c7195f1a3 Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	core/kpi.class.inc.php
2023-07-19 10:53:09 +02:00
Eric Espie
00b070b3cf Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	core/kpi.class.inc.php
2023-07-19 10:44:22 +02:00
Eric Espie
2c4cad4dac N°6436 - Integrate Performance Audit pre requisite in iTop Pro 2.7.9 (avoid unnecessary calls) 2023-07-19 10:37:41 +02:00
Eric Espie
9c37d5c23e Merge remote-tracking branch 'origin/support/3.0' into support/3.1
# Conflicts:
#	application/applicationextension.inc.php
#	application/cmdbabstract.class.inc.php
#	core/dbobject.class.php
#	core/kpi.class.inc.php
#	core/metamodel.class.php
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_static.php
#	tests/php-unit-tests/unitary-tests/setup/DBBackupTest.php
2023-07-19 09:26:46 +02:00
Stephen Abello
89145593ef N°6552 - Security hardening 2023-07-19 09:25:48 +02:00
Eric Espie
b2e80d37dd N°6436 - typo 2023-07-18 14:48:32 +02:00
Eric Espie
6432678de9 Merge remote-tracking branch 'origin/support/2.7' into support/3.0
# Conflicts:
#	application/cmdbabstract.class.inc.php
#	application/utils.inc.php
#	bootstrap.inc.php
#	composer.json
#	core/MyHelpers.class.inc.php
#	core/cmdbsource.class.inc.php
#	core/config.class.inc.php
#	core/dbobject.class.php
#	core/kpi.class.inc.php
#	core/metamodel.class.php
#	lib/composer/autoload_classmap.php
#	lib/composer/autoload_real.php
#	lib/composer/autoload_static.php
2023-07-18 14:36:58 +02:00
Pierre Goiffon
952194b385 N°6570 Fix BulkChangeExtKeyTest errors
- transaction started but never stopped
- invalid value label typo
- urlencode on search url
2023-07-18 14:12:29 +02:00
Pierre Goiffon
bfb452dd69 N°6570 Rename BulkChangeExtKeyTest file so it is run in Jenkins
Was *Test.inc.php instead of default *Test.php
2023-07-18 14:12:29 +02:00
Pierre Goiffon
64baeba1c7 Merge remote-tracking branch 'origin/support/3.0' into support/3.1 2023-07-18 09:49:03 +02:00
Molkobain
71ed784c60 N°6532 - Fix missing "/" in path
(cherry picked from commit 32fd75bc4b)
2023-07-18 09:40:34 +02:00
Eric Espie
da45651121 Merge branch 'feature/6548_Hide_DBHost_and_DBUser_in_log' into support/2.7 2023-07-18 09:34:48 +02:00
Eric Espie
d388ce9a06 Merge branch 'feature/6548_Hide_DBHost_and_DBUser_in_log' into support/2.7 2023-07-18 09:17:40 +02:00
Eric Espie
47e71d8838 Merge branch 'feature/6436-Integrate_Performance_Audit_extensibility' into support/2.7 2023-07-18 09:17:05 +02:00
Stephen Abello
2b5973ec67 N°6436 - Integrate Performance Audit pre requisite in iTop Pro 2.7.9 2023-07-18 09:15:37 +02:00
Benjamin Dalsass
e58918f53e N°6546 - AttributeLinkedSetIndirect filter dosen't work 2023-07-18 08:53:26 +02:00
Molkobain
125715af3f N°6562 - Temporarily disable XML conversion unit tests failing in PHP 8.2.8 2023-07-14 21:09:37 +02:00
Molkobain
ea8e7c5131 N°6562 - Temporarily disable XML conversion unit tests failing in PHP 8.1.21 2023-07-13 10:11:56 +02:00
Eric Espie
06e5e0b102 Merge branch 'support/3.1.0' into support/3.1 2023-07-12 13:31:34 +02:00
Eric Espie
df1cb0b6e3 N°6408 - CRUD : Fix log consuming too much memory 2023-07-12 11:21:32 +02:00
Pierre Goiffon
5247f5b3ea 🔖 Prepare version 3.1.1 2023-07-11 09:56:59 +02:00
Eric Espie
78396d8e4a 6548 - [ER] Hide DBHost and DBUser in log 2023-07-10 17:37:27 +02:00
Pierre Goiffon
f1ee22cbed Merge branch 'release/3.1.0' into develop 2023-07-10 16:57:23 +02:00
Molkobain
9b409b117f N°6043 - Booking: Move \TemporaryObjectDescriptor to /core to keep compatibility with legacy/custom packages
Cherry picked from 39305468
2023-07-10 13:16:53 +02:00
Molkobain
39305468f8 N°6043 - Booking: Move \TemporaryObjectDescriptor to /core to keep compatibility with legacy/custom packages 2023-07-10 12:25:32 +02:00
Molkobain
32fd75bc4b N°6532 - Fix missing "/" in path 2023-07-10 09:43:28 +02:00
Pierre Goiffon
efadf2cc79 Merge remote-tracking branch 'origin/support/3.0' into develop 2023-07-07 10:24:57 +02:00
Pierre Goiffon
40d63a2fa4 N°3663 💡 Fix depreciation comment in core/coreexception.class.inc.php 2023-07-07 10:24:15 +02:00
Pierre Goiffon
baa6dedbcf Merge remote-tracking branch 'origin/support/3.0' into develop 2023-07-07 09:32:14 +02:00
Pierre Goiffon
556b9ad89a N°6532 Fix "failed to open stream" error on require_once approot in coreexception.class.inc.php
Was occurring in TemplateFieldValueTest templates-base phpunit test
2023-07-07 09:31:34 +02:00
Stephen Abello
9afc22bd8f N°6123 - Add tests and comments 2023-07-07 09:29:15 +02:00
Pierre Goiffon
ef0b0f88c9 Merge remote-tracking branch 'origin/support/3.0' into develop
# Conflicts:
#	sources/Core/Email/EmailSwiftMailer.php
#	tests/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
#	tests/php-unit-tests/postbuild_integration.xml.dist
2023-07-06 17:11:10 +02:00
Pierre Goiffon
a010239efb Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-07-06 15:48:42 +02:00
Pierre Goiffon
264a8cd70a N°6494 - Some tests are run twice, some never
(cherry picked from commit a2a0b2cd0b)

(cherry picked from commit 4c9ea0c9d4)

# Conflicts:
#	tests/php-unit-tests/integration-tests/DictionariesConsistencyTest.php
2023-07-06 15:45:09 +02:00
Pierre Goiffon
a2a0b2cd0b N°6494 Fix missing PHPUnit log in console log for postbuild tests 2023-07-06 15:28:32 +02:00
Stephen Abello
aa1834170b N°6427 - Fix SwiftMailer not retrieving sendmail path 2023-07-06 14:31:54 +02:00
Stephen Abello
f94d67ab35 N°6340 - Fix permission refused when sending an email and renewing OAuth token in synchronous mode 2023-07-06 10:28:10 +02:00
Stephen Abello
3048c8c41f N°5560 - Display an error when trying to regenerate an expired OAuth token 2023-07-06 09:52:00 +02:00
Stephen Abello
246e4a9f50 N°6123 - Fix warnings when launching a backup on MariaDB > v10.6.1 with localhost dbhost 2023-07-06 09:28:01 +02:00
odain
4c9ea0c9d4 N°6494 - Some tests are run twice, some never 2023-07-05 14:37:02 +02:00
Benjamin Dalsass
e654daf4a5 N°6516 - Add @experimental PHP annotation on temporary objects features 2023-07-05 14:24:05 +02:00
Molkobain
8292b16387 N°6502 - Fix AttributeImage::GetAsHtml() using download URL instead of display URL which triggers download listeners 2023-07-05 10:35:36 +02:00
Molkobain
340b982d77 N°6502 - Avoid new history entry on AttributeBlob download 2023-07-05 10:35:35 +02:00
Stephen Abello
3e187282b0 N°6498 - Fix str_replace crashing with null value 2023-07-05 09:18:56 +02:00
Molkobain
722a4a2c4d Merge remote-tracking branch 'origin/support/3.0' into develop
# Conflicts:
#	js/jquery.ba-bbq.js
2023-07-05 08:59:47 +02:00
Molkobain
8907525b78 Merge remote-tracking branch 'origin/support/2.7' into support/3.0 2023-07-05 08:56:17 +02:00
Molkobain
6d58adb6dd N°6359 - Fix JS crash due to new version trying to detect MSIE browser through a dependency that we don't have.
Cherry-picked from f889c53d71
2023-07-05 08:41:00 +02:00
Benjamin Dalsass
03e7e0e79f N°6503 - Logs purge system delete index.php 2023-07-05 08:39:48 +02:00
Molkobain
83529da319 N°6500 - Fix user request approval freezing in the portal due to "Cannot read properties of undefined (reading 'validation')" 2023-07-04 21:36:34 +02:00
bdalsass
9d38b4d1d6 N°6043 - Booking: Add prerequisites in iTop core - CRUD extensibility (#520) 2023-07-04 16:22:53 +02:00
Stephen Abello
40dc3deabb N°6495 - Fix strlen crashing with null value in AttributePassword 2023-07-04 13:56:31 +02:00
Stephen Abello
56688fbbff Merge branch 'support/3.0' into develop 2023-07-03 14:30:20 +02:00
Stephen Abello
764a170cd0 N°6483 - Security hardening 2023-07-03 14:29:45 +02:00
Stephen Abello
c30da57818 N°6488 - Fix object keyboard shortcut not working anymore due to summary cards stealing its shortcuts 2023-07-03 11:50:12 +02:00
Pierre Goiffon
e36b9eb664 N°6414 Make AbstractSimpleField::Validate final
We don't have any overrides remaining anymore
2023-07-03 11:30:04 +02:00
Pierre Goiffon
6cc2d49cd5 N°6414 Move existing AbstractSimpleField::Validate impl to custom validators
- LinkedSetField
- SelectObjectField
- MultipleChoicesField (warning this hierarchy contains non multiple value fields like SelectField !)

Also change AbstractValidator::Validate signature : now we are returning an array of error messages, so that we can return multiple ones
2023-07-03 11:30:04 +02:00
Pierre Goiffon
d085f15b6d N°6414 Separate SubFormField and Scalar fields
This will help to set methods as final, as SubFormField is often the sole one to have a real custom impl
2023-07-03 11:30:04 +02:00
Pierre Goiffon
6606af71ff N°6414 Validator refactoring
New AbstractValidator class, with new method Validate
All existing validators are now children of AbstractRegexpValidator
Handle validators JS counterparts in renderers : only regexp validators are implemented client side
2023-07-03 11:30:04 +02:00
Pierre Goiffon
52049b7837 N°6414 Disable Field validation for untouched attcodes 2023-07-03 11:30:04 +02:00
Pierre Goiffon
f40674ec85 N°6414 Replace SelectObjectField::VerifyCurrentValue by ResetCurrentValueIfNotAmongAllowedValues 2023-07-03 11:30:04 +02:00
bdalsass
b46d4db8ff N°6476 - Revert datamodel / compiler changes from N°5563 (#515) 2023-06-29 15:11:30 +02:00
Molkobain
12dbd0ed3d N°6482 - Fix URP_UserProfile classes not flagged as link classes so they can benefit of the same mechanisms (eg. events) 2023-06-29 09:59:09 +02:00
Lars Kaltefleiter
0d9f33ec4c 🌐 Updated german translations for 3.1 (#511) 2023-06-29 09:05:27 +02:00
Molkobain
71704404d0 N°5945 - Apply same explicit value comparison as previous commit 2023-06-28 10:19:07 +02:00
Molkobain
3c8bea8921 N°5945 - Fix "menu" option in dashlet list having no effect since relations refactoring 2023-06-28 10:11:51 +02:00
Molkobain
b755f65a8a Improve PHPDoc 2023-06-27 23:35:57 +02:00
Molkobain
3bd3081359 Merge remote-tracking branch 'origin/support/3.0' into develop
# Conflicts:
#	synchro/synchro_exec.php
2023-06-27 18:19:48 +02:00
Molkobain
5a33fb7a6a N°6474 - Fix regression introduced by 70e6f707 2023-06-27 18:16:55 +02:00
Stephen Abello
29a90fe244 N°6474 - Fix undefined variable due to failed merge + refactoring 2023-06-27 16:55:25 +02:00
Molkobain
011116029b N°6478 - Add "edit_mode" node for AttributeLinkedSetIndirect (n:n) for future usages 2023-06-27 16:41:01 +02:00
Eric Espie
f95cb50002 N°6442 - comment 2023-06-27 15:49:39 +02:00
Eric Espie
2c8db92504 N°6442 - Error in Database integrity due to "translate placeholder in notification" 2023-06-27 15:23:28 +02:00
Eric Espie
98d4fa4331 N°6384 - fix typo 2023-06-27 14:13:33 +02:00
Anne-Catherine
4a39a5e51d N°6342 - Fix empty list when configuring a list adding a log attribute (#498)
* N°6342 - Empty list when configuring a list adding a case log attribute

* Update js/dataTables.settings.js

---------

Co-authored-by: Molkobain <lajarige.guillaume@free.fr>
2023-06-27 13:45:04 +02:00
Eric Espie
8373a03d82 N°6408 - CRUD fix tests 2023-06-27 12:11:36 +02:00
Eric Espie
befbe2dfa9 N°6408 - CRUD fix tests 2023-06-27 11:52:23 +02:00
Eric Espie
86ca7fcb7a N°6408 - CRUD : rework on DBUpdate reentrancy 2023-06-27 11:37:10 +02:00
Stephen Abello
ccf1d7ecfb N°6446 Fix OAuth landing page missing jQuery library needed in ajax calls 2023-06-27 11:24:06 +02:00
Stephen Abello
178e82a039 N°6446 Replace jQuery with vanilla JS in ajax dictionaries 2023-06-27 11:24:06 +02:00
Stephen Abello
452cc77168 N°6446 Prevent loaded js file constant from being missing if an ajax call is made from a page that's not a Webpage 2023-06-27 11:24:05 +02:00
Molkobain
7fc46fbc50 N°6472 - Fix empty tables in "Progress" tab of a survey 2023-06-27 10:36:30 +02:00
Benjamin Dalsass
f338d3bdc8 N°6326 - Magnifier pop-up search from ExtKey in Link edit in pop-up, fails 2023-06-27 09:42:12 +02:00
Benjamin Dalsass
d41e54bf34 N°6473 - Do not track QueryOQL statistic values 2023-06-27 08:42:44 +02:00
Eric Espie
aa75456e6e N°6271 - Fix drop-down list not refreshed when adding an external key with a friendlyname built on an external key 2023-06-27 08:41:20 +02:00
Eric Espie
db6e4137b1 N°6271 - Fix drop-down list not refreshed when adding an external key with a friendlyname built on an external key 2023-06-26 18:00:04 +02:00
Benjamin Dalsass
a206af1813 N°6005 - CSV import : import an object and a linkset fails
- Restore old get as html for linked set with display style tab
2023-06-26 15:11:41 +02:00
Eric Espie
77868e356b N°6408 - CRUD : Issue on DBlinkchange event when delete et create 2023-06-26 11:34:00 +02:00
Eric Espie
60e302162c N°6408 - CRUD : Issue on DBlinkchange event when delete et create 2023-06-26 11:31:53 +02:00
Eric Espie
f36c8c5cdd N°6408 - CRUD : Issue on DBlinkchange event when delete et create 2023-06-26 11:17:20 +02:00
Molkobain
d062ba8196 N°6456 - Code convention 2023-06-24 11:49:43 +02:00
Eric Espie
c3469e43bc N°6408 - Add logs, changed modification test of current object and prevent calling OnDBUpdate() when object is not modified 2023-06-23 17:02:31 +02:00
acognet
68ee12bf5e N°6456 - Empty list when configuring a list and cancel 2023-06-23 09:35:42 +02:00
Purple Grape
47400d94ba N°6468 update zh-cn dict (#512) 2023-06-23 09:03:49 +02:00
Molkobain
b642dbe3d6 N°6389 - Fix SQL error when saving an object with an emptied blob attribute 2023-06-22 20:43:56 +02:00
Molkobain
83564849e0 N°6356 - Search, SELECT on class with a single field display the count and an empty list 2023-06-22 20:18:18 +02:00
Molkobain
3e73038709 N°6380 - Fix exception "Failed to parse time string" with check_backup.php script 2023-06-22 13:51:01 +02:00
vdumas
dcfefc1588 N°1350 - Audit domains: add uniqueness rule on n:n with Category 2023-06-22 11:19:53 +02:00
vdumas
4db092ea52 N°6370 - Replace Audit Category menu by a dashboard only in module 2023-06-22 11:05:01 +02:00
Molkobain
96f1bd3646 N°6462 - Sort \AttributeApplicationLanguage alphabetically (eg. "Language" in ActionEmail class) 2023-06-21 18:33:12 +02:00
Molkobain
f889c53d71 N°6359 - Fix JS crash due to new version trying to detect MSIE browser through a dependency that we don't have.
It's far from perfect but as mentioned in the previous commit, we don't have much choices for now
2023-06-21 17:21:40 +02:00
Molkobain
814916fb21 N°6362 - Fix export of linkset tab not working due to JS error 2023-06-21 17:04:55 +02:00
Eric Espie
9e667c968e N°6408 - CRUD : Issue on DBlinkchange event when delete et create 2023-06-21 16:41:54 +02:00
Molkobain
a8a3385969 N°6460 - Sort \AttributeClassAttCodeSet alphabetically (eg. "Target fields" in Trigger class) 2023-06-21 16:06:22 +02:00
Molkobain
87e04547bd N°6448 - Restore sort order for \AttributeClass and \AttributeSetEnumPadded (eg. "Target class" and "Context" in DataSynchronisation and Trigger classes) 2023-06-21 15:58:11 +02:00
Eric Espie
6fe41796d9 N°5909 - Fix iApplicationExtension not called when attachment is added 2023-06-21 15:15:59 +02:00
Eric Espie
99a4e5e861 N°5909 - Fix iApplicationExtension not called when attachment is added 2023-06-21 14:39:04 +02:00
Molkobain
3d3a751072 N°6200 - Delete old redundant turkish dict file 2023-06-21 13:13:57 +02:00
Molkobain
216a1b95b1 N°6405 - Fix XML displayed corrupted when using \DesignerLongTextField due to usage of \utils::EscapeHtml() without double encoding 2023-06-21 11:33:18 +02:00
Benjamin Dalsass
2074a0fa0d N°5305 - CSV import ergonomy for SaaS
- Fix ext key displayable value
2023-06-21 11:21:40 +02:00
Eric Espie
bfd078c2a3 N°6281 - Rest API core/create key value is no more between quote 2023-06-20 17:25:13 +02:00
Benjamin Dalsass
85a879b587 N°5305 - CSV import ergonomy for SaaS
- Change checkbox error ugly font
- Improve errors messages (ambiguous, mismatch)
2023-06-20 17:21:39 +02:00
Eric Espie
9b9ba3c440 N°6281 - Rest API core/create key value is no more between quote 2023-06-20 16:58:16 +02:00
bdalsass
4d43d83b95 N°6000 - CSV Import with quote no more handled (#508) 2023-06-20 16:39:56 +02:00
Benjamin Dalsass
63487226a9 Merge remote-tracking branch 'origin/support/3.0' into develop
# Conflicts:
#	core/csvbulkexport.class.inc.php
2023-06-20 10:24:03 +02:00
vdumas
7b5ef52865 N°6422 - Improve french dictionary 2023-06-20 08:37:17 +02:00
Molkobain
4550dfb1d4 N°5388 - PHP 8.2: Fix dynamic property declaration 2023-06-19 16:27:45 +02:00
Molkobain
1a5ffc23ce N°6251 - Fix dynamic property declaration 2023-06-19 14:47:06 +02:00
vdumas
3a9198bf1c N°6422 - Finalize french dictionaries 2023-06-16 16:39:05 +02:00
vdumas
2242a80808 N°6428 - Portal : Hide role attribute in linkset Contact/Ticket 2023-06-16 16:19:04 +02:00
Benjamin Dalsass
86148ecf57 N°6415 - Linked set shown as tag set in csv import is ugly 2023-06-16 16:06:35 +02:00
Benjamin Dalsass
2c4a7c5a77 # Conflicts:
#	core/csvbulkexport.class.inc.php
2023-06-16 15:57:58 +02:00
Benjamin Dalsass
2cca57c7fa N°6431 - CSV bulk export text delimiter option not initialized correctly 2023-06-16 15:50:28 +02:00
Timothee
e52fa28089 Merge remote-tracking branch 'origin/release/3.1.0-beta' into develop 2023-06-16 15:21:51 +02:00
odain
0001e8ffc4 💚 use new ci validation 2020-10-09 10:13:51 +02:00
364 changed files with 10078 additions and 4618 deletions

View File

@@ -62,6 +62,12 @@ gitGraph
commit id: "2022-12-28" tag: "2.7.8"
checkout support/3.0
commit id: "2023-04-12" tag: "3.0.3"
checkout develop
commit id: "2023-06-19" tag: "3.1.0-beta" type: REVERSE
commit id: "2023-07-26" tag: "3.1.0-1" type: HIGHLIGHT
branch support/3.1 order: 840
checkout support/3.1
commit id: "2023-08-09" tag: "3.1.0-2"
```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

View File

@@ -228,6 +228,7 @@ class URP_UserProfile extends UserRightsBaseClassGUI
"db_table" => "priv_urp_userprofile",
"db_key_field" => "id",
"db_finalclass_field" => "",
"is_link" => true, /** @since 3.1.0 N°6482 */
'uniqueness_rules' => array(
'no_duplicate' => array(
'attributes' => array(

View File

@@ -334,6 +334,7 @@ class URP_UserProfile extends UserRightsBaseClassGUI
"db_table" => "priv_urp_userprofile",
"db_key_field" => "id",
"db_finalclass_field" => "",
"is_link" => true, /** @since 3.1.0 N°6482 */
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();

View File

@@ -277,6 +277,7 @@ class URP_UserProfile extends UserRightsBaseClass
"db_table" => "priv_urp_userprofile",
"db_key_field" => "id",
"db_finalclass_field" => "",
"is_link" => true, /** @since 3.1.0 N°6482 */
);
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();

View File

@@ -238,7 +238,7 @@ class ApplicationContext
{
$aContextInputBlocks = [];
foreach ($this->aValues as $sName => $sValue) {
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", utils::EscapeHtml($sValue));
$aContextInputBlocks[] = InputUIBlockFactory::MakeForHidden("c[$sName]", $sValue);
}
return $aContextInputBlocks;
}

View File

@@ -2246,3 +2246,27 @@ interface iModuleExtension
*/
public function __construct();
}
/**
* KPI logging extensibility point
*
* KPI Logger extension
*/
interface iKPILoggerExtension
{
/**
* Init the statistics collected
*
* @return void
*/
public function InitStats();
/**
* Add a new KPI to the stats
*
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKpiLogData
*
* @return mixed
*/
public function LogOperation($oKpiLogData);
}

View File

@@ -34,15 +34,15 @@ class AuditCategory extends cmdbAbstractObject
{
$aParams = array
(
"category" => "application, grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",
"reconc_keys" => array('name'),
"db_table" => "priv_auditcategory",
"db_key_field" => "id",
"category" => "application,grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",
"reconc_keys" => array('name'),
"db_table" => "priv_auditcategory",
"db_key_field" => "id",
"db_finalclass_field" => "",
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
);
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));

View File

@@ -35,7 +35,7 @@ class AuditDomain extends cmdbAbstractObject
{
$aParams = array
(
"category" => "application, grant_by_profile",
"category" => "application,grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "name",
"complementary_name_attcode" => array('description'),
@@ -86,15 +86,26 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
{
$aParams = array
(
"category" => "application, grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array('category_id', 'domain_id'),
"db_table" => "priv_link_audit_category_domain",
"db_key_field" => "id",
"category" => "application, grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array('category_id', 'domain_id'),
"db_table" => "priv_link_audit_category_domain",
"db_key_field" => "id",
"db_finalclass_field" => "",
"is_link" => true,
"is_link" => true,
'uniqueness_rules' => array(
'no_duplicate' => array(
'attributes' => array(
0 => 'category_id',
1 => 'domain_id',
),
'filter' => '',
'disabled' => false,
'is_blocking' => true,
),
),
);
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));

View File

@@ -35,7 +35,7 @@ class AuditRule extends cmdbAbstractObject
{
$aParams = array
(
"category" => "application, grant_by_profile",
"category" => "application,grant_by_profile",
"key_type" => "autoincrement",
"name_attcode" => "name",
"state_attcode" => "",

View File

@@ -47,6 +47,7 @@ use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
use Combodo\iTop\Service\Links\LinkSetDataTransformer;
use Combodo\iTop\Service\Links\LinkSetModel;
use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectHelper;
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
@@ -187,9 +188,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
/** @var array initial attributes flags cache [attcode]['flags'] */
protected $aInitialAttributesFlags;
protected $iUpdateLoopCount;
const MAX_UPDATE_LOOP_COUNT = 10;
/**
* @var array First level classname, second level id, value number of calls done
@@ -227,7 +225,6 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
$this->sDisplayMode = static::DEFAULT_DISPLAY_MODE;
$this->bAllowWrite = false;
$this->bAllowDelete = false;
$this->iUpdateLoopCount = 0;
}
/**
@@ -1169,7 +1166,7 @@ HTML
/**
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams
* @param array $aExtraParams See possible values in {@see DataTableUIBlockFactory::RenderDataTable()}
*
* @throws \ApplicationException
* @throws \CoreException
@@ -2822,33 +2819,33 @@ JS
}
}
// Custom operation for the form ?
if (isset($aExtraParams['custom_operation'])) {
$sOperation = $aExtraParams['custom_operation'];
} else {
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
$sOperation = 'apply_modify';
} else {
$sOperation = 'apply_new';
}
}
if (isset($aExtraParams['custom_operation'])) {
$sOperation = $aExtraParams['custom_operation'];
} else {
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
$sOperation = 'apply_modify';
} else {
$sOperation = 'apply_new';
}
}
$oContentBlock = new UIContentBlock();
$oPage->AddUiBlock($oContentBlock);
$oContentBlock = new UIContentBlock();
$oPage->AddUiBlock($oContentBlock);
$oForm = new Form("form_{$this->m_iFormId}");
$oForm->SetAction($sFormAction);
$sOnSubmitForm = "let bOnSubmitForm = OnSubmit('form_{$this->m_iFormId}');";
if (isset($aExtraParams['js_handlers']['form_on_submit'])) {
$oForm->SetOnSubmitJsCode($sOnSubmitForm.$aExtraParams['js_handlers']['form_on_submit']);
} else {
$oForm->SetOnSubmitJsCode($sOnSubmitForm."return bOnSubmitForm;");
}
$oContentBlock->AddSubBlock($oForm);
$oForm = new Form("form_{$this->m_iFormId}");
$oForm->SetAction($sFormAction);
$sOnSubmitForm = "let bOnSubmitForm = OnSubmit('form_{$this->m_iFormId}');";
if (isset($aExtraParams['js_handlers']['form_on_submit'])) {
$oForm->SetOnSubmitJsCode($sOnSubmitForm . $aExtraParams['js_handlers']['form_on_submit']);
} else {
$oForm->SetOnSubmitJsCode($sOnSubmitForm . "return bOnSubmitForm;");
}
$oContentBlock->AddSubBlock($oForm);
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
// The object already exists in the database, it's a modification
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('id', $iKey, "{$sPrefix}_id"));
}
if ($this->GetDisplayMode() === static::ENUM_DISPLAY_MODE_EDIT) {
// The object already exists in the database, it's a modification
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('id', $iKey, "{$sPrefix}_id"));
}
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('operation', $sOperation));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('class', $sClass));
@@ -2857,6 +2854,11 @@ JS
$oPage->SetTransactionId($iTransactionId);
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', $iTransactionId));
// Add temporary object watchdog (only on root form)
if (!utils::IsXmlHttpRequest()) {
$oPage->add_ready_script(TemporaryObjectHelper::GetWatchDogJS($iTransactionId));
}
// TODO 3.0.0: Is this (the if condition, not the code inside) still necessary?
if (isset($aExtraParams['wizard_container']) && $aExtraParams['wizard_container']) {
$sClassLabel = MetaModel::GetName($sClass);
@@ -2867,34 +2869,34 @@ JS
}
}
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
$oCancelButton = ButtonUIBlockFactory::MakeForCancel();
$oCancelButton->AddCSSClasses(['action', 'cancel']);
$oToolbarButtons->AddSubBlock($oCancelButton);
$oApplyButton = ButtonUIBlockFactory::MakeForPrimaryAction($sApplyButton, null, null, true);
$oApplyButton->AddCSSClass('action');
$oToolbarButtons->AddSubBlock($oApplyButton);
$bAreTransitionsHidden = isset($aExtraParams['hide_transitions']) && $aExtraParams['hide_transitions'] === true;
$aTransitions = $this->EnumTransitions();
if (!isset($aExtraParams['custom_operation']) && !$bAreTransitionsHidden && count($aTransitions)) {
// Transitions are displayed only for the standard new/modify actions, not for modify_all or any other case...
$oSetToCheckRights = DBObjectSet::FromObject($this);
$oCancelButton = ButtonUIBlockFactory::MakeForCancel();
$oCancelButton->AddCSSClasses(['action', 'cancel']);
$oToolbarButtons->AddSubBlock($oCancelButton);
$oApplyButton = ButtonUIBlockFactory::MakeForPrimaryAction($sApplyButton, null, null, true);
$oApplyButton->AddCSSClass('action');
$oToolbarButtons->AddSubBlock($oApplyButton);
$bAreTransitionsHidden = isset($aExtraParams['hide_transitions']) && $aExtraParams['hide_transitions'] === true;
$aTransitions = $this->EnumTransitions();
if (!isset($aExtraParams['custom_operation']) && !$bAreTransitionsHidden && count($aTransitions)) {
// Transitions are displayed only for the standard new/modify actions, not for modify_all or any other case...
$oSetToCheckRights = DBObjectSet::FromObject($this);
$oTransitionPopoverMenu = new PopoverMenu();
$sTPMSectionId = 'transitions';
$oTransitionPopoverMenu->AddSection($sTPMSectionId);
$aStimuli = Metamodel::EnumStimuli($sClass);
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass,
$sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO;
switch ($iActionAllowed) {
case UR_ALLOWED_YES:
// Button to be displayed on its own on large screens
$oButton = ButtonUIBlockFactory::MakeForPrimaryAction($aStimuli[$sStimulusCode]->GetLabel(), 'next_action', $sStimulusCode, true);
$oButton->AddCSSClass('action');
$oButton->SetColor(Button::ENUM_COLOR_SCHEME_NEUTRAL);
$oToolbarButtons->AddSubBlock($oButton);
$oTransitionPopoverMenu = new PopoverMenu();
$sTPMSectionId = 'transitions';
$oTransitionPopoverMenu->AddSection($sTPMSectionId);
$aStimuli = Metamodel::EnumStimuli($sClass);
foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
$iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass,
$sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO;
switch ($iActionAllowed) {
case UR_ALLOWED_YES:
// Button to be displayed on its own on large screens
$oButton = ButtonUIBlockFactory::MakeForPrimaryAction($aStimuli[$sStimulusCode]->GetLabel(), 'next_action', $sStimulusCode, true);
$oButton->AddCSSClass('action');
$oButton->SetColor(Button::ENUM_COLOR_SCHEME_NEUTRAL);
$oToolbarButtons->AddSubBlock($oButton);
// Button to be displayed in a grouped button on smaller screens
$oTPMPopupMenuItem = new JSPopupMenuItem('next_action--'.$oButton->GetId(), $oButton->GetLabel(), "$(`#{$oButton->GetId()}`).trigger(`click`);");
@@ -3049,16 +3051,21 @@ JS
$oPage->SetCurrentTab('');
// Static fields values for wizard helper serialization
$aWizardHelperStaticValues = [];
// Add as hidden inputs values that we want displayed if they're readonly
if(isset($aExtraParams['forceFieldsSubmission'])){
$aExtraFlags = $aExtraParams['fieldsFlags'] ?? [];
foreach ($aExtraParams['forceFieldsSubmission'] as $sAttCode) {
if(FormHelper::GetAttributeFlagsForObject($this, $sAttCode, $aExtraFlags) & OPT_ATT_READONLY) {
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('attr_'.$sPrefix.$sAttCode, $this->Get($sAttCode)));
$aWizardHelperStaticValues[$sAttCode] = $this->Get($sAttCode);
}
}
}
$sWizardHelperStaticValues = json_encode($aWizardHelperStaticValues);
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('class', $sClass));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', $iTransactionId));
foreach ($aExtraParams as $sName => $value) {
@@ -3101,6 +3108,7 @@ JS
var oWizardHelper$sPrefix = new WizardHelper('$sClass', '$sPrefix', '$sLifecycleStateForWizardHelper');
oWizardHelper$sPrefix.SetFieldsMap($sJsonFieldsMap);
oWizardHelper$sPrefix.SetFieldsCount($iFieldsCount);
oWizardHelper$sPrefix.SetStaticValues($sWizardHelperStaticValues);
EOF
);
$oPage->add_ready_script(
@@ -4513,16 +4521,12 @@ HTML;
*/
public function DBInsertNoReload()
{
$this->LogCRUDEnter(__METHOD__);
try {
$res = parent::DBInsertNoReload();
$this->SetWarningsAsSessionMessages('create');
// Invoke extensions after insertion (the object must exist, have an id, etc.)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance) {
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
}
} finally {
if (static::IsCrudStackEmpty()) {
// Avoid signaling the current object that links were modified
@@ -4530,9 +4534,25 @@ HTML;
static::FireEventDbLinksChangedForAllObjects();
}
}
$this->LogCRUDExit(__METHOD__);
return $res;
}
public function PostInsertActions(): void
{
parent::PostInsertActions();
// Invoke extensions after insertion (the object must exist, have an id, etc.)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBInsert()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
}
}
/**
* @inheritdoc
* Attaches InlineImages to the current object
@@ -4544,13 +4564,16 @@ HTML;
protected function DBCloneTracked_Internal($newKey = null)
{
$oNewObj = parent::DBCloneTracked_Internal($newKey);
/** @var cmdbAbstractObject $oNewObj */
$oNewObj = MetaModel::GetObject(get_class($this), parent::DBCloneTracked_Internal($newKey));
// Invoke extensions after insertion (the object must exist, have an id, etc.)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBInsert($oNewObj, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
}
return $oNewObj;
@@ -4558,57 +4581,41 @@ HTML;
public function DBUpdate()
{
$this->LogCRUDEnter(__METHOD__);
try {
if (count($this->ListChanges()) === 0) {
$this->LogCRUDExit(__METHOD__);
return $this->GetKey();
}
$res = parent::DBUpdate();
$this->SetWarningsAsSessionMessages('update');
// Protection against reentrance (e.g. cascading the update of ticket logs)
// Note: This is based on the fix made on r 3190 in DBObject::DBUpdate()
if (!MetaModel::StartReentranceProtection($this)) {
$sClass = get_class($this);
$sKey = $this->GetKey();
IssueLog::Debug("CRUD: DBUpdate $sClass::$sKey Rejected (reentrance)", LogChannels::DM_CRUD);
return $res;
}
try {
// Invoke extensions after the update (could be before)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance) {
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
}
}
finally {
MetaModel::StopReentranceProtection($this);
}
$aChanges = $this->ListChanges();
if (count($aChanges) != 0) {
$this->iUpdateLoopCount++;
if ($this->iUpdateLoopCount > self::MAX_UPDATE_LOOP_COUNT) {
$sClass = get_class($this);
$sKey = $this->GetKey();
$aPlugins = [];
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance) {
$aPlugins[] = get_class($oExtensionInstance);
}
$sPlugins = implode(', ', $aPlugins);
IssueLog::Error("CRUD: DBUpdate $sClass::$sKey Update loop detected plugins: $sPlugins", LogChannels::DM_CRUD);
} else {
return $this->DBUpdate();
}
}
} finally {
if (static::IsCrudStackEmpty()) {
static::FireEventDbLinksChangedForAllObjects();
}
}
$this->LogCRUDExit(__METHOD__);
return $res;
}
public function PostUpdateActions(array $aChanges): void
{
parent::PostUpdateActions($aChanges);
// Invoke extensions after the update (could be before)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBUpdate()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBUpdate');
}
}
/**
* @param string $sMessageIdPrefix
*
@@ -4628,6 +4635,7 @@ HTML;
public function DBDelete(&$oDeletionPlan = null)
{
$this->LogCRUDEnter(__METHOD__);
try {
parent::DBDelete($oDeletionPlan);
} finally {
@@ -4637,6 +4645,7 @@ HTML;
static::FireEventDbLinksChangedForAllObjects();
}
}
$this->LogCRUDExit(__METHOD__);
return $oDeletionPlan;
}
@@ -4647,7 +4656,9 @@ HTML;
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBDelete');
}
return parent::DBDeleteTracked_Internal($oDeletionPlan);
@@ -4665,9 +4676,15 @@ HTML;
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
if ($oExtensionInstance->OnIsModified($this))
{
$sExtensionClass = get_class($oExtensionInstance);
$oKPI = new ExecutionKPI();
$bIsModified = $oExtensionInstance->OnIsModified($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnIsModified');
if ($bIsModified) {
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> true");
return true;
} else {
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> false");
}
}
@@ -4719,7 +4736,9 @@ HTML;
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$oKPI = new ExecutionKPI();
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToWrite');
if (is_array($aNewIssues) && (count($aNewIssues) > 0)) // Some extensions return null instead of an empty array
{
$this->m_aCheckIssues = array_merge($this->m_aCheckIssues, $aNewIssues);
@@ -4767,7 +4786,9 @@ HTML;
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$oKPI = new ExecutionKPI();
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToDelete');
if (is_array($aNewIssues) && count($aNewIssues) > 0)
{
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
@@ -6021,14 +6042,16 @@ JS
// - we have a EVENT_DB_LINKS_CHANGED listener on Ticket that will update impacted items, so it will create new lnkApplicationSolutionToFunctionalCI
// We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
// By disabling the event to be fired, we can remove the current object from the attribute !
/** @noinspection PhpRedundantOptionalArgumentInspection */
$oObject = MetaModel::GetObject($sClass, $sId, true);
self::SetEventDBLinksChangedBlocked(true);
MetaModel::StartReentranceProtection($oObject);
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
MetaModel::StopReentranceProtection($oObject);
if ($oObject->IsModified()) {
$oObject->DBUpdate();
$oObject = MetaModel::GetObject($sClass, $sId, false);
// N°6408 The object can have been deleted
if (!is_null($oObject)) {
self::SetEventDBLinksChangedBlocked(true);
MetaModel::StartReentranceProtection($oObject);
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
MetaModel::StopReentranceProtection($oObject);
if (count($oObject->ListChanges()) !== 0) {
$oObject->DBUpdate();
}
}
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);

View File

@@ -918,6 +918,11 @@ class RuntimeDashboard extends Dashboard
{
$bCustomized = false;
$sDashboardFileSanitized = utils::RealPath($sDashboardFile, APPROOT);
if (false === $sDashboardFileSanitized) {
throw new SecurityException('Invalid dashboard file !');
}
// Search for an eventual user defined dashboard
$oUDSearch = new DBObjectSearch('UserDashboard');
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
@@ -929,7 +934,7 @@ class RuntimeDashboard extends Dashboard
$sDashboardDefinition = $oUserDashboard->Get('contents');
$bCustomized = true;
} else {
$sDashboardDefinition = @file_get_contents($sDashboardFile);
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
}
@@ -937,7 +942,7 @@ class RuntimeDashboard extends Dashboard
$oDashboard = new RuntimeDashboard($sDashBoardId);
$oDashboard->FromXml($sDashboardDefinition);
$oDashboard->SetCustomFlag($bCustomized);
$oDashboard->SetDefinitionFile($sDashboardFile);
$oDashboard->SetDefinitionFile($sDashboardFileSanitized);
} else {
$oDashboard = null;
}

View File

@@ -667,7 +667,7 @@ class DashletUnknown extends Dashlet
*/
public function GetPropertiesFields(DesignerForm $oForm)
{
$oField = new DesignerLongTextField('xml', Dict::S('UI:DashletUnknown:Prop-XMLConfiguration'), $this->sOriginalDashletXML);
$oField = new DesignerXMLField('xml', Dict::S('UI:DashletUnknown:Prop-XMLConfiguration'), $this->sOriginalDashletXML);
$oForm->AddField($oField);
}

View File

@@ -100,20 +100,11 @@
<enable_class>URP_Profiles</enable_class>
<enable_action>UR_ACTION_MODIFY</enable_action>
</menu>
<menu id="AuditCategories" xsi:type="DashboardMenuNode" _delta="define">
<menu id="AuditCategories" xsi:type="OQLMenuNode" _delta="define">
<rank>20</rank>
<parent>AdminTools</parent>
<definition>
<layout>DashboardLayoutOneCol</layout>
<title>Menu:WelcomeMenuPage</title>
<cells>
<cell id="0">
<rank>0</rank>
<dashlets>
</dashlets>
</cell>
</cells>
</definition>
<oql><![CDATA[SELECT AuditCategory]]></oql>
<do_search>1</do_search>
<enable_class>AuditCategory</enable_class>
<enable_action>UR_ACTION_MODIFY</enable_action>
</menu>

View File

@@ -1246,6 +1246,10 @@ JS
} else {
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
}
$sClassDescription = MetaModel::GetClassDescription($sClass);
if (utils::IsNotNullOrEmptyString($sClassDescription)) {
$oBlock->SetClassDescription($sClassDescription);
}
return $oBlock;
}
@@ -1871,7 +1875,13 @@ class MenuBlock extends DisplayBlock
/** @var array $aToolkitActions Any "legacy" toolkit menu item, which are now displayed in the same menu as the $aRegularActions, after them */
$aToolkitActions = [];
if (!isset($aExtraParams['selection_mode']) || ($aExtraParams['selection_mode'] == "")) {
// Display menu actions only if...
if (
// ... NOT in a selection mode
(!isset($aExtraParams['selection_mode']) || ($aExtraParams['selection_mode'] == ""))
// ... "menu" parameter is NOT EXPLICITLY disabled
&& (!isset($aExtraParams['menu']) || $aExtraParams['menu'] === "1" || $aExtraParams['menu'] === true)
) {
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink();
if (utils::IsNotNullOrEmptyString($sContext)) {

View File

@@ -1110,13 +1110,41 @@ $('#$sId').on('change keyup validate', function() { ValidateWithPattern('$sId',
}
EOF
);
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".utils::EscapeHtml($this->defaultValue)."</textarea>";
$sValue = "<textarea $sCSSClasses id=\"$sId\" name=\"$sName\">".$this->PrepareValueForRendering()."</textarea>";
}
else {
$sValue = "<div $sCSSClasses id=\"$sId\">".utils::EscapeHtml($this->defaultValue)."</div>";
$sValue = "<div $sCSSClasses id=\"$sId\">".$this->PrepareValueForRendering()."</div>";
}
return array('label' => $this->sLabel, 'value' => $sValue);
}
/**
* @return string|null The value itself as expected for rendering. May it be encoded, escaped or else.
* @since 3.1.0 N°6405
*/
protected function PrepareValueForRendering(): ?string
{
return utils::EscapeHtml($this->defaultValue);
}
}
/**
* Class DesignerXMLField
*
* Field to display XML content
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @since 3.1.0 N°6405
*/
class DesignerXMLField extends DesignerLongTextField
{
/**
* @inheritDoc
*/
protected function PrepareValueForRendering(): ?string
{
return utils::EscapeHtml($this->defaultValue, true);
}
}
class DesignerIntegerField extends DesignerFormField

View File

@@ -74,6 +74,7 @@ abstract class Query extends cmdbAbstractObject
"default_value" => 0,
"is_null_allowed" => false,
"depends_on" => array(),
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
)));
MetaModel::Init_AddAttribute(new AttributeDateTime("export_last_date", array(
@@ -82,6 +83,7 @@ abstract class Query extends cmdbAbstractObject
"default_value" => null,
"is_null_allowed" => true,
"depends_on" => array(),
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
)));
MetaModel::Init_AddAttribute(new AttributeExternalKey("export_last_user_id",
@@ -93,14 +95,16 @@ abstract class Query extends cmdbAbstractObject
"depends_on"=>array(),
"display_style"=>'select',
"always_load_in_tables"=>false,
"on_target_delete"=>DEL_SILENT
"on_target_delete"=>DEL_SILENT,
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
)));
MetaModel::Init_AddAttribute(new AttributeExternalField("export_last_user_contact",
array(
"allowed_values"=>null,
"extkey_attcode"=> "export_last_user_id",
"target_attcode"=>"contactid"
"target_attcode"=>"contactid",
"tracking_level" => ATTRIBUTE_TRACKING_NONE,
)));
// Display lists
@@ -292,7 +296,7 @@ class QueryOQL extends Query
}
catch
(OQLException $e) {
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::Format('UI:RunQuery:Error'), $e->getHtmlDesc())
$oAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:RunQuery:Error'), $e->getHtmlDesc())
->SetIsClosable(false)
->SetIsCollapsible(false);
$oAlert->AddCSSClass('mb-5');

View File

@@ -99,4 +99,10 @@ else
Session::Set('itop_env', ITOP_DEFAULT_ENV);
}
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
try {
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
}
catch (MySQLException $e) {
IssueLog::Debug($e->getMessage());
throw new MySQLException('Could not connect to the DB server', []);
}

View File

@@ -168,8 +168,6 @@ class UIExtKeyWidget
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
if ($this->bSearchMode) {
$sWizHelper = 'null';
@@ -1070,18 +1068,27 @@ JS
{
$oObj = MetaModel::NewObject($this->sTargetClass);
$aErrors = $oObj->UpdateObjectFromPostedForm($this->iId);
if (count($aErrors) == 0)
{
$oObj->DBInsert();
if (count($aErrors) == 0) {
// Retrieve JSON data
$sJSON = utils::ReadParam('json', '{}', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$oJSON = json_decode($sJSON);
$oObj->SetContextSection('temporary_objects', [
'create' => [
'transaction_id' => utils::ReadParam('root_transaction_id', '', false, utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID),
'host_class' => $oJSON->m_sClass,
'host_att_code' => $this->sAttCode,
],
]);
$oObj->DBInsertNoReload();
return array('name' => $oObj->GetName(), 'id' => $oObj->GetKey());
}
else
{
} else {
return array('error' => implode(' ', $aErrors), 'id' => 0);
}
}
catch(Exception $e)
{
catch (Exception $e) {
return array('error' => $e->getMessage(), 'id' => 0);
}
}

View File

@@ -178,17 +178,18 @@ class UILinksWidget
$oDisplayBlock = new DisplayBlock($oFilter, 'search', false);
$oBlock->AddSubBlock($oDisplayBlock->GetDisplay($oPage, "SearchFormToAdd_{$sLinkedSetId}",
array(
'menu' => false,
[
'menu' => false,
'result_list_outer_selector' => "SearchResultsToAdd_{$sLinkedSetId}",
'table_id' => "add_{$sLinkedSetId}",
'table_inner_id' => "ResultsToAdd_{$sLinkedSetId}",
'selection_mode' => true,
'json' => $sJson,
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
'query_params' => $oFilter->GetInternalParams(),
'hidden_criteria' => $sAlreadyLinkedExpression,
)));
'table_id' => "add_{$sLinkedSetId}",
'table_inner_id' => "ResultsToAdd_{$sLinkedSetId}",
'selection_mode' => true,
'json' => $sJson,
'cssCount' => '#count_'.$this->m_sAttCode.$this->m_sNameSuffix,
'query_params' => $oFilter->GetInternalParams(),
'hidden_criteria' => $sAlreadyLinkedExpression,
'submit_on_load' => false,
]));
$oBlock->AddForm();
}

View File

@@ -20,6 +20,7 @@
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Service\Module\ModuleService;
use ScssPhp\ScssPhp\Compiler;
use ScssPhp\ScssPhp\OutputStyle;
use ScssPhp\ScssPhp\ValueConverter;
@@ -1396,13 +1397,23 @@ class utils
return APPROOT . 'env-' . MetaModel::GetEnvironment() . '/';
}
/**
* @return string A path to the folder into which data can be written
* @internal
* @since N°6097 2.7.10 3.0.4 3.1.1
*/
public static function GetDataPath(): string
{
return APPROOT.'data/';
}
/**
* @return string A path to a folder into which any module can store cache data
* The corresponding folder is created or cleaned upon code compilation
*/
public static function GetCachePath()
{
return APPROOT.'data/cache-'.MetaModel::GetEnvironment().'/';
return static::GetDataPath().'cache-'.MetaModel::GetEnvironment().'/';
}
/**
@@ -1970,6 +1981,7 @@ SQL;
/**
* @param string $sValue
* @param bool $bDoubleEncode Whether to double encode the value or not
*
* @return string passed value with only characters having a special meaning in HTML escaped as entities
* Since 3.0.0 we were using for this {@link HtmlEntities} but it was overkill and leads to double escaping !
@@ -1977,14 +1989,15 @@ SQL;
* @uses \htmlspecialchars()
* @link https://www.php.net/manual/fr/function.htmlspecialchars.php
* @since 3.0.0 N°3623
* @since 3.1.0 N°6405 Add $bDoubleEncode parameter
*/
public static function EscapeHtml($sValue)
public static function EscapeHtml($sValue, bool $bDoubleEncode = false)
{
return htmlspecialchars(
$sValue ?? '',
ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5,
WebPage::PAGES_CHARSET,
false
$bDoubleEncode
);
}
@@ -2045,6 +2058,9 @@ SQL;
*/
public static function TextToHtml($sText)
{
if (static::IsNullOrEmptyString($sText)){
return '';
}
$sText = str_replace("\r\n", "\n", $sText);
$sText = str_replace("\r", "\n", $sText);
@@ -2260,24 +2276,7 @@ SQL;
*/
public static function GetCurrentModuleName($iCallDepth = 0)
{
$sCurrentModuleName = '';
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$sCallerFile = realpath($aCallStack[$iCallDepth]['file']);
foreach(GetModulesInfo() as $sModuleName => $aInfo)
{
if ($aInfo['root_dir'] !== '')
{
$sRootDir = realpath(APPROOT.$aInfo['root_dir']);
if(substr($sCallerFile, 0, strlen($sRootDir)) === $sRootDir)
{
$sCurrentModuleName = $sModuleName;
break;
}
}
}
return $sCurrentModuleName;
return ModuleService::GetInstance()->GetCurrentModuleName($iCallDepth + 1);
}
/**
@@ -2299,24 +2298,7 @@ SQL;
*/
public static function GetCurrentModuleDir($iCallDepth)
{
$sCurrentModuleDir = '';
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$sCallerFile = realpath($aCallStack[$iCallDepth]['file']);
foreach(GetModulesInfo() as $sModuleName => $aInfo)
{
if ($aInfo['root_dir'] !== '')
{
$sRootDir = realpath(APPROOT.$aInfo['root_dir']);
if(substr($sCallerFile, 0, strlen($sRootDir)) === $sRootDir)
{
$sCurrentModuleDir = basename($sRootDir);
break;
}
}
}
return $sCurrentModuleDir;
return ModuleService::GetInstance()->GetCurrentModuleDir($iCallDepth);
}
/**
@@ -2331,12 +2313,7 @@ SQL;
*/
public static function GetCurrentModuleUrl()
{
$sDir = static::GetCurrentModuleDir(1);
if ( $sDir !== '')
{
return static::GetAbsoluteUrlModulesRoot().'/'.$sDir;
}
return '';
return ModuleService::GetInstance()->GetCurrentModuleUrl(1);
}
/**
@@ -2346,8 +2323,7 @@ SQL;
*/
public static function GetCurrentModuleSetting($sProperty, $defaultvalue = null)
{
$sModuleName = static::GetCurrentModuleName(1);
return MetaModel::GetModuleSetting($sModuleName, $sProperty, $defaultvalue);
return ModuleService::GetInstance()->GetCurrentModuleSetting($sProperty, $defaultvalue);
}
/**
@@ -2356,12 +2332,7 @@ SQL;
*/
public static function GetCompiledModuleVersion($sModuleName)
{
$aModulesInfo = GetModulesInfo();
if (array_key_exists($sModuleName, $aModulesInfo))
{
return $aModulesInfo[$sModuleName]['version'];
}
return null;
return ModuleService::GetInstance()->GetCompiledModuleVersion($sModuleName);
}
/**
@@ -2686,24 +2657,26 @@ SQL;
}
/**
* Returns the local path relative to the iTop installation of an existing file
* Returns the local path relative to the iTop installation (APPROOT or the given base path)
* Dir separator is changed to '/' for consistency among the different OS
*
* @param string $sAbsolutePath absolute path
* @param string $sBasePath Base path for the resulting local path (default APPROOT)
*
* @return false|string
* @return false|string The generated local path or false if absolute path is not under the base path
* @since 3.1.1 Added base path defaulted to previous version APPROOT
*/
final public static function LocalPath($sAbsolutePath)
final public static function LocalPath($sAbsolutePath, string $sBasePath = APPROOT)
{
$sRootPath = realpath(APPROOT);
$sRootPath = realpath($sBasePath);
$sFullPath = realpath($sAbsolutePath);
if (($sFullPath === false) || !self::StartsWith($sFullPath, $sRootPath))
{
return false;
}
$sLocalPath = substr($sFullPath, strlen($sRootPath.DIRECTORY_SEPARATOR));
$sLocalPath = str_replace(DIRECTORY_SEPARATOR, '/', $sLocalPath);
return $sLocalPath;
return str_replace(DIRECTORY_SEPARATOR, '/', $sLocalPath);
}
/**
@@ -2895,7 +2868,7 @@ HTML;
// Add already loaded classes
$aCurrentClasses = array_fill_keys(get_declared_classes(), '');
$aClassMap = array_merge($aClassMap, $aCurrentClasses);
$aClassMap = array_merge($aCurrentClasses, $aClassMap);
foreach ($aClassMap as $sPHPClass => $sPHPFile) {
$bSkipped = false;
@@ -2920,11 +2893,12 @@ HTML;
$bSkipped = true; // file not found
}
}
if(!$bSkipped){
try {
$oRefClass = new ReflectionClass($sPHPClass);
if ($oRefClass->implementsInterface($sInterface) && $oRefClass->isInstantiable()) {
if ($oRefClass->implementsInterface($sInterface) &&
!$oRefClass->isInterface() && !$oRefClass->isAbstract() && !$oRefClass->isTrait()) {
$aMatchingClasses[] = $sPHPClass;
}
} catch (Exception $e) {
@@ -3369,5 +3343,22 @@ HTML;
{
return in_array($sTrait, self::TraitsUsedByClass($sClass, true));
}
/**
* Get stack trace as string array.
*
* @return array
* @since 3.1.0
*/
public static function GetStackTraceAsArray(): array
{
$e = new Exception();
$aTrace = explode("\n", $e->getTraceAsString());
// Remove call to this method
array_shift($aTrace);
// Remove Main
array_pop($aTrace);
return $aTrace;
}
}

View File

@@ -45,6 +45,7 @@ define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
$fItopStarted = microtime(true);
$iItopInitialMemory = memory_get_usage(true);
if (!isset($GLOBALS['bBypassAutoload']) || $GLOBALS['bBypassAutoload'] == false) {
require_once APPROOT.'/lib/autoload.php';

View File

@@ -59,9 +59,16 @@ class DbConnectionWrapper
* Use this to register a mock that will handle {@see mysqli::query()}
*
* @param \mysqli|null $oMysqli
* @since 3.0.4 3.1.1 3.2.0 Param $oMysqli becomes nullable
*/
public static function SetDbConnectionMockForQuery(?mysqli $oMysqli): void
public static function SetDbConnectionMockForQuery(?mysqli $oMysqli = null): void
{
static::$oDbCnxMockableForQuery = $oMysqli;
if (is_null($oMysqli)) {
// Reset to standard connection
static::$oDbCnxMockableForQuery = static::$oDbCnxStandard;
}
else {
static::$oDbCnxMockableForQuery = $oMysqli;
}
}
}

View File

@@ -419,6 +419,7 @@ class MyHelpers
//}
return $sOutput;
}
}
/**
@@ -523,5 +524,3 @@ class Str
return (strtolower($sString) == $sString);
}
}
?>

View File

@@ -0,0 +1,101 @@
<?php
/*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Class TemporaryObjectDescriptor
*
* Descriptor to track a temporary object.
*
* @experimental do not use, this feature will be part of a future version
*
* @since 3.1
*/
class TemporaryObjectDescriptor extends DBObject
{
public static function Init()
{
$aParams = array(
'category' => 'core',
'key_type' => 'autoincrement',
'name_attcode' => array('item_class', 'temp_id'),
'image_attcode' => '',
'state_attcode' => '',
'reconc_keys' => array(''),
'db_table' => 'priv_temporary_object_descriptor',
'db_key_field' => 'id',
'db_finalclass_field' => '',
'style' => new ormStyle(null, null, null, null, null, null),
'indexes' => array(
1 =>
array(
0 => 'temp_id',
),
2 =>
array(
0 => 'item_class',
1 => 'item_id',
),
),
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime('expiration_date', array('sql' => 'expiration_date', 'is_null_allowed' => false, 'default_value' => '', 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeString('temp_id', array('sql' => 'temp_id', 'is_null_allowed' => true, 'default_value' => '', 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeString('item_class', array('sql' => 'item_class', 'is_null_allowed' => false, 'default_value' => '', 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeObjectKey('item_id', array('class_attcode' => 'item_class', 'sql' => 'item_id', 'is_null_allowed' => true, 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeDateTime('creation_date', array('sql' => 'creation_date', 'is_null_allowed' => true, 'default_value' => '', 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeString('host_class', array('sql' => 'host_class', 'is_null_allowed' => true, 'default_value' => '', 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeObjectKey('host_id', array('class_attcode' => 'host_class', 'sql' => 'host_id', 'is_null_allowed' => true, 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeString('host_att_code', array('sql' => 'host_att_code', 'is_null_allowed' => true, 'default_value' => '', 'allowed_values' => null, 'depends_on' => array(), 'always_load_in_tables' => false)));
MetaModel::Init_AddAttribute(new AttributeEnum("operation", array("allowed_values" => new ValueSetEnum('create,delete'), "sql" => "operation", "default_value" => "create", "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_SetZListItems('details', array(
0 => 'temp_id',
1 => 'item_class',
2 => 'item_id',
3 => 'creation_date',
4 => 'expiration_date',
5 => 'meta',
));
MetaModel::Init_SetZListItems('standard_search', array(
0 => 'temp_id',
1 => 'item_class',
2 => 'item_id',
));
MetaModel::Init_SetZListItems('list', array(
0 => 'temp_id',
1 => 'item_class',
2 => 'item_id',
3 => 'creation_date',
4 => 'expiration_date',
));;
}
public function DBInsertNoReload()
{
$this->SetCurrentDateIfNull('creation_date');
return parent::DBInsertNoReload();
}
/**
* Set/Update all of the '_item' fields
*
* @param object $oItem Container item
*
* @return void
*/
public function SetItem($oItem, $bUpdateOnChange = false)
{
$sClass = get_class($oItem);
$iItemId = $oItem->GetKey();
$this->Set('item_class', $sClass);
$this->Set('item_id', $iItemId);
}
}

View File

@@ -650,6 +650,9 @@ class ActionEmail extends ActionNotification
$aMessageContent['subject'] = 'TEST['.$aMessageContent['subject'].']';
$aMessageContent['body'] = $sTestBody;
$aMessageContent['to'] = $this->Get('test_recipient');
// N°6677 Ensure emails in test are never sent to cc'd and bcc'd addresses
$aMessageContent['cc'] = '';
$aMessageContent['bcc'] = '';
}
// Note: N°4849 We pass the "References" identifier instead of the "Message-ID" on purpose as we want notifications emails to group around the triggering iTop object, not just the users' replies to the notification
$aMessageContent['in_reply_to'] = $aMessageContent['references'];

View File

@@ -9,9 +9,7 @@ use Combodo\iTop\Application\UI\Links\Set\BlockLinkSetDisplayAsProperty;
use Combodo\iTop\Form\Field\LabelField;
use Combodo\iTop\Form\Field\TextAreaField;
use Combodo\iTop\Form\Form;
use Combodo\iTop\Form\Validator\LinkedSetValidator;
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
use Combodo\iTop\Form\Validator\Validator;
use Combodo\iTop\Form\Validator\CustomRegexpValidator;
use Combodo\iTop\Renderer\BlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
use Combodo\iTop\Service\Links\LinkSetModel;
@@ -93,9 +91,6 @@ define('LINKSET_EDITMODE_ACTIONS', 2); // Show the usual 'Actions' popup menu
define('LINKSET_EDITMODE_INPLACE', 3); // The "linked" objects can be created/modified/deleted in place
define('LINKSET_EDITMODE_ADDREMOVE', 4); // The "linked" objects can be added/removed in place
define('LINKSET_RELATIONTYPE_PROPERTY', 'property');
define('LINKSET_RELATIONTYPE_LINK', 'link');
define('LINKSET_DISPLAY_STYLE_PROPERTY', 'property');
define('LINKSET_DISPLAY_STYLE_TAB', 'tab');
@@ -1126,7 +1121,7 @@ abstract class AttributeDefinition
// Validation pattern
if ($this->GetValidationPattern() !== '') {
$oFormField->AddValidator(new Validator($this->GetValidationPattern()));
$oFormField->AddValidator(new CustomRegexpValidator($this->GetValidationPattern()));
}
// Description
@@ -1155,6 +1150,13 @@ abstract class AttributeDefinition
$oFormField->AddMetadata('value-raw', (string)$oObject->Get($this->GetCode()));
}
// We don't want to invalidate field because of old untouched values that are no longer valid
$aModifiedAttCodes = $oObject->ListChanges();
$bAttributeHasBeenModified = array_key_exists($this->GetCode(), $aModifiedAttCodes);
if (false === $bAttributeHasBeenModified) {
$oFormField->SetValidationDisabled(true);
}
return $oFormField;
}
@@ -1697,22 +1699,12 @@ class AttributeLinkedSet extends AttributeDefinition
/**
* @return string see LINKSET_EDITMODE_* constants
* @since 3.1.0 N°5563 relations are edited using new attributes in details mode, but as nothing changed in edit mode we are still using edit_mode attribute
*/
public function GetEditMode()
{
return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS);
}
/**
* @return string see LINKSET_RELATIONTYPE_* constants
* @since 3.1.0 N°5563
*/
public function GetRelationType()
{
return $this->GetOptional('relation_type', LINKSET_RELATIONTYPE_LINK);
}
/**
* @return string see LINKSET_DISPLAY_STYLE_* constants
* @since 3.1.0 N°3190
@@ -1737,15 +1729,6 @@ class AttributeLinkedSet extends AttributeDefinition
return $this->GetOptional('with_php_constraint', false);
}
/**
* @return boolean
* @since 3.1.0 N°5563
*/
public function GetReadOnly()
{
return $this->GetOptional('read_only', false);
}
public function GetLinkedClass()
{
return $this->Get('linked_class');
@@ -1772,7 +1755,53 @@ class AttributeLinkedSet extends AttributeDefinition
}
/** @inheritDoc * */
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true): string
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
{
if($this->GetDisplayStyle() === LINKSET_DISPLAY_STYLE_TAB){
return $this->GetAsHTMLForTab($sValue, $oHostObject, $bLocalize);
}
else{
return $this->GetAsHTMLForProperty($sValue, $oHostObject, $bLocalize);
}
}
public function GetAsHTMLForTab($sValue, $oHostObject = null, $bLocalize = true)
{
if (is_object($sValue) && ($sValue instanceof ormLinkSet))
{
$sValue->Rewind();
$aItems = array();
while ($oObj = $sValue->Fetch())
{
// Show only relevant information (hide the external key to the current object)
$aAttributes = array();
foreach(MetaModel::ListAttributeDefs($this->GetLinkedClass()) as $sAttCode => $oAttDef)
{
if ($sAttCode == $this->GetExtKeyToMe())
{
continue;
}
if ($oAttDef->IsExternalField())
{
continue;
}
$sAttValue = $oObj->GetAsHTML($sAttCode);
if (strlen($sAttValue) > 0)
{
$aAttributes[] = $sAttValue;
}
}
$sAttributes = implode(', ', $aAttributes);
$aItems[] = $sAttributes;
}
return implode('<br/>', $aItems);
}
return null;
}
public function GetAsHTMLForProperty($sValue, $oHostObject = null, $bLocalize = true): string
{
try {
@@ -2447,8 +2476,6 @@ class AttributeLinkedSet extends AttributeDefinition
$oFormField->SetLnkAttributesToDisplay($aLnkAttributesToDisplay);
}
$oFormField->AddValidator(new LinkedSetValidator());
parent::MakeFormField($oObject, $oFormField);
return $oFormField;
@@ -2558,15 +2585,6 @@ class AttributeLinkedSetIndirect extends AttributeLinkedSet
return $this->GetOptional("duplicates", false);
} // The same object may be linked several times... or not...
/**
* @return boolean
* @since 3.1.0 N°5563
*/
public function GetReadOnly()
{
return $this->GetOptional('read_only', false);
}
public function GetTrackingLevel()
{
return $this->GetOptional('tracking_level',
@@ -3873,6 +3891,12 @@ class AttributeApplicationLanguage extends AttributeString
{
$aLanguageCodes[$sLangCode] = $aInfo['description'].' ('.$aInfo['localized_description'].')';
}
// N°6462 This should be sorted directly in \Dict during the compilation but we can't for 2 reasons:
// - Additional languages can be added on the fly even though it is not recommended
// - Formatting is done at run time (just above)
natcasesort($aLanguageCodes);
$aParams["allowed_values"] = new ValueSetEnum($aLanguageCodes);
parent::__construct($sCode, $aParams);
}
@@ -4163,7 +4187,7 @@ class AttributePassword extends AttributeString implements iAttributeNoGroupBy
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
{
if (strlen($sValue) == 0)
if (utils::IsNullOrEmptyString($sValue))
{
return '';
}
@@ -7196,14 +7220,27 @@ class AttributeExternalKey extends AttributeDBFieldVoid
{
return 0;
}
if (MetaModel::IsValidObject($proposedValue))
{
if (MetaModel::IsValidObject($proposedValue)) {
return $proposedValue->GetKey();
}
return (int)$proposedValue;
}
/** @inheritdoc @since 3.1 */
public function WriteExternalValues(DBObject $oHostObject): void
{
$sTargetKey = $oHostObject->Get($this->GetCode());
$oFilter = DBSearch::FromOQL('SELECT `'.TemporaryObjectDescriptor::class.'` WHERE item_class=:class AND item_id=:id');
$oSet = new DBObjectSet($oFilter, [], ['class' => $this->GetTargetClass(), 'id' => $sTargetKey]);
while ($oTemporaryObjectDescriptor = $oSet->Fetch()) {
$oTemporaryObjectDescriptor->Set('host_class', get_class($oHostObject));
$oTemporaryObjectDescriptor->Set('host_id', $oHostObject->GetKey());
$oTemporaryObjectDescriptor->Set('host_att_code', $this->GetCode());
$oTemporaryObjectDescriptor->DBUpdate();
}
}
public function GetMaximumComboLength()
{
return $this->GetOptional('max_combo_length', MetaModel::GetConfig()->Get('max_combo_length'));
@@ -7267,6 +7304,7 @@ class AttributeExternalKey extends AttributeDBFieldVoid
public function MakeFormField(DBObject $oObject, $oFormField = null)
{
/** @var \Combodo\iTop\Form\Field\Field $oFormField */
if ($oFormField === null) {
// Later : We should check $this->Get('display_style') and create a Radio / Select / ... regarding its value
$sFormFieldClass = static::GetFormFieldClass();
@@ -7297,19 +7335,12 @@ class AttributeExternalKey extends AttributeDBFieldVoid
}
});
}
else
{
else {
$oSearch = DBSearch::FromOQL($this->GetValuesDef()->GetFilterExpression());
$oSearch->SetInternalParams(array('this' => $oObject));
$oFormField->SetSearch($oSearch);
}
// If ExtKey is mandatory, we add a validator to ensure that the value 0 is not selected
if ($oObject->GetAttributeFlags($this->GetCode()) & OPT_ATT_MANDATORY)
{
$oFormField->AddValidator(new NotEmptyExtKeyValidator());
}
parent::MakeFormField($oObject, $oFormField);
return $oFormField;
@@ -7935,6 +7966,17 @@ class AttributeExternalField extends AttributeDefinition
return $oExtAttDef->MakeRealValue($proposedValue, $oHostObj);
}
/**
* @inheritDoc
* @since 3.1.0 N°6271 Delegate to remote attribute to ensure cascading computed values
*/
public function GetSQLValues($value)
{
$oExtAttDef = $this->GetExtAttDef();
return $oExtAttDef->GetSQLValues($value);
}
public function ScalarToSQL($value)
{
// This one could be used in case of filtering only
@@ -8343,7 +8385,7 @@ class AttributeBlob extends AttributeDefinition
$aValues[$this->GetCode().'_data'] = '';
$aValues[$this->GetCode().'_mimetype'] = '';
$aValues[$this->GetCode().'_filename'] = '';
$aValues[$this->GetCode().'_downloads_count'] = \ormDocument::DEFAULT_DOWNLOADS_COUNT;
$aValues[$this->GetCode().'_downloads_count'] = ormDocument::DEFAULT_DOWNLOADS_COUNT;
}
return $aValues;
@@ -8533,6 +8575,22 @@ class AttributeBlob extends AttributeDefinition
return utils::IsNotNullOrEmptyString($proposedValue->GetData()) && utils::IsNotNullOrEmptyString($proposedValue->GetFileName());
}
/**
* @inheritDoc
* @param \ormDocument $original
* @param \ormDocument $value
* @since N°6502
*/
public function RecordAttChange(DBObject $oObject, $original, $value): void
{
// N°6502 Don't record history if only the download count has changed
if ($original->EqualsExceptDownloadsCount($value)) {
return;
}
parent::RecordAttChange($oObject, $original, $value);
}
protected function GetChangeRecordAdditionalData(CMDBChangeOp $oMyChangeOp, DBObject $oObject, $original, $value): void
{
if (is_null($original)) {
@@ -8692,7 +8750,7 @@ class AttributeImage extends AttributeBlob
return 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData());
}
return $value->GetDownloadURL(get_class($oHostObject), $oHostObject->GetKey(), $this->GetCode());
return $value->GetDisplayURL(get_class($oHostObject), $oHostObject->GetKey(), $this->GetCode());
}
public static function GetFormFieldClass()
@@ -11302,6 +11360,9 @@ class AttributeClassAttCodeSet extends AttributeSet
}
$aAllowedAttributes[$sAttCode] = $sLabel;
}
// N°6460 Always sort on the labels, not on the datamodel definition order
natcasesort($aAllowedAttributes);
return $aAllowedAttributes;
}

View File

@@ -35,6 +35,7 @@ MetaModel::IncludeModule('synchro/synchrodatasource.class.inc.php');
MetaModel::IncludeModule('core/backgroundtask.class.inc.php');
MetaModel::IncludeModule('core/inlineimage.class.inc.php');
MetaModel::IncludeModule('core/counter.class.inc.php');
MetaModel::IncludeModule('core/TemporaryObjectDescriptor.php');
MetaModel::IncludeModule('webservices/webservices.basic.php');

View File

@@ -37,6 +37,14 @@ abstract class CellChangeSpec
return $this->m_proposedValue;
}
/**
* @since 3.1.0 N°5305
*/
public function SetDisplayableValue(string $sDisplayableValue)
{
$this->m_proposedValue = $sDisplayableValue;
}
public function GetOql()
{
return $this->m_sOql;
@@ -136,6 +144,12 @@ class CellStatus_SearchIssue extends CellStatus_Issue
/** @var string|null $m_sTargetClass */
private $m_sTargetClass;
/**
* @since 3.1.0 N°5305
* @var string $sAllowedValuesSearch
*/
private $sAllowedValuesSearch;
/**
* CellStatus_SearchIssue constructor.
* @since 3.1.0 N°5305
@@ -144,13 +158,15 @@ class CellStatus_SearchIssue extends CellStatus_Issue
* @param string $sReason : main message
* @param null $sClass : used for additional message that provides allowed values for current class $sClass
* @param null $sAllowedValues : used for additional message that provides allowed values $sAllowedValues for current class
* @param string|null $sAllowedValuesSearch : used to search all allowed values
*/
public function __construct($sSerializedSearch, $sReason, $sClass=null, $sAllowedValues=null)
public function __construct($sSerializedSearch, $sReason, $sClass=null, $sAllowedValues=null, string $sAllowedValuesSearch=null)
{
parent::__construct(null, null, $sReason);
$this->sSerializedSearch = $sSerializedSearch;
$this->m_sAllowedValues = $sAllowedValues;
$this->m_sTargetClass = $sClass;
$this->sAllowedValuesSearch = $sAllowedValuesSearch;
}
public function GetDisplayableValue()
@@ -182,6 +198,17 @@ class CellStatus_SearchIssue extends CellStatus_Issue
rawurlencode($this->sSerializedSearch)
);
}
/**
* @since 3.1.0 N°5305
* @return null|string
*/
public function GetAllowedValuesLinkUrl(): ?string
{
return sprintf("UI.php?operation=search&filter=%s",
rawurlencode($this->sAllowedValuesSearch)
);
}
}
class CellStatus_NullIssue extends CellStatus_Issue
@@ -745,6 +772,7 @@ class BulkChange
$oDbSearchWithoutAnyCondition->AllowAllData(false);
$oExtObjectSetWithCurrentUserPermissions = new CMDBObjectSet($oDbSearchWithoutAnyCondition);
$iCurrentUserRightsObjectCount = $oExtObjectSetWithCurrentUserPermissions->Count();
$sAllowedValuesOql = $oDbSearchWithoutAnyCondition->serialize();
if ($iCurrentUserRightsObjectCount === 0){
// No objects visible by current user
@@ -785,7 +813,7 @@ class BulkChange
if ($iAllowAllDataObjectCount != $iCurrentUserRightsObjectCount) {
// No match and some objects NOT visible by current user. including current search maybe...
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-SomeObjectNotVisibleForCurrentUser', $oDbSearchWithConditions->GetClass());
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues);
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues, $sAllowedValuesOql);
}
// No match. This is not linked to any right issue
@@ -796,7 +824,7 @@ class BulkChange
}
$value =implode(" ", $aCurrentValueFields);
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch', $value);
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues);
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues, $sAllowedValuesOql);
}
protected function PrepareMissingObject(&$oTargetObj, &$aErrors)

View File

@@ -469,7 +469,10 @@ abstract class CMDBObject extends DBObject
*/
public function DBDelete(&$oDeletionPlan = null)
{
return $this->DBDeleteTracked_Internal($oDeletionPlan);
$this->LogCRUDEnter(__METHOD__);
$oDeletionPlan = $this->DBDeleteTracked_Internal($oDeletionPlan);
$this->LogCRUDExit(__METHOD__);
return $oDeletionPlan;
}
/**
@@ -519,15 +522,6 @@ abstract class CMDBObject extends DBObject
utils::PopArchiveMode();
}
}
public function DBUpdate()
{
if (count($this->ListChanges()) === 0) {
$this->InitPreviousValuesForUpdatedAttributes();
return $this->GetKey();
}
return parent::DBUpdate(); // TODO: Change the autogenerated stub
}
}

View File

@@ -431,6 +431,7 @@ class CMDBSource
{
self::$m_sDBName = '';
}
self::_TablesInfoCacheReset(); // reset the table info cache!
}
public static function CreateTable($sQuery)
@@ -607,8 +608,9 @@ class CMDBSource
{
self::LogDeadLock($e, true);
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
}
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
} finally {
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
}
if ($oResult === false) {
$aContext = array('query' => $sSql);
@@ -626,18 +628,24 @@ class CMDBSource
}
/**
* @param \Exception $e
* @param Exception $e
* @param bool $bForQuery to get the proper DB connection
* @param bool $bCheckMysqliErrno if false won't try to check for mysqli::errno value
*
* @since 2.7.1
* @since 3.0.0 N°4325 add new optional parameter to use the correct DB connection
* @since 3.0.4 3.1.1 3.2.0 N°6643 new bCheckMysqliErrno parameter as a workaround for mysqli::errno cannot be mocked
*/
private static function LogDeadLock(Exception $e, $bForQuery = false)
private static function LogDeadLock(Exception $e, $bForQuery = false, $bCheckMysqliErrno = true)
{
// checks MySQL error code
$iMySqlErrorNo = DbConnectionWrapper::GetDbConnection($bForQuery)->errno;
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK))) {
return;
if ($bCheckMysqliErrno) {
$iMySqlErrorNo = DbConnectionWrapper::GetDbConnection($bForQuery)->errno;
if (!in_array($iMySqlErrorNo, array(self::MYSQL_ERRNO_WAIT_TIMEOUT, self::MYSQL_ERRNO_DEADLOCK))) {
return;
}
} else {
$iMySqlErrorNo = "N/A";
}
// Get error info
@@ -664,7 +672,10 @@ class CMDBSource
);
DeadLockLog::Info($sMessage, $iMySqlErrorNo, $aLogContext);
IssueLog::Error($sMessage, LogChannels::DEADLOCK, $e->getMessage());
IssueLog::Error($sMessage, LogChannels::DEADLOCK, [
'exception.class' => get_class($e),
'exception.message' => $e->getMessage(),
]);
}
/**

View File

@@ -29,7 +29,7 @@ define('ITOP_APPLICATION_SHORT', 'iTop');
*
* @see ITOP_CORE_VERSION to get iTop core version
*/
define('ITOP_VERSION', '3.1.0-dev');
define('ITOP_VERSION', '3.1.1-dev');
define('ITOP_VERSION_NAME', 'Fullmoon');
define('ITOP_REVISION', 'svn');
@@ -137,7 +137,7 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'log_purge.max_keep_days' => [
'log_purge.max_keep_days' => [
'type' => 'integer',
'description' => 'Optional purge number of days to keep logs.',
'default' => 365,
@@ -145,7 +145,7 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'event_service.debug.filter_events' => [
'event_service.debug.filter_events' => [
'type' => 'array',
'description' => 'List of events name to filter Event Service debug messages',
'default' => [],
@@ -153,7 +153,7 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'event_service.debug.filter_sources' => [
'event_service.debug.filter_sources' => [
'type' => 'array',
'description' => 'List of event sources to filter Event Service debug messages',
'default' => '',
@@ -161,6 +161,38 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'temporary_object.force_creation' => [
'type' => 'bool',
'description' => 'If true, all the objects created by the external key are temporary',
'default' => false,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'temporary_object.lifetime' => [
'type' => 'integer',
'description' => 'Seconds for temporary objects created',
'default' => 300,
'value' => 300,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'temporary_object.watchdog_interval' => [
'type' => 'integer',
'description' => 'Seconds between watchdog signals',
'default' => 60,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'temporary_object.garbage_interval' => [
'type' => 'integer',
'description' => 'Seconds between garbage collections',
'default' => 60,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'app_env_label' => [
'type' => 'string',
'description' => 'Label displayed to describe the current application environment, defaults to the environment name (e.g. "production")',
@@ -185,7 +217,7 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'db_host' => [
'db_host' => [
'type' => 'string',
'default' => null,
'value' => '',
@@ -624,22 +656,22 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'email_transport_smtp.allow_self_signed' => array(
'email_transport_smtp.allow_self_signed' => [
'type' => 'bool',
'description' => 'Allow self signed peer certificates',
'default' => false,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'email_transport_smtp.verify_peer' => array(
],
'email_transport_smtp.verify_peer' => [
'type' => 'bool',
'description' => 'Verify peer certificate',
'default' => true,
'value' => true,
'source_of_value' => '',
'show_in_conf_sample' => false,
),
],
'email_css' => [
'type' => 'string',
'description' => 'CSS that will override the standard stylesheet used for the notifications',
@@ -1037,6 +1069,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'log_kpi_generate_legacy_report' => [
'type' => 'bool',
'description' => 'Generate the legacy KPI report (kpi.html)',
'default' => true,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'max_linkset_output' => [
'type' => 'integer',
'description' => 'Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.',

View File

@@ -1,8 +1,11 @@
<?php
/**
* This file is only here for compatibility issues. Will be removed in iTop 3.1.0 (N°3664)
* This file is only here for compatibility reasons.
* It will be removed in future iTop versions (N°6533)
*
* @deprecated 3.0.0 N°3663 Exception classes were moved to `/application/exceptions`, use autoloader instead of require !
*/
require_once '../approot.inc.php';
DeprecatedCallsLog::NotifyDeprecatedFile('Classes were moved to /application/exceptions');
require_once __DIR__ . '/../approot.inc.php';
DeprecatedCallsLog::NotifyDeprecatedFile('Classes were moved to /application/exceptions and can be used directly with the autoloader');

View File

@@ -188,8 +188,8 @@ final class ItopCounter
if (!$hDBLink)
{
throw new Exception("Could not connect to the DB server (host=$sDBHost, user=$sDBUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
}
throw new MySQLException('Could not connect to the DB server '.mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno(), array('host' => $sDBHost, 'user' => $sDBUser));
}
return $hDBLink;
}

View File

@@ -137,7 +137,7 @@ class CSVBulkExport extends TabularBulkExport
$aSep['other'] = Dict::S('UI:CSVImport:SeparatorOther').' <input type="text" size="3" name="other-separator" value="'.utils::EscapeHtml($sOtherSeparator).'"/>';
foreach ($aSep as $sVal => $sLabel) {
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", utils::EscapeHtml($sVal), $sLabel, "radio");
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "separator", $sVal, $sLabel, "radio");
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
$oRadio->SetBeforeInput(false);
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
@@ -163,8 +163,8 @@ class CSVBulkExport extends TabularBulkExport
$aQualifiers['other'] = Dict::S('UI:CSVImport:QualifierOther').' <input type="text" size="3" name="other-text-qualifier" value="'.utils::EscapeHtml($sOtherQualifier).'"/>';
foreach ($aQualifiers as $sVal => $sLabel) {
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "text-qualifier", utils::EscapeHtml($sVal), $sLabel, "radio");
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawSeparator));
$oRadio = InputUIBlockFactory::MakeForInputWithLabel($sLabel, "text-qualifier", $sVal, $sLabel, "radio");
$oRadio->GetInput()->SetIsChecked(($sVal == $sRawQualifier));
$oRadio->SetBeforeInput(false);
$oRadio->GetInput()->AddCSSClass('ibo-input--label-right');
$oRadio->GetInput()->AddCSSClass('ibo-input-checkbox');

View File

@@ -58,6 +58,7 @@
<parent>cmdbAbstractObject</parent>
<properties>
<category>addon/userrights,grant_by_profile</category>
<is_link>1</is_link>
</properties>
<fields>
<field id="userid" xsi:type="AttributeExternalKey">
@@ -218,6 +219,19 @@
<field id="friendlyname" xsi:type="AttributeFriendlyName"/>
</fields>
</class>
<class id="AuditDomain" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<category>application, grant_by_profile</category>
</properties>
<fields>
<field id="name" xsi:type="AttributeString"/>
<field id="description" xsi:type="AttributeString"/>
<field id="icon" xsi:type="AttributeImage"/>
<field id="categories_list" xsi:type="AttributeLinkedSet"/>
<field id="friendlyname" xsi:type="AttributeFriendlyName"/>
</fields>
</class>
<class id="Query" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>cmdbAbstractObject</parent>
@@ -488,6 +502,12 @@
<type>boolean</type>
<default>false</default>
</property>
<property id="create_temporary_object">
<php_param>create_temporary_object</php_param>
<mandatory>false</mandatory>
<type>boolean</type>
<default>false</default>
</property>
<property id="on_target_delete">
<php_param>on_target_delete</php_param>
<mandatory>false</mandatory>

File diff suppressed because it is too large Load Diff

View File

@@ -767,7 +767,10 @@ class DBObjectSet implements iDBObjectSetIterator
try
{
$oKPI = new ExecutionKPI();
$this->m_oSQLResult = CMDBSource::Query($sSQL);
$sOQL = $this->GetPseudoOQL($this->m_oFilter, $this->GetRealSortOrder(), $this->m_iLimitCount, $this->m_iLimitStart, false);
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
} catch (MySQLException $e)
{
// 1116 = ER_TOO_MANY_TABLES
@@ -847,8 +850,11 @@ class DBObjectSet implements iDBObjectSetIterator
{
if (is_null($this->m_iNumTotalDBRows))
{
$oKPI = new ExecutionKPI();
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
$resQuery = CMDBSource::Query($sSQL);
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), 0, 0, true);
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
if (!$resQuery) return 0;
$aRow = CMDBSource::FetchArray($resQuery);
@@ -859,6 +865,42 @@ class DBObjectSet implements iDBObjectSetIterator
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
}
/**
* @param \DBSearch $oFilter
* @param array $aOrder
* @param int $iLimitCount
* @param int $iLimitStart
* @param bool $bCount
*
* @return string
*/
private function GetPseudoOQL($oFilter, $aOrder, $iLimitCount, $iLimitStart, $bCount)
{
$sOQL = '';
if ($bCount) {
$sOQL .= 'COUNT ';
}
$sOQL .= $oFilter->ToOQL();
if ($iLimitCount > 0) {
$sOQL .= ' LIMIT ';
if ($iLimitStart > 0) {
$sOQL .= "$iLimitStart, ";
}
$sOQL .= "$iLimitCount";
}
if (count($aOrder) > 0) {
$sOQL .= ' ORDER BY ';
$aOrderBy = [];
foreach ($aOrder as $sAttCode => $bAsc) {
$aOrderBy[] = $sAttCode.' '.($bAsc ? 'ASC' : 'DESC');
}
$sOQL .= implode(', ', $aOrderBy);
}
return $sOQL;
}
/**
* Check if the count exceeds a given limit
*
@@ -875,8 +917,11 @@ class DBObjectSet implements iDBObjectSetIterator
{
if (is_null($this->m_iNumTotalDBRows))
{
$oKPI = new ExecutionKPI();
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
$resQuery = CMDBSource::Query($sSQL);
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), $iLimit + 2, 0, true);
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
if ($resQuery)
{
$aRow = CMDBSource::FetchArray($resQuery);
@@ -887,7 +932,7 @@ class DBObjectSet implements iDBObjectSetIterator
{
$iCount = 0;
}
}
}
else
{
$iCount = $this->m_iNumTotalDBRows;
@@ -912,8 +957,11 @@ class DBObjectSet implements iDBObjectSetIterator
{
if (is_null($this->m_iNumTotalDBRows))
{
$oKPI = new ExecutionKPI();
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
$resQuery = CMDBSource::Query($sSQL);
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), $iLimit + 2, 0, true);
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
if ($resQuery)
{
$aRow = CMDBSource::FetchArray($resQuery);
@@ -924,7 +972,7 @@ class DBObjectSet implements iDBObjectSetIterator
{
$iCount = 0;
}
}
}
else
{
$iCount = $this->m_iNumTotalDBRows;

View File

@@ -3,7 +3,7 @@
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
@@ -56,10 +56,11 @@ class Dict
* @param $sLanguageCode
*
* @throws \DictExceptionUnknownLanguage
* @since 3.0.4 3.1.1 3.2.0 Param $sLanguageCode becomes nullable
*/
public static function SetUserLanguage($sLanguageCode)
public static function SetUserLanguage($sLanguageCode = null)
{
if (!array_key_exists($sLanguageCode, self::$m_aLanguages))
if (!is_null($sLanguageCode) && !array_key_exists($sLanguageCode, self::$m_aLanguages))
{
throw new DictExceptionUnknownLanguage($sLanguageCode);
}
@@ -115,33 +116,50 @@ class Dict
* @return string
*/
public static function S($sStringCode, $sDefault = null, $bUserLanguageOnly = false)
{
$aInfo = self::GetLabelAndLangCode($sStringCode, $sDefault, $bUserLanguageOnly);
return $aInfo['label'];
}
/**
* Returns a localised string from the dictonary with its associated lang code
*
* @param string $sStringCode The code identifying the dictionary entry
* @param string $sDefault Default value if there is no match in the dictionary
* @param bool $bUserLanguageOnly True to allow the use of the default language as a fallback, false otherwise
*
* @return array{
* lang: string, label: string
* } with localized label string and used lang code
*/
private static function GetLabelAndLangCode($sStringCode, $sDefault = null, $bUserLanguageOnly = false)
{
// Attempt to find the string in the user language
//
$sLangCode = self::GetUserLanguage();
self::InitLangIfNeeded($sLangCode);
if (!array_key_exists($sLangCode, self::$m_aData))
if (! array_key_exists($sLangCode, self::$m_aData))
{
IssueLog::Warning("Cannot find $sLangCode in dictionnaries. default labels displayed");
IssueLog::Warning("Cannot find $sLangCode in all registered dictionaries.");
// It may happen, when something happens before the dictionaries get loaded
return $sStringCode;
return [ 'label' => $sStringCode, 'lang' => $sLangCode ];
}
$aCurrentDictionary = self::$m_aData[$sLangCode];
if (is_array($aCurrentDictionary) && array_key_exists($sStringCode, $aCurrentDictionary))
{
return $aCurrentDictionary[$sStringCode];
return [ 'label' => $aCurrentDictionary[$sStringCode], 'lang' => $sLangCode ];
}
if (!$bUserLanguageOnly)
{
// Attempt to find the string in the default language
//
self::InitLangIfNeeded(self::$m_sDefaultLanguage);
$aDefaultDictionary = self::$m_aData[self::$m_sDefaultLanguage];
if (is_array($aDefaultDictionary) && array_key_exists($sStringCode, $aDefaultDictionary))
{
return $aDefaultDictionary[$sStringCode];
return [ 'label' => $aDefaultDictionary[$sStringCode], 'lang' => self::$m_sDefaultLanguage ];
}
// Attempt to find the string in english
//
@@ -150,17 +168,17 @@ class Dict
$aDefaultDictionary = self::$m_aData['EN US'];
if (is_array($aDefaultDictionary) && array_key_exists($sStringCode, $aDefaultDictionary))
{
return $aDefaultDictionary[$sStringCode];
return [ 'label' => $aDefaultDictionary[$sStringCode], 'lang' => 'EN US' ];
}
}
// Could not find the string...
//
if (is_null($sDefault))
{
return $sStringCode;
return [ 'label' => $sStringCode, 'lang' => null ];
}
return $sDefault;
return [ 'label' => $sDefault, 'lang' => null ];
}
@@ -176,19 +194,25 @@ class Dict
*/
public static function Format($sFormatCode /*, ... arguments ... */)
{
$sLocalizedFormat = self::S($sFormatCode);
['label' => $sLocalizedFormat, 'lang' => $sLangCode] = self::GetLabelAndLangCode($sFormatCode);
$aArguments = func_get_args();
array_shift($aArguments);
if ($sLocalizedFormat == $sFormatCode)
{
// Make sure the information will be displayed (ex: an error occuring before the dictionary gets loaded)
return $sFormatCode.' - '.implode(', ', $aArguments);
}
return vsprintf($sLocalizedFormat, $aArguments);
try{
return vsprintf($sLocalizedFormat, $aArguments);
} catch(\Throwable $e){
\IssueLog::Error("Cannot format dict key", null, ["sFormatCode" => $sFormatCode, "sLangCode" => $sLangCode, 'exception_msg' => $e->getMessage() ]);
return $sFormatCode.' - '.implode(', ', $aArguments);
}
}
/**
* Initialize a the entries for a given language (replaces the former Add() method)
* @param string $sLanguageCode Code identifying the language i.e. 'FR-FR', 'EN-US'
@@ -198,7 +222,7 @@ class Dict
{
self::$m_aData[$sLanguageCode] = $aEntries;
}
/**
* Set the list of available languages
* @param hash $aLanguagesList
@@ -259,7 +283,7 @@ class Dict
{
$sDictFile = APPROOT.'env-'.utils::GetCurrentEnvironment().'/dictionaries/'.str_replace(' ', '-', strtolower($sLangCode)).'.dict.php';
require_once($sDictFile);
if (self::GetApcService()->function_exists('apc_store')
&& (self::$m_sApplicationPrefix !== null))
{
@@ -269,7 +293,7 @@ class Dict
}
return $bResult;
}
/**
* Enable caching (cached using APC)
* @param string $sApplicationPrefix The prefix for uniquely identiying this iTop instance
@@ -312,14 +336,14 @@ class Dict
}
}
}
public static function MakeStats($sLanguageCode, $sLanguageRef = 'EN US')
{
$aMissing = array(); // Strings missing for the target language
$aUnexpected = array(); // Strings defined for the target language, but not found in the reference dictionary
$aNotTranslated = array(); // Strings having the same value in both dictionaries
$aOK = array(); // Strings having different values in both dictionaries
foreach (self::$m_aData[$sLanguageRef] as $sStringCode => $sValue)
{
if (!array_key_exists($sStringCode, self::$m_aData[$sLanguageCode]))
@@ -327,7 +351,7 @@ class Dict
$aMissing[$sStringCode] = $sValue;
}
}
foreach (self::$m_aData[$sLanguageCode] as $sStringCode => $sValue)
{
if (!array_key_exists($sStringCode, self::$m_aData[$sLanguageRef]))
@@ -350,7 +374,7 @@ class Dict
}
return array($aMissing, $aUnexpected, $aNotTranslated, $aOK);
}
public static function Dump()
{
MyHelpers::var_dump_html(self::$m_aData);
@@ -373,7 +397,7 @@ class Dict
// No need to actually load the strings since it's only used to know the list of languages
// at setup time !!
}
/**
* Export all the dictionary entries - of the given language - whose code matches the given prefix
* missing entries in the current language will be replaced by entries in the default language
@@ -386,7 +410,7 @@ class Dict
self::InitLangIfNeeded(self::$m_sDefaultLanguage);
$aEntries = array();
$iLength = strlen($sStartingWith);
// First prefill the array with entries from the default language
foreach(self::$m_aData[self::$m_sDefaultLanguage] as $sCode => $sEntry)
{
@@ -395,7 +419,7 @@ class Dict
$aEntries[$sCode] = $sEntry;
}
}
// Now put (overwrite) the entries for the user language
foreach(self::$m_aData[self::GetUserLanguage()] as $sCode => $sEntry)
{

View File

@@ -1,27 +1,14 @@
<?php
// Copyright (C) 2010-2023 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Core\Kpi\KpiLogData;
use Combodo\iTop\Service\Module\ModuleService;
/**
* Measures operations duration, memory usage, etc. (and some other KPIs)
*
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ExecutionKPI
@@ -30,6 +17,8 @@ class ExecutionKPI
static protected $m_bEnabled_Memory = false;
static protected $m_bBlameCaller = false;
static protected $m_sAllowedUser = '*';
static protected $m_bGenerateLegacyReport = true;
static protected $m_fSlowQueries = 0;
static protected $m_aStats = []; // Recurrent operations
static protected $m_aExecData = []; // One shot operations
@@ -86,14 +75,39 @@ class ExecutionKPI
return false;
}
static public function SetGenerateLegacyReport($bReportExtensionsOnly)
{
self::$m_bGenerateLegacyReport = $bReportExtensionsOnly;
}
static public function SetSlowQueries($fSlowQueries)
{
self::$m_fSlowQueries = $fSlowQueries;
}
static public function GetDescription()
{
$aFeatures = array();
if (self::$m_bEnabled_Duration) $aFeatures[] = 'Duration';
if (self::$m_bEnabled_Memory) $aFeatures[] = 'Memory usage';
$sFeatures = implode(', ', $aFeatures);
$sFeatures = 'Measures: '.implode(', ', $aFeatures);
$sFor = self::$m_sAllowedUser == '*' ? 'EVERYBODY' : "'".trim(self::$m_sAllowedUser)."'";
return "KPI logging is active for $sFor. Measures: $sFeatures";
$sSlowQueries = '';
if (self::$m_fSlowQueries > 0) {
$sSlowQueries = ". Slow Queries: ".self::$m_fSlowQueries."s";
}
$aExtensions = [];
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$aExtensions[] = ModuleService::GetInstance()->GetModuleNameFromObject($oExtensionInstance);
}
$sExtensions = '';
if (count($aExtensions) > 0) {
$sExtensions = '. KPI Extensions: ['.implode(', ', $aExtensions).']';
}
return "KPI logging is active for $sFor. $sFeatures$sSlowQueries$sExtensions";
}
static public function ReportStats()
@@ -101,7 +115,28 @@ class ExecutionKPI
if (!self::IsEnabled()) return;
global $fItopStarted;
global $iItopInitialMemory;
$sExecId = microtime(); // id to differentiate the hrefs!
$sRequest = $_SERVER['REQUEST_URI'].' ('.$_SERVER['REQUEST_METHOD'].')';
if (isset($_POST['operation'])) {
$sRequest .= ' operation: '.$_POST['operation'];
}
$fStop = MyHelpers::getmicrotime();
if (($fStop - $fItopStarted) > self::$m_fSlowQueries) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
$iCurrentMemory = self::memory_get_usage();
$iPeakMemory = self::memory_get_peak_usage();
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oKPILogData = new KpiLogData(KpiLogData::TYPE_REQUEST, 'Page', $sRequest, $fItopStarted, $fStop, '', $iItopInitialMemory, $iCurrentMemory, $iPeakMemory);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
if (!self::$m_bGenerateLegacyReport) {
return;
}
$aBeginTimes = array();
foreach (self::$m_aExecData as $aOpStats)
@@ -114,9 +149,9 @@ class ExecutionKPI
$sHtml = "<hr/>";
$sHtml .= "<div style=\"background-color: grey; padding: 10px;\">";
$sHtml .= "<h3><a name=\"".md5($sExecId)."\">KPIs</a> - ".$_SERVER['REQUEST_URI']." (".$_SERVER['REQUEST_METHOD'].")</h3>";
$sHtml .= "<h3><a name=\"".md5($sExecId)."\">KPIs</a> - $sRequest</h3>";
$oStarted = DateTime::createFromFormat('U.u', $fItopStarted);
$sHtml .= "<p>".$oStarted->format('Y-m-d H:i:s.u')."</p>";
$sHtml .= '<p>'.$oStarted->format('Y-m-d H:i:s.u').'</p>';
$sHtml .= "<p>log_kpi_user_id: ".UserRights::GetUserId()."</p>";
$sHtml .= "<div>";
$sHtml .= "<table border=\"1\" style=\"$sTableStyle\">";
@@ -257,7 +292,7 @@ class ExecutionKPI
$sTotalInter = round($fTotalInter, 3);
$sMinInter = round($fMinInter, 3);
$sMaxInter = round($fMaxInter, 3);
if (($fTotalInter >= $fSlowQueries))
if (($fTotalInter >= self::$m_fSlowQueries))
{
if ($bDisplayHeader)
{
@@ -285,37 +320,19 @@ class ExecutionKPI
self::Report($sHtml);
}
public static function InitStats()
{
// Invoke extensions to initialize the KPI statistics
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oExtensionInstance->InitStats();
}
}
public function __construct()
{
$this->ResetCounters();
self::Push($this);
}
/**
* Stack executions to remove children duration from stats
*
* @param \ExecutionKPI $oExecutionKPI
*/
private static function Push(ExecutionKPI $oExecutionKPI)
{
self::$m_aExecutionStack[] = $oExecutionKPI;
}
/**
* Pop current child and count its duration in its parent
*
* @param float|int $fChildDuration
*/
private static function Pop(float $fChildDuration = 0)
{
array_pop(self::$m_aExecutionStack);
// Update the parent's children duration
$oPrevExecutionKPI = end(self::$m_aExecutionStack);
if ($oPrevExecutionKPI) {
$oPrevExecutionKPI->m_fChildrenDuration += $fChildDuration;
}
}
}
// Get the duration since startup, and reset the counter for the next measure
//
@@ -323,9 +340,15 @@ class ExecutionKPI
{
global $fItopStarted;
if (!self::IsEnabled()) {
return;
}
$aNewEntry = null;
if (self::$m_bEnabled_Duration) {
$fStarted = $this->m_fStarted;
$fStopped = $this->m_fStarted;
if (self::$m_bEnabled_Duration) {
$fStopped = MyHelpers::getmicrotime();
$aNewEntry = array(
'op' => $sOperationDesc,
@@ -336,6 +359,9 @@ class ExecutionKPI
$this->m_fStarted = $fStopped;
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (self::$m_bEnabled_Memory)
{
$iCurrentMemory = self::memory_get_usage();
@@ -345,40 +371,103 @@ class ExecutionKPI
}
$aNewEntry['mem_begin'] = $this->m_iInitialMemory;
$aNewEntry['mem_end'] = $iCurrentMemory;
if (function_exists('memory_get_peak_usage'))
{
$aNewEntry['mem_peak'] = memory_get_peak_usage();
}
$iPeakMemory = self::memory_get_peak_usage();
$aNewEntry['mem_peak'] = $iPeakMemory;
// Reset for the next operation (if the object is recycled)
$this->m_iInitialMemory = $iCurrentMemory;
}
if (!is_null($aNewEntry))
if (self::$m_bEnabled_Duration || self::$m_bEnabled_Memory) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance)
{
$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_REPORT,
'Step',
$sOperationDesc,
$fStarted,
$fStopped,
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
if (!is_null($aNewEntry) && self::$m_bGenerateLegacyReport)
{
self::$m_aExecData[] = $aNewEntry;
}
$this->ResetCounters();
}
public function ComputeStatsForExtension($object, $sMethod)
{
if (!self::IsEnabled()) {
return;
}
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
if (utils::StartsWith($sSignature, '[')) {
$this->ComputeStats('Extension', $sSignature);
}
}
public function ComputeStats($sOperation, $sArguments)
{
if (!self::IsEnabled()) {
return;
}
$fDuration = 0;
if (self::$m_bEnabled_Duration) {
$fStopped = MyHelpers::getmicrotime();
$fDuration = $fStopped - $this->m_fStarted;
$fSelfDuration = $fDuration - $this->m_fChildrenDuration;
if (self::$m_bBlameCaller) {
self::$m_aStats[$sOperation][$sArguments][] = array(
'time' => $fSelfDuration,
'callers' => MyHelpers::get_callstack(1),
);
} else {
self::$m_aStats[$sOperation][$sArguments][] = array(
'time' => $fSelfDuration,
);
}
}
self::Pop($fDuration);
$aCallstack = [];
if (self::$m_bGenerateLegacyReport) {
if (self::$m_bBlameCaller) {
$aCallstack = MyHelpers::get_callstack(1);
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration,
'callers' => $aCallstack,
];
} else {
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration
];
}
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (self::$m_bEnabled_Memory)
{
$iCurrentMemory = self::memory_get_usage();
$iPeakMemory = self::memory_get_peak_usage();
}
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_STATS,
$sOperation,
$sArguments,
$this->m_fStarted,
$fStopped,
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory,
$aCallstack);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
}
protected function ResetCounters()
@@ -408,35 +497,7 @@ class ExecutionKPI
static protected function memory_get_usage()
{
if (function_exists('memory_get_usage'))
{
return memory_get_usage(true);
}
// Copied from the PHP manual
//
//If its Windows
//Tested on Win XP Pro SP2. Should work on Win 2003 Server too
//Doesn't work for 2000
//If you need it to work for 2000 look at http://us2.php.net/manual/en/function.memory-get-usage.php#54642
if (substr(PHP_OS,0,3) == 'WIN')
{
$output = array();
exec('tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output);
return preg_replace( '/[\D]/', '', $output[5] ) * 1024;
}
else
{
//We now assume the OS is UNIX
//Tested on Mac OS X 10.4.6 and Linux Red Hat Enterprise 4
//This should work on most UNIX systems
$pid = getmypid();
exec("ps -eo%mem,rss,pid | grep $pid", $output);
$output = explode(" ", $output[0]);
//rss is given in 1024 byte units
return $output[1] * 1024;
}
return memory_get_usage(true);
}
static public function memory_get_peak_usage($bRealUsage = false)

View File

@@ -583,6 +583,12 @@ class LogChannels
*/
public const DM_CRUD = 'DMCRUD';
/**
* @var string Everything related to the datamodel CRUD
* @since 3.1.0
*/
public const WEB_REQUEST = 'WebRequest';
/**
* @var string Everything related to the event service
* @since 3.1.0
@@ -606,6 +612,8 @@ class LogChannels
public const PORTAL = 'portal';
public const TEMPORARY_OBJECTS = 'TemporaryObjects';
/**
* @var string
* @since 3.1.0
@@ -1130,7 +1138,7 @@ class DeprecatedCallsLog extends LogAPI
parent::Enable($sTargetFile);
if (
(false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME))
(false === defined('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME'))
&& static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD)
) {
set_error_handler([static::class, 'DeprecatedNoticesErrorHandler'], E_DEPRECATED | E_USER_DEPRECATED);
@@ -1406,7 +1414,7 @@ class LogFileRotationProcess implements iScheduledProcess
$iMaxDays = MetaModel::GetConfig()->Get(LogAPI::ENUM_CONFIG_PARAM_PURGE_MAX_KEEP_DAYS);
// Files iterator (*.*)
$oIterator = new \GlobIterator(APPROOT.'log'.DIRECTORY_SEPARATOR.'/*.*');
$oIterator = new \GlobIterator(APPROOT.'log'.DIRECTORY_SEPARATOR.'*.*');
$aLogFiles = iterator_to_array($oIterator);
// Reference date
@@ -1418,6 +1426,11 @@ class LogFileRotationProcess implements iScheduledProcess
// File real path
$sFileRealPath = $oLogFile->getRealPath();
// Check file extension
if(!in_array($oLogFile->getExtension(), ['log','sql','xml'])){
continue;
}
// Compute number of days since last modification
$oDateFileLastModification = new DateTime();
$oDateFileLastModification->setTimestamp($oLogFile->getMTime());

View File

@@ -2927,52 +2927,7 @@ abstract class MetaModel
}
self::$m_sTablePrefix = $sTablePrefix;
// Build the list of available extensions
//
$aInterfaces = [
'iApplicationUIExtension',
'iPreferencesExtension',
'iApplicationObjectExtension',
'iLoginFSMExtension',
'iLoginUIExtension',
'iLogoutExtension',
'iQueryModifier',
'iOnClassInitialization',
'iPopupMenuExtension',
'iPageUIExtension',
'iPageUIBlockExtension',
'iBackofficeLinkedScriptsExtension',
'iBackofficeEarlyScriptExtension',
'iBackofficeScriptExtension',
'iBackofficeInitScriptExtension',
'iBackofficeReadyScriptExtension',
'iBackofficeLinkedStylesheetsExtension',
'iBackofficeStyleExtension',
'iBackofficeDictEntriesExtension',
'iBackofficeDictEntriesPrefixesExtension',
'iPortalUIExtension',
'ModuleHandlerApiInterface',
'iNewsroomProvider',
'iModuleExtension',
];
foreach($aInterfaces as $sInterface)
{
self::$m_aExtensionClassNames[$sInterface] = array();
}
foreach(get_declared_classes() as $sPHPClass)
{
$oRefClass = new ReflectionClass($sPHPClass);
$oExtensionInstance = null;
foreach($aInterfaces as $sInterface)
{
if ($oRefClass->implementsInterface($sInterface) && $oRefClass->isInstantiable())
{
self::$m_aExtensionClassNames[$sInterface][$sPHPClass] = $sPHPClass;
}
}
}
self::InitExtensions();
// Initialize the classes (declared attributes, etc.)
//
@@ -6343,6 +6298,13 @@ abstract class MetaModel
*/
public static function Startup($config, $bModelOnly = false, $bAllowCache = true, $bTraceSourceFiles = false, $sEnvironment = 'production')
{
// Startup on a new environment is not supported
static $bStarted = false;
if ($bStarted) {
return;
}
$bStarted = true;
self::$m_sEnvironment = $sEnvironment;
try {
@@ -6421,7 +6383,9 @@ abstract class MetaModel
ExecutionKPI::EnableDuration(self::$m_oConfig->Get('log_kpi_duration'));
ExecutionKPI::EnableMemory(self::$m_oConfig->Get('log_kpi_memory'));
ExecutionKPI::SetAllowedUser(self::$m_oConfig->Get('log_kpi_user_id'));
ExecutionKPI::SetAllowedUser(self::$m_oConfig->Get('log_kpi_user_id'));
ExecutionKPI::SetGenerateLegacyReport(self::$m_oConfig->Get('log_kpi_generate_legacy_report'));
ExecutionKPI::SetSlowQueries(self::$m_oConfig->Get('log_kpi_slow_queries'));
self::$m_bSkipCheckToWrite = self::$m_oConfig->Get('skip_check_to_write');
self::$m_bSkipCheckExtKeys = self::$m_oConfig->Get('skip_check_ext_keys');
@@ -6540,6 +6504,7 @@ abstract class MetaModel
CMDBSource::InitFromConfig(self::$m_oConfig);
// Later when timezone implementation is correctly done: CMDBSource::SetTimezone($sDBTimezone);
ExecutionKPI::InitStats();
}
/**
@@ -6571,6 +6536,19 @@ abstract class MetaModel
return $value;
}
/**
* @internal Used for resetting the configuration during automated tests
* @param \Config $oConfiguration
*
* @return void
* @since 3.0.4 3.1.1 3.2.0
*/
public static function SetConfig(Config $oConfiguration)
{
self::$m_oConfig = $oConfiguration;
}
/**
* @return Config
*/
@@ -6852,25 +6830,21 @@ abstract class MetaModel
* $bMustBeFound=false)
* @throws CoreException if no result found and $bMustBeFound=true
* @throws ArchivedObjectException if archive mode disabled and result is archived and $bMustBeFound=true
* @throws \Exception
*
*/
public static function GetObject($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false, $aModifierProperties = null)
{
$oObject = self::GetObjectWithArchive($sClass, $iKey, $bMustBeFound, $bAllowAllData, $aModifierProperties);
if (empty($oObject))
{
if (empty($oObject)) {
return null;
}
if (!utils::IsArchiveMode() && $oObject->IsArchived())
{
if (!utils::IsArchiveMode() && $oObject->IsArchived()) {
if ($bMustBeFound) {
throw new ArchivedObjectException("The object $sClass::$iKey is archived");
} else {
return null;
}
return null;
}
return $oObject;
@@ -7642,6 +7616,57 @@ abstract class MetaModel
unset(self::$m_aReentranceProtection[get_class($oObject)][$oObject->GetKey()]);
}
}
/**
* For test purpose
* @throws \ReflectionException
* @since 3.1.0
*/
public static function InitExtensions()
{
// Build the list of available extensions
//
$aInterfaces = [
'iLoginFSMExtension',
'iLogoutExtension',
'iLoginUIExtension',
'iPreferencesExtension',
'iApplicationUIExtension',
'iApplicationObjectExtension',
'iPopupMenuExtension',
'iPageUIExtension',
'iPageUIBlockExtension',
'iBackofficeLinkedScriptsExtension',
'iBackofficeEarlyScriptExtension',
'iBackofficeScriptExtension',
'iBackofficeInitScriptExtension',
'iBackofficeReadyScriptExtension',
'iBackofficeLinkedStylesheetsExtension',
'iBackofficeStyleExtension',
'iBackofficeDictEntriesExtension',
'iBackofficeDictEntriesPrefixesExtension',
'iPortalUIExtension',
'iQueryModifier',
'iOnClassInitialization',
'iModuleExtension',
'iKPILoggerExtension',
'ModuleHandlerApiInterface',
'iNewsroomProvider',
];
foreach ($aInterfaces as $sInterface) {
self::$m_aExtensionClassNames[$sInterface] = array();
}
foreach (get_declared_classes() as $sPHPClass) {
$oRefClass = new ReflectionClass($sPHPClass);
$oExtensionInstance = null;
foreach ($aInterfaces as $sInterface) {
if ($oRefClass->implementsInterface($sInterface) && $oRefClass->isInstantiable()) {
self::$m_aExtensionClassNames[$sInterface][$sPHPClass] = $sPHPClass;
}
}
}
}
}

View File

@@ -257,7 +257,7 @@ class iTopMutex
$this->hDBLink = CMDBSource::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $bTlsEnabled, $sTlsCA, false);
if (!$this->hDBLink) {
throw new Exception("Could not connect to the DB server (host=$sServer, user=$sUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
throw new MySQLException('Could not connect to the DB server '.mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno(), array('host' => $sDBHost, 'user' => $sDBUser));
}
// Make sure that the server variable `wait_timeout` is at least 86400 seconds for this connection,

View File

@@ -3526,6 +3526,7 @@ class CharConcatWSExpression extends CharConcatExpression
$aRes = array();
foreach ($this->m_aExpressions as $oExpr)
{
// TODO: Seems weird, this should rather be $aRes[] = $oExpr->Evaluate($aArgs);
$aRes .= $oExpr->Evaluate($aArgs);
}
return implode($this->m_separator, $aRes);

View File

@@ -86,6 +86,33 @@ class ormDocument
{
return ($this->m_data == null);
}
/**
* @param \ormDocument $oCompared
*
* @return bool True if the current ormDocument is equals to $oCompared EXCEPT for its download count. False if any other property is different OR if count is the same.
* @since 3.1.0 N°6502
*/
public function EqualsExceptDownloadsCount(ormDocument $oCompared): bool
{
// First checking equality on others properties
if ($oCompared->GetData() !== $this->GetData()) {
return false;
}
if ($oCompared->GetMimeType() !== $this->GetMimeType()) {
return false;
}
if ($oCompared->GetFileName() !== $this->GetFileName()) {
return false;
}
// Finally check equality of the download count
if ($oCompared->GetDownloadsCount() === $this->GetDownloadsCount()) {
return false;
} else {
return true;
}
}
public function GetMimeType()
{

View File

@@ -98,4 +98,14 @@ class PluginManager
return $oInstance;
}
/**
* For test purpose
* @return void
* @since 3.1.0
*/
protected static function ResetPlugins()
{
self::$m_aExtensionClasses = null;
}
}

View File

@@ -43,6 +43,12 @@
class SimpleCrypt
{
/**
* @var \SimpleCrypt
* @since 3.1.0 N°5388
*/
protected $oEngine;
public static function GetNewDefaultParams()
{
if(function_exists('sodium_crypto_secretbox_open') && function_exists('random_bytes')){
@@ -62,6 +68,7 @@ class SimpleCrypt
$sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
return $sEngineName::GetNewDefaultParams();
}
/**
* Constructor
* @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt, Sodium or OpenSSL

View File

@@ -218,8 +218,8 @@ class SQLObjectQueryBuilder
continue;
}
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
// Skip this attribute if not made of SQL columns
if (count($oAttDef->GetSQLExpressions()) == 0)
// Skip this attribute if not made of SQL columns nor in current table
if (count($oAttDef->GetSQLExpressions()) == 0 || $oAttDef->IsExternalField())
{
continue;
}

View File

@@ -50,7 +50,7 @@ abstract class Trigger extends cmdbAbstractObject
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("action_list",
array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array())));
$aTags = ContextTag::GetTags();
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
// "complement" is a computed field, fed by Trigger sub-classes, in general in ComputeValues method, for eg. the TriggerOnObject fed it with target_class info
MetaModel::Init_AddAttribute(new AttributeString("complement", array("allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
@@ -121,7 +121,9 @@ abstract class Trigger extends cmdbAbstractObject
$oAction = MetaModel::GetObject('Action', $iActionId);
if ($oAction->IsActive())
{
$oKPI = new ExecutionKPI();
$oAction->DoExecute($this, $aContextArgs);
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
}
}
}

View File

@@ -761,14 +761,25 @@ class UserRights
protected static $m_aCacheContactPictureAbsUrl = [];
/** @var UserRightsAddOnAPI $m_oAddOn */
protected static $m_oAddOn;
protected static $m_oUser;
protected static $m_oRealUser;
protected static $m_oUser = null;
protected static $m_oRealUser = null;
protected static $m_sSelfRegisterAddOn = null;
protected static $m_aAdmins = array();
protected static $m_aPortalUsers = array();
/** @var array array('sName' => $sName, 'bSuccess' => $bSuccess); */
private static $m_sLastLoginStatus = null;
/**
* @return void
* @since 3.0.4 3.1.1 3.2.0
*/
protected static function ResetCurrentUserData()
{
self::$m_oUser = null;
self::$m_oRealUser = null;
self::$m_sLastLoginStatus = null;
}
/**
* @param string $sModuleName
*
@@ -787,8 +798,7 @@ class UserRights
}
self::$m_oAddOn = new $sModuleName;
self::$m_oAddOn->Init();
self::$m_oUser = null;
self::$m_oRealUser = null;
self::ResetCurrentUserData();
}
/**
@@ -855,6 +865,8 @@ class UserRights
*/
public static function Login($sLogin, $sAuthentication = 'any')
{
static::Logoff();
$oUser = self::FindUser($sLogin, $sAuthentication);
if (is_null($oUser))
{
@@ -872,6 +884,17 @@ class UserRights
return true;
}
/**
* @return void
* @since 3.0.4 3.1.1 3.2.0
*/
public static function Logoff()
{
self::ResetCurrentUserData();
Dict::SetUserLanguage(null);
self::_ResetSessionCache();
}
/**
* @param string $sLogin Login of the user to check the credentials for
* @param string $sPassword

View File

@@ -97,7 +97,7 @@ abstract class ValueSetDefinition
public function SortValues(array &$aValues): void
{
// Sort alphabetically on values
asort($aValues);
natcasesort($aValues);
}
abstract protected function LoadValues($aArgs);
@@ -465,11 +465,11 @@ class ValueSetEnum extends ValueSetDefinition
{
protected $m_values;
/**
* @var bool $bSortByValue If true, values will be sorted at runtime, otherwise it is sorted at compile time in a predefined order.
* @var bool $bSortByValues If true, values will be sorted at runtime (on their values, not their keys), otherwise it is sorted at compile time in a predefined order.
* {@see \MFCompiler::CompileAttributeEnumValues()} for complete reasons.
* @since 3.1.0 N°1646
*/
protected bool $bSortByValue;
protected bool $bSortByValues;
/**
* @param array|string $Values
@@ -477,20 +477,20 @@ class ValueSetEnum extends ValueSetDefinition
*
* @since 3.1.0 N°1646 Add $bLocalizedSort parameter
*/
public function __construct($Values, bool $bSortByValue = false)
public function __construct($Values, bool $bSortByValues = false)
{
$this->m_values = $Values;
$this->bSortByValue = $bSortByValue;
$this->bSortByValues = $bSortByValues;
}
/**
* @see \ValueSetEnum::$bSortByValue
* @see \ValueSetEnum::$bSortByValues
* @return bool
* @since 3.1.0 N°1646
*/
public function IsSortedByValues(): bool
{
return $this->bSortByValue;
return $this->bSortByValues;
}
// Helper to export the data model
@@ -507,8 +507,8 @@ class ValueSetEnum extends ValueSetDefinition
public function SortValues(array &$aValues): void
{
// Force sort by values only if necessary
if ($this->bSortByValue) {
asort($aValues);
if ($this->bSortByValues) {
natcasesort($aValues);
return;
}
@@ -548,9 +548,13 @@ class ValueSetEnum extends ValueSetDefinition
class ValueSetEnumPadded extends ValueSetEnum
{
public function __construct($Values)
/**
* @inheritDoc
* @since 3.1.0 N°6448 Add $bSortByValues parameter
*/
public function __construct($Values, bool $bSortByValues = false)
{
parent::__construct($Values);
parent::__construct($Values, $bSortByValues);
if (is_string($Values))
{
$this->LoadValues(null);
@@ -562,6 +566,7 @@ class ValueSetEnumPadded extends ValueSetEnum
$aPaddedValues = array();
foreach ($this->m_aValues as $sKey => $sVal)
{
// Pad keys to the min. length required by the \AttributeSet
$sKey = str_pad($sKey, 3, '_', STR_PAD_LEFT);
$aPaddedValues[$sKey] = $sVal;
}
@@ -610,7 +615,7 @@ class ValueSetEnumClasses extends ValueSetEnum
public function __construct($sCategories = '', $sAdditionalValues = '')
{
$this->m_sCategories = $sCategories;
parent::__construct($sAdditionalValues);
parent::__construct($sAdditionalValues, true /* Classes are always sorted alphabetically */);
}
protected function LoadValues($aArgs)

View File

@@ -20,6 +20,8 @@ $ibo-dashlet-badge--icon--size: 48px !default;
$ibo-dashlet-badge--action-icon--margin-right: $ibo-spacing-300 !default;
$ibo-dashlet-badge--body--tooltip-title--margin-bottom: $ibo-spacing-500 !default;
/* CSS variables (can be changed directly from the browser) */
:root {
--ibo-dashlet-badge--min-width: #{$ibo-dashlet-badge--min-width};
@@ -74,18 +76,27 @@ $ibo-dashlet-badge--action-icon--margin-right: $ibo-spacing-300 !default;
@extend %ibo-hyperlink-inherited-colors;
}
}
.ibo-dashlet-badge--action-list-count{
margin-right: $ibo-dashlet-badge--action-list-count--margin-right;
@extend %ibo-font-ral-bol-450;
.ibo-dashlet-badge--action-list-count {
margin-right: $ibo-dashlet-badge--action-list-count--margin-right;
@extend %ibo-font-ral-bol-450;
}
.ibo-dashlet-badge--action-list-label{
display: inline-block;
@extend %ibo-text-truncated-with-ellipsis;
.ibo-dashlet-badge--action-list-label {
display: inline-block;
@extend %ibo-text-truncated-with-ellipsis;
}
.ibo-dashlet-badge--action-create{
@extend %ibo-baseline-centered-content;
@extend %ibo-font-size-150;
.ibo-dashlet-badge--action-create {
@extend %ibo-baseline-centered-content;
@extend %ibo-font-size-150;
}
.ibo-dashlet-badge--action-create-icon{
margin-right: $ibo-dashlet-badge--action-icon--margin-right;
.ibo-dashlet-badge--action-create-icon {
margin-right: $ibo-dashlet-badge--action-icon--margin-right;
}
.ibo-dashlet-badge--body--tooltip-title {
@extend %ibo-font-weight-600;
margin-bottom: $ibo-dashlet-badge--body--tooltip-title--margin-bottom;
}

View File

@@ -25,5 +25,7 @@
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:UserLDAP' => 'LDAP-Benutzer',
'Class:UserLDAP+' => 'Benutzer, der via LDAP authentifiziert wird',
'UserLDAP:server' => 'LDAP specifics~~',
'Class:UserLDAP/Attribute:ldap_server' => 'LDAP-Server',
'Class:UserLDAP/Attribute:ldap_server+' => 'Optional: LDAP-Server, der zur Authentifizierung verwendet werden soll, falls mehrere LDAP-Server konfiguriert sind.',
'UserLDAP:server' => 'LDAP-Einstellungen',
));

View File

@@ -462,6 +462,12 @@ class DatabaseAnalyzer
$aCols = $oAttDef->GetSQLExpressions(); // Workaround a PHP bug: sometimes issuing a Notice if invoking current(somefunc())
$sMyAttributeField = current($aCols); // get the first column for the moment
$sFilter = "FROM `$sTable` WHERE `$sTable`.`$sMyAttributeField` NOT IN ($sExpectedValues)";
if ($oAttDef->IsNullAllowed()) {
// NotEmptyToSql should have been in AttributeDefinition, as a workaround the search type is used
$sSearchType = $oAttDef->GetSearchType();
$sCondition = $this->NotEmptyToSql("`$sTable`.`$sMyAttributeField`", $sSearchType);
$sFilter .= " AND $sCondition";
}
$sDelete = "DELETE `$sTable`";
$sSelect = "SELECT DISTINCT `$sTable`.`$sKeyField` AS id, `$sTable`.`$sMyAttributeField` AS value";
$sSelWrongRecs = "$sSelect $sFilter";
@@ -492,6 +498,26 @@ class DatabaseAnalyzer
}
}
/**
* @param $sRef
* @param string $sSearchType
*
* @return string
* @since 3.1.0 N°6442
*/
private function NotEmptyToSql($sRef, string $sSearchType)
{
switch ($sSearchType) {
case AttributeDefinition::SEARCH_WIDGET_TYPE_NUMERIC:
case AttributeDefinition::SEARCH_WIDGET_TYPE_EXTERNAL_FIELD:
case AttributeDefinition::SEARCH_WIDGET_TYPE_DATE:
case AttributeDefinition::SEARCH_WIDGET_TYPE_DATE_TIME:
return "ISNULL({$sRef}) = 0";
}
return "({$sRef} != '')";
}
/**
* Check user accounts without profile
*

View File

@@ -43,7 +43,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'DBTools:ShowAll' => 'Alle Fehler anzeigen',
'DBTools:Inconsistencies' => 'Datenbank-Inkonsistenzen',
'DBTools:DetailedErrorTitle' => '%2$s Fehler(s) in der Klasse %1$s: %3$s',
'DBTools:DetailedErrorLimit' => 'List limited to %1$s errors~~',
'DBTools:DetailedErrorLimit' => 'Liste auf %1$s Fehler begrenzt',
'DBAnalyzer-Integrity-OrphanRecord' => 'Verwaister Eintrag in `%1$s`, er sollte eine Entsprechung in Tabelle `%2$s` haben',
'DBAnalyzer-Integrity-InvalidExtKey' => 'Ungültiger Externer Key %1$s (Spalte: `%2$s.%3$s`)',
'DBAnalyzer-Integrity-MissingExtKey' => 'Fehlender Externer Key %1$s (Spalte: `%2$s.%3$s`)',

View File

@@ -74,7 +74,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Attachments:File:Uploader' => 'hochgeladen von',
'Attachments:File:Size' => 'Größe',
'Attachments:File:MimeType' => 'Typ',
'Attachments:File:DownloadsCount' => 'Downloads~~',
'Attachments:File:DownloadsCount' => 'Downloads',
));
//
// Class: Attachment
@@ -94,6 +94,6 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
//
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:TriggerOnAttachmentDownload' => 'Trigger (on object\'s attachment download)~~',
'Class:TriggerOnAttachmentDownload+' => 'Trigger on object\'s attachment download of [a child class of] the given class~~',
'Class:TriggerOnAttachmentDownload' => 'Trigger (beim Herunterladen eines Attachment eines Objekts)',
'Class:TriggerOnAttachmentDownload+' => 'Trigger für das Herunterladen des Attachments der angegebenen Klasse oder einer Unterklasse',
));

View File

@@ -344,6 +344,7 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
while ($oAttachment = $oSet->Fetch())
{
$oTempAttachment = clone $oAttachment;
$oTempAttachment->Set('expire', time() + utils::GetConfig()->Get('draft_attachments_lifetime'));
$oTempAttachment->Set('item_id', null);
$oTempAttachment->Set('temp_id', $sTempId);
$oTempAttachment->DBInsert();

View File

@@ -102,14 +102,19 @@ if (!function_exists('sys_get_temp_dir'))
}
/**
* @param int $iRefTime Reference date time as a unix timestamp
*
* @return string Absolute path to the backup file, WITHOUT the file extension (`.tar.gz`)
* @throws \Exception
*/
function MakeArchiveFileName($iRefTime = null)
{
$sDefaultBackupFileName = sys_get_temp_dir().'/'."__DB__-%Y-%m-%d";
$sBackupFile = utils::ReadParam('backup_file', $sDefaultBackupFileName, true, 'raw_data');
$oBackup = new DBBackup();
$oDateTime = $iRefTime !== null ? new DateTime($iRefTime) : new DateTime();
$oDateTime = $iRefTime !== null ? DateTime::createFromFormat('U', $iRefTime) : new DateTime();
$sBackupFile = $oBackup->MakeName($sBackupFile, $oDateTime);
return $sBackupFile;

View File

@@ -235,13 +235,16 @@ class DBRestore extends DBBackup
if (in_array($oFileInfo->getFilename(), $aStandardFiles)) {
continue;
}
if (strncmp($oFileInfo->getPathname(), $sDataDir.'/production-modules', strlen($sDataDir.'/production-modules')) == 0) {
// Normalize filenames to cope with Windows backslashes
$sPath = str_replace('\\', '/', $oFileInfo->getPathname());
$sRefPath = str_replace('\\', '/', $sDataDir.'/production-modules');
if (strncmp($sPath, $sRefPath, strlen($sRefPath)) == 0) {
continue;
}
$aExtraFiles[$oFileInfo->getPathname()] = APPROOT.substr($oFileInfo->getPathname(), strlen($sDataDir));
}
return $aExtraFiles;
}
}

View File

@@ -197,7 +197,6 @@
<count_max>0</count_max>
<ext_key_to_remote>providercontract_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="services_list" xsi:type="AttributeLinkedSetIndirect" _delta="define">
<linked_class>lnkFunctionalCIToService</linked_class>
@@ -206,7 +205,6 @@
<count_max>0</count_max>
<ext_key_to_remote>service_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -385,7 +383,6 @@
<count_max>0</count_max>
<ext_key_to_remote>contract_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="services_list" xsi:type="AttributeLinkedSetIndirect" _delta="define">
<linked_class>lnkDocumentToService</linked_class>
@@ -394,7 +391,6 @@
<count_max>0</count_max>
<ext_key_to_remote>service_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods/>

View File

@@ -33,7 +33,7 @@
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkFunctionalCIToProviderContract' => 'Verknüpfung FunctionalCI/Provider-Vertrag',
'Class:lnkFunctionalCIToProviderContract+' => '',
'Class:lnkFunctionalCIToProviderContract/Name' => '%1$s / %2$s~~',
'Class:lnkFunctionalCIToProviderContract/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id' => 'Provider-Vertrag',
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_id+' => '',
'Class:lnkFunctionalCIToProviderContract/Attribute:providercontract_name' => 'Provider-Vertragsname',
@@ -51,7 +51,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkFunctionalCIToService' => 'Verknüpfung FunctionalCI/Service',
'Class:lnkFunctionalCIToService+' => '',
'Class:lnkFunctionalCIToService/Name' => '%1$s / %2$s~~',
'Class:lnkFunctionalCIToService/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Service',
'Class:lnkFunctionalCIToService/Attribute:service_id+' => '',
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Service-Name',
@@ -79,7 +79,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Document/Attribute:contracts_list' => 'Verträge',
'Class:Document/Attribute:contracts_list+' => 'All the contracts linked to this document~~',
'Class:Document/Attribute:contracts_list+' => 'Alle mit diesem Dokument verknüpften Verträge',
'Class:Document/Attribute:services_list' => 'Services',
'Class:Document/Attribute:services_list+' => 'All the services linked to this document~~',
'Class:Document/Attribute:services_list+' => 'Alle mit diesem Dokument verknüpften Services',
));

View File

@@ -139,7 +139,6 @@
<count_max>0</count_max>
<ext_key_to_remote>ticket_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
</class>

View File

@@ -33,7 +33,7 @@
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkFunctionalCIToTicket' => 'Verknüpfung FunctionalCI/Ticket',
'Class:lnkFunctionalCIToTicket+' => '',
'Class:lnkFunctionalCIToTicket/Name' => '%1$s / %2$s~~',
'Class:lnkFunctionalCIToTicket/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Ticket',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Referenz',
@@ -57,5 +57,5 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
//
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:FunctionalCI/Attribute:tickets_list' => 'Tickets',
'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~',
'Class:FunctionalCI/Attribute:tickets_list+' => 'Alle Ticket, die mit diesem CI verknüpft sind',
));

View File

@@ -33,7 +33,7 @@
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkFunctionalCIToTicket' => 'Lien CI / Ticket',
'Class:lnkFunctionalCIToTicket+' => '',
'Class:lnkFunctionalCIToTicket/Name' => '%1$s / %2$s~~',
'Class:lnkFunctionalCIToTicket/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Ticket',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Référence',

View File

@@ -264,8 +264,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="related_incident_list" xsi:type="AttributeLinkedSet">
<linked_class>Incident</linked_class>
@@ -273,8 +271,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="related_problems_list" xsi:type="AttributeLinkedSet">
<linked_class>Problem</linked_class>
@@ -282,8 +278,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="child_changes_list" xsi:type="AttributeLinkedSet">
<linked_class>Change</linked_class>
@@ -292,8 +286,6 @@
<filter><![CDATA[SELECT Change WHERE id != :this->id]]></filter>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<lifecycle>

View File

@@ -27,21 +27,21 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:Change:Overview' => 'Übersicht',
'Menu:Change:Overview+' => '',
'Menu:NewChange' => 'Neuer Change',
'Menu:NewChange+' => 'Ein neues Change Ticket erstellen',
'Menu:SearchChanges' => 'Nach Changes suchen',
'Menu:SearchChanges+' => 'Nach Change Tickets suchen',
'Menu:NewChange+' => 'Einen neuen Change erstellen',
'Menu:SearchChanges' => 'Suche nach Changes',
'Menu:SearchChanges+' => 'Unter den bestehenden Changes suchen',
'Menu:Change:Shortcuts' => 'Shortcuts',
'Menu:Change:Shortcuts+' => '',
'Menu:WaitingAcceptance' => 'Changes, die auf Annahme warten',
'Menu:WaitingAcceptance+' => '',
'Menu:WaitingAcceptance+' => 'Changes, die auf Annahme warten',
'Menu:WaitingApproval' => 'Changes, die auf Genehmigung warten',
'Menu:WaitingApproval+' => '',
'Menu:WaitingApproval+' => 'Changes, die auf Genehmigung warten',
'Menu:Changes' => 'Offene Changes',
'Menu:Changes+' => 'Alle Offene Changes',
'Menu:MyChanges' => 'Mir zugewiesene Changes',
'Menu:MyChanges+' => 'Mir zugewiesene Changes (als Bearbeiter)',
'Menu:Changes+' => 'Offene Changes',
'Menu:MyChanges' => 'Changes, die mir zugewiesen sind',
'Menu:MyChanges+' => 'Changes, die mir zugewiesen sind',
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Changes der letzten sieben Tage nach Kategorie',
'UI-ChangeManagementOverview-Last-7-days' => 'Anzahl der Changes der letzten sieben Tage',
'UI-ChangeManagementOverview-Last-7-days' => 'Zahl der Changes in den letzten sieben Tagen',
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Changes der letzten sieben Tage nach Typ',
'UI-ChangeManagementOverview-ChangeByStatus-last-7-days' => 'Changes der letzten sieben Tage nach Status',
'Tickets:Related:OpenChanges' => 'Offene Changes',
@@ -127,14 +127,14 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Change/Attribute:parent_name' => 'Parent Change Ref',
'Class:Change/Attribute:parent_name+' => '',
'Class:Change/Attribute:related_request_list' => 'Verwandte Requests',
'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~',
'Class:Change/Attribute:related_request_list+' => 'Alle Benutzeranfragen, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:related_problems_list' => 'Verwandte Probleme',
'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~',
'Class:Change/Attribute:related_problems_list+' => 'Alle Probleme, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:related_incident_list' => 'Verwandte Incidents',
'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~',
'Class:Change/Attribute:related_incident_list+' => 'Alle Incidents, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:child_changes_list' => 'Abgeleitete Changes',
'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~',
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Friendly Name',
'Class:Change/Attribute:child_changes_list+' => 'Alle abgeleiteten Changes, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Change Anzeigename',
'Class:Change/Attribute:parent_id_friendlyname+' => '',
'Class:Change/Attribute:parent_id_finalclass_recall' => 'Change-Typ',
'Class:Change/Attribute:parent_id_finalclass_recall+' => '',

View File

@@ -198,7 +198,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:ApprovedChange' => 'Changements pré-approuvés',
'Class:ApprovedChange' => 'Changement pré-approuvé',
'Class:ApprovedChange+' => '',
'Class:ApprovedChange/Attribute:approval_date' => 'Date d\'approbation',
'Class:ApprovedChange/Attribute:approval_date+' => '',
@@ -268,7 +268,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
//
Dict::Add('FR FR', 'French', 'Français', array(
'Class:EmergencyChange' => 'Changement d\'Urgence',
'Class:EmergencyChange' => 'Changement urgent',
'Class:EmergencyChange+' => '',
'Class:EmergencyChange/Stimulus:ev_validate' => 'Valider',
'Class:EmergencyChange/Stimulus:ev_validate+' => '',

View File

@@ -192,8 +192,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="related_incident_list" xsi:type="AttributeLinkedSet">
<linked_class>Incident</linked_class>
@@ -201,8 +199,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="related_problems_list" xsi:type="AttributeLinkedSet">
<linked_class>Problem</linked_class>
@@ -210,8 +206,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="child_changes_list" xsi:type="AttributeLinkedSet">
<linked_class>Change</linked_class>
@@ -220,8 +214,6 @@
<filter><![CDATA[SELECT Change WHERE id != :this->id]]></filter>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<lifecycle>

View File

@@ -27,19 +27,19 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:Change:Overview' => 'Übersicht',
'Menu:Change:Overview+' => '',
'Menu:NewChange' => 'Neuer Change',
'Menu:NewChange+' => '',
'Menu:NewChange+' => 'Einen neuen Change erstellen',
'Menu:SearchChanges' => 'Suche nach Changes',
'Menu:SearchChanges+' => '',
'Menu:SearchChanges+' => 'Unter den bestehenden Changes suchen',
'Menu:Change:Shortcuts' => 'Shortcuts',
'Menu:Change:Shortcuts+' => '',
'Menu:WaitingAcceptance' => 'Changes, die auf Annahme warten',
'Menu:WaitingAcceptance+' => '',
'Menu:WaitingAcceptance+' => 'Changes, die auf Annahme warten',
'Menu:WaitingApproval' => 'Changes, die auf Genehmigung warten',
'Menu:WaitingApproval+' => '',
'Menu:WaitingApproval+' => 'Changes, die auf Genehmigung warten',
'Menu:Changes' => 'Offene Changes',
'Menu:Changes+' => '',
'Menu:Changes+' => 'Offene Changes',
'Menu:MyChanges' => 'Changes, die mir zugewiesen sind',
'Menu:MyChanges+' => '',
'Menu:MyChanges+' => 'Changes, die mir zugewiesen sind',
'UI-ChangeManagementOverview-ChangeByCategory-last-7-days' => 'Changes der letzten sieben Tage nach Kategorie',
'UI-ChangeManagementOverview-Last-7-days' => 'Zahl der Changes in den letzten sieben Tagen',
'UI-ChangeManagementOverview-ChangeByDomain-last-7-days' => 'Changes der letzten sieben Tage nach Typ',
@@ -83,17 +83,17 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Change/Attribute:category' => 'Kategorie',
'Class:Change/Attribute:category+' => '',
'Class:Change/Attribute:category/Value:application' => 'Applikation',
'Class:Change/Attribute:category/Value:application+' => '',
'Class:Change/Attribute:category/Value:application+' => 'Applikation',
'Class:Change/Attribute:category/Value:hardware' => 'Hardware',
'Class:Change/Attribute:category/Value:hardware+' => '',
'Class:Change/Attribute:category/Value:hardware+' => 'Hardware',
'Class:Change/Attribute:category/Value:network' => 'Netzwerk',
'Class:Change/Attribute:category/Value:network+' => '',
'Class:Change/Attribute:category/Value:network+' => 'Netzwerk',
'Class:Change/Attribute:category/Value:other' => 'Andere',
'Class:Change/Attribute:category/Value:other+' => '',
'Class:Change/Attribute:category/Value:other+' => 'Andere',
'Class:Change/Attribute:category/Value:software' => 'Software',
'Class:Change/Attribute:category/Value:software+' => '',
'Class:Change/Attribute:category/Value:software+' => 'Software',
'Class:Change/Attribute:category/Value:system' => 'System',
'Class:Change/Attribute:category/Value:system+' => '',
'Class:Change/Attribute:category/Value:system+' => 'System',
'Class:Change/Attribute:reject_reason' => 'Ablehnungsgrund',
'Class:Change/Attribute:reject_reason+' => '',
'Class:Change/Attribute:changemanager_id' => 'Change Manager',
@@ -111,14 +111,14 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Change/Attribute:fallback_plan' => 'Fallback-Plan',
'Class:Change/Attribute:fallback_plan+' => '',
'Class:Change/Attribute:related_request_list' => 'Verwandte Requests',
'Class:Change/Attribute:related_request_list+' => 'All the user requests linked to this change~~',
'Class:Change/Attribute:related_request_list+' => 'Alle Benutzeranfragen, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:related_incident_list' => 'Verwandte Incidents',
'Class:Change/Attribute:related_incident_list+' => 'All the incidents linked to this change~~',
'Class:Change/Attribute:related_incident_list+' => 'Alle Incidents, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:related_problems_list' => 'Verwandte Probleme',
'Class:Change/Attribute:related_problems_list+' => 'All the problems linked to this change~~',
'Class:Change/Attribute:related_problems_list+' => 'Alle Probleme, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:child_changes_list' => 'Abgeleitete Changes',
'Class:Change/Attribute:child_changes_list+' => 'All the sub changes linked to this change~~',
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Change',
'Class:Change/Attribute:child_changes_list+' => 'Alle abgeleiteten Changes, die mit diesem Change verknüpft sind',
'Class:Change/Attribute:parent_id_friendlyname' => 'Parent Change Anzeigename',
'Class:Change/Attribute:parent_id_friendlyname+' => '',
'Class:Change/Stimulus:ev_assign' => 'Zuweisen',
'Class:Change/Stimulus:ev_assign+' => '',

View File

@@ -84,7 +84,6 @@
<count_max>0</count_max>
<ext_key_to_remote>contact_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="documents_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkDocumentToFunctionalCI</linked_class>
@@ -93,7 +92,6 @@
<count_max>0</count_max>
<ext_key_to_remote>document_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="applicationsolution_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkApplicationSolutionToFunctionalCI</linked_class>
@@ -102,7 +100,6 @@
<count_max>0</count_max>
<ext_key_to_remote>applicationsolution_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="softwares_list" xsi:type="AttributeLinkedSet">
<linked_class>SoftwareInstance</linked_class>
@@ -111,8 +108,6 @@
<tracking_level>all</tracking_level>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>property</relation_type>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -559,7 +554,6 @@
<count_max>0</count_max>
<ext_key_to_remote>networkdevice_id</ext_key_to_remote>
<duplicates>true</duplicates>
<read_only>false</read_only>
</field>
<field id="physicalinterface_list" xsi:type="AttributeLinkedSet">
<linked_class>PhysicalInterface</linked_class>
@@ -568,8 +562,6 @@
<tracking_level>all</tracking_level>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>property</relation_type>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -804,8 +796,6 @@
<tracking_level>all</tracking_level>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>property</relation_type>
<read_only>false</read_only>
</field>
<field id="san_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkSanToDatacenterDevice</linked_class>
@@ -814,7 +804,6 @@
<count_max>0</count_max>
<ext_key_to_remote>san_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="redundancy" xsi:type="AttributeRedundancySettings">
<sql>redundancy</sql>
@@ -1036,7 +1025,6 @@
<count_max>0</count_max>
<ext_key_to_remote>connectableci_id</ext_key_to_remote>
<duplicates>true</duplicates>
<read_only>false</read_only>
</field>
<field id="iosversion_id" xsi:type="AttributeExternalKey">
<sql>iosversion_id</sql>
@@ -1376,7 +1364,6 @@
<count_max>0</count_max>
<ext_key_to_remote>volume_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -1662,7 +1649,6 @@
<count_max>0</count_max>
<ext_key_to_remote>functionalci_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="businessprocess_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkApplicationSolutionToBusinessProcess</linked_class>
@@ -1671,7 +1657,6 @@
<count_max>0</count_max>
<ext_key_to_remote>businessprocess_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="status" xsi:type="AttributeEnum">
<values>
@@ -1840,7 +1825,6 @@
<count_max>0</count_max>
<ext_key_to_remote>applicationsolution_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="status" xsi:type="AttributeEnum">
<values>
@@ -2185,8 +2169,6 @@
<tracking_level>all</tracking_level>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>property</relation_type>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -2341,8 +2323,6 @@
<tracking_level>all</tracking_level>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>property</relation_type>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -2497,8 +2477,6 @@
<tracking_level>all</tracking_level>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>property</relation_type>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -3364,7 +3342,6 @@
<count_max>0</count_max>
<ext_key_to_remote>document_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="type" xsi:type="AttributeEnum">
<sort_type>label</sort_type>
@@ -3396,8 +3373,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="softwarepatch_list" xsi:type="AttributeLinkedSet">
<linked_class>SoftwarePatch</linked_class>
@@ -3405,8 +3380,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="softwarelicence_list" xsi:type="AttributeLinkedSet">
<linked_class>SoftwareLicence</linked_class>
@@ -3414,8 +3387,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -3542,7 +3513,6 @@
<count_max>0</count_max>
<ext_key_to_remote>document_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="description" xsi:type="AttributeText">
<sql>description</sql>
@@ -3628,7 +3598,6 @@
<count_max>0</count_max>
<ext_key_to_remote>functionalci_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="osversion_id" xsi:type="AttributeExternalKey">
<sql>osversion_id</sql>
@@ -3741,7 +3710,6 @@
<count_max>0</count_max>
<ext_key_to_remote>softwareinstance_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -3845,7 +3813,6 @@
<count_max>0</count_max>
<ext_key_to_remote>document_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="org_id" xsi:type="AttributeExternalKey">
<sql>org_id</sql>
@@ -4035,8 +4002,6 @@
<edit_mode>none</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>true</read_only>
</field>
<field id="servers_list" xsi:type="AttributeLinkedSet">
<linked_class>Server</linked_class>
@@ -4044,8 +4009,6 @@
<edit_mode>none</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>true</read_only>
</field>
</fields>
<methods/>
@@ -4197,8 +4160,6 @@
<edit_mode>none</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>true</read_only>
</field>
</fields>
<methods/>
@@ -4556,8 +4517,6 @@
<count_min>0</count_min>
<count_max>0</count_max>
<duplicates/>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -4708,8 +4667,6 @@
<count_min>0</count_min>
<count_max>0</count_max>
<duplicates/>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -4796,8 +4753,6 @@
<count_min>0</count_min>
<count_max>0</count_max>
<duplicates/>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -5524,7 +5479,6 @@
<count_max>0</count_max>
<ext_key_to_remote>vlan_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods>
@@ -5737,7 +5691,6 @@
<count_max>0</count_max>
<ext_key_to_remote>subnet_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="physicalinterfaces_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkPhysicalInterfaceToVLAN</linked_class>
@@ -5746,7 +5699,6 @@
<count_max>0</count_max>
<ext_key_to_remote>physicalinterface_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods>
@@ -6178,7 +6130,6 @@
<count_max>0</count_max>
<ext_key_to_remote>vlan_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -6977,7 +6928,6 @@
<count_max>0</count_max>
<ext_key_to_remote>ci_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -7186,7 +7136,6 @@
<count_max>0</count_max>
<ext_key_to_remote>functionalci_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -7208,8 +7157,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<presentation>
@@ -7231,7 +7178,6 @@
<count_max>0</count_max>
<ext_key_to_remote>functionalci_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
</class>

View File

@@ -32,8 +32,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Relation:depends on/Description' => 'Elemente, von denen dieses Element abhängt.',
'Relation:depends on/DownStream' => 'Hängt ab von ...',
'Relation:depends on/UpStream' => 'Wirkt auf ...',
'Relation:impacts/LoadData' => 'Load data~~',
'Relation:impacts/NoFilteredData' => 'please select objects in Graphical view tag~~',
'Relation:impacts/LoadData' => 'Daten laden',
'Relation:impacts/FilteredData' => 'Daten sind über den Tab "Grafische Ansicht" gefiltert',
'Relation:impacts/NoFilteredData' => 'Bitte wählen Sie Objekte im Tab "Grafische Ansicht"',
));
@@ -81,7 +82,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkContactToFunctionalCI' => 'Verknüpfung Kontakt/FunctionalCI',
'Class:lnkContactToFunctionalCI+' => '',
'Class:lnkContactToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkContactToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_id' => 'FunctionalCI',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_name' => 'FunctionalCI-Name',
@@ -110,25 +111,25 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:FunctionalCI/Attribute:business_criticity' => 'Business-Kritikalität',
'Class:FunctionalCI/Attribute:business_criticity+' => '',
'Class:FunctionalCI/Attribute:business_criticity/Value:high' => 'hoch',
'Class:FunctionalCI/Attribute:business_criticity/Value:high+' => '',
'Class:FunctionalCI/Attribute:business_criticity/Value:high+' => 'hoch',
'Class:FunctionalCI/Attribute:business_criticity/Value:low' => 'niedrig',
'Class:FunctionalCI/Attribute:business_criticity/Value:low+' => '',
'Class:FunctionalCI/Attribute:business_criticity/Value:low+' => 'niedrig',
'Class:FunctionalCI/Attribute:business_criticity/Value:medium' => 'mittel',
'Class:FunctionalCI/Attribute:business_criticity/Value:medium+' => '',
'Class:FunctionalCI/Attribute:business_criticity/Value:medium+' => 'mittel',
'Class:FunctionalCI/Attribute:move2production' => 'Go-Live-Datum',
'Class:FunctionalCI/Attribute:move2production+' => 'Datum, an dem in Produktivbetrieb gegangen wird/wurde',
'Class:FunctionalCI/Attribute:contacts_list' => 'Kontakte',
'Class:FunctionalCI/Attribute:contacts_list+' => 'All the contacts for this configuration item~~',
'Class:FunctionalCI/Attribute:contacts_list+' => 'Alle Kontakte dieses CIs',
'Class:FunctionalCI/Attribute:documents_list' => 'Dokumente',
'Class:FunctionalCI/Attribute:documents_list+' => 'All the documents linked to this configuration item~~',
'Class:FunctionalCI/Attribute:documents_list+' => 'Alle Dokumente, die mit diesem CI verknüpft sind',
'Class:FunctionalCI/Attribute:applicationsolution_list' => 'Anwendungslösungen',
'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'All the application solutions depending on this configuration item~~',
'Class:FunctionalCI/Attribute:applicationsolution_list+' => 'Alle Anwendungslösungen, die von diesem CI abhängen',
'Class:FunctionalCI/Attribute:softwares_list' => 'Software',
'Class:FunctionalCI/Attribute:softwares_list+' => 'All the softwares installed on this configuration item~~',
'Class:FunctionalCI/Attribute:softwares_list+' => 'Software, die auf diesem CI installiert ist',
'Class:FunctionalCI/Attribute:finalclass' => 'Typ',
'Class:FunctionalCI/Attribute:finalclass+' => '',
'Class:FunctionalCI/Attribute:finalclass+' => 'Name der instanziierbaren Klasse',
'Class:FunctionalCI/Tab:OpenedTickets' => 'Offene Tickets',
'Class:FunctionalCI/Tab:OpenedTickets+' => 'Active Tickets which are impacting this functional CI~~',
'Class:FunctionalCI/Tab:OpenedTickets+' => 'Offene Tickets, die sich auf dieses CI auswirken',
));
//
@@ -138,7 +139,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PhysicalDevice' => 'Physisches Gerät',
'Class:PhysicalDevice+' => '',
'Class:PhysicalDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:PhysicalDevice/ComplementaryName' => '%1$s - %2$s',
'Class:PhysicalDevice/Attribute:serialnumber' => 'Seriennummer',
'Class:PhysicalDevice/Attribute:serialnumber+' => '',
'Class:PhysicalDevice/Attribute:location_id' => 'Standort',
@@ -178,13 +179,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Rack' => 'Rack',
'Class:Rack+' => '',
'Class:Rack/ComplementaryName' => '%1$s - %2$s~~',
'Class:Rack/ComplementaryName' => '%1$s - %2$s',
'Class:Rack/Attribute:nb_u' => 'Höheneinheiten',
'Class:Rack/Attribute:nb_u+' => '',
'Class:Rack/Attribute:device_list' => 'Devices',
'Class:Rack/Attribute:device_list+' => 'All the physical devices racked into this rack~~',
'Class:Rack/Attribute:device_list+' => 'Alle physischen Geräte, die in dieses Rack eingebaut sind',
'Class:Rack/Attribute:enclosure_list' => 'Enclosures',
'Class:Rack/Attribute:enclosure_list+' => 'All the enclosures in this rack~~',
'Class:Rack/Attribute:enclosure_list+' => 'Alle Enclosures in diesem Rack',
));
//
@@ -245,11 +246,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:ConnectableCI' => 'Verknüpfbares CI',
'Class:ConnectableCI+' => 'Physisches CI',
'Class:ConnectableCI/ComplementaryName' => '%1$s - %2$s~~',
'Class:ConnectableCI/ComplementaryName' => '%1$s - %2$s',
'Class:ConnectableCI/Attribute:networkdevice_list' => 'Netzwerkgeräte',
'Class:ConnectableCI/Attribute:networkdevice_list+' => 'All network devices connected to this device~~',
'Class:ConnectableCI/Attribute:networkdevice_list+' => 'Alle Netzwerkgeräte, die mit diesem Gerät verbunden sind',
'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Netzwerkinterfaces',
'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'All the physical network interfaces~~',
'Class:ConnectableCI/Attribute:physicalinterface_list+' => 'Alle physischen Netzwerkinterfaces des Geräts',
));
//
@@ -259,7 +260,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:DatacenterDevice' => 'Datacenter-Gerät',
'Class:DatacenterDevice+' => '',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s',
'Class:DatacenterDevice/Attribute:rack_id' => 'Rack',
'Class:DatacenterDevice/Attribute:rack_id+' => '',
'Class:DatacenterDevice/Attribute:rack_name' => 'Rack-Name',
@@ -281,9 +282,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:DatacenterDevice/Attribute:powerB_name' => 'Strom-B-Quellenname',
'Class:DatacenterDevice/Attribute:powerB_name+' => '',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => 'FC-Ports',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'All the fiber channel interfaces for this device~~',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => 'Alle Fibre-Channel-Schnittstellen für dieses Gerät',
'Class:DatacenterDevice/Attribute:san_list' => 'SANs',
'Class:DatacenterDevice/Attribute:san_list+' => 'All the SAN switches connected to this device~~',
'Class:DatacenterDevice/Attribute:san_list+' => 'Alle mit diesem Gerät verbundenen SAN-Switches',
'Class:DatacenterDevice/Attribute:redundancy' => 'Redundanz',
'Class:DatacenterDevice/Attribute:redundancy/count' => 'Das Gerät läuft, wenn mindestens eine der Stromversorgungen (A oder B) läuft.',
// Unused yet
@@ -298,13 +299,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:NetworkDevice' => 'Netzwerk-Gerät',
'Class:NetworkDevice+' => '',
'Class:NetworkDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:NetworkDevice/ComplementaryName' => '%1$s - %2$s',
'Class:NetworkDevice/Attribute:networkdevicetype_id' => 'Netzwerktyp',
'Class:NetworkDevice/Attribute:networkdevicetype_id+' => '',
'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Netzwerk-Typname',
'Class:NetworkDevice/Attribute:networkdevicetype_name+' => '',
'Class:NetworkDevice/Attribute:connectablecis_list' => 'Geräte',
'Class:NetworkDevice/Attribute:connectablecis_list+' => 'All the devices connected to this network device~~',
'Class:NetworkDevice/Attribute:connectablecis_list+' => 'Alle Geräte, die mit diesem Netzwerkgerät verbunden sind',
'Class:NetworkDevice/Attribute:iosversion_id' => 'IOS Version',
'Class:NetworkDevice/Attribute:iosversion_id+' => '',
'Class:NetworkDevice/Attribute:iosversion_name' => 'IOS-Versionsname',
@@ -320,7 +321,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Server' => 'Server',
'Class:Server+' => '',
'Class:Server/ComplementaryName' => '%1$s - %2$s~~',
'Class:Server/ComplementaryName' => '%1$s - %2$s',
'Class:Server/Attribute:osfamily_id' => 'OS Familie',
'Class:Server/Attribute:osfamily_id+' => '',
'Class:Server/Attribute:osfamily_name' => 'OS-Familienname',
@@ -338,7 +339,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Server/Attribute:ram' => 'RAM',
'Class:Server/Attribute:ram+' => '',
'Class:Server/Attribute:logicalvolumes_list' => 'Logische Volumes',
'Class:Server/Attribute:logicalvolumes_list+' => 'All the logical volumes connected to this server~~',
'Class:Server/Attribute:logicalvolumes_list+' => 'Alle mit diesem Server verbundenen logischen Volumes',
));
//
@@ -348,9 +349,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:StorageSystem' => 'Storage-System',
'Class:StorageSystem+' => '',
'Class:StorageSystem/ComplementaryName' => '%1$s - %2$s~~',
'Class:StorageSystem/ComplementaryName' => '%1$s - %2$s',
'Class:StorageSystem/Attribute:logicalvolume_list' => 'Logische Volumes',
'Class:StorageSystem/Attribute:logicalvolume_list+' => 'All the logical volumes in this storage system~~',
'Class:StorageSystem/Attribute:logicalvolume_list+' => 'Alle logischen Volumes in diesem Storage-System',
));
//
@@ -360,9 +361,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:SANSwitch' => 'SAN-Switch',
'Class:SANSwitch+' => '',
'Class:SANSwitch/ComplementaryName' => '%1$s - %2$s~~',
'Class:SANSwitch/ComplementaryName' => '%1$s - %2$s',
'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Geräte',
'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'All the devices connected to this SAN switch~~',
'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'Alle Geräte, die mit diesem SAN-Switche verbundenen sind',
));
//
@@ -372,9 +373,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:TapeLibrary' => 'Tape-Library',
'Class:TapeLibrary+' => '',
'Class:TapeLibrary/ComplementaryName' => '%1$s - %2$s~~',
'Class:TapeLibrary/ComplementaryName' => '%1$s - %2$s',
'Class:TapeLibrary/Attribute:tapes_list' => 'Tapes',
'Class:TapeLibrary/Attribute:tapes_list+' => 'All the tapes in the tape library~~',
'Class:TapeLibrary/Attribute:tapes_list+' => 'Alle Tapes in der Tape-Library',
));
//
@@ -384,9 +385,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:NAS' => 'NAS',
'Class:NAS+' => '',
'Class:NAS/ComplementaryName' => '%1$s - %2$s~~',
'Class:NAS/ComplementaryName' => '%1$s - %2$s',
'Class:NAS/Attribute:nasfilesystem_list' => 'Dateisysteme',
'Class:NAS/Attribute:nasfilesystem_list+' => 'All the file systems in this NAS~~',
'Class:NAS/Attribute:nasfilesystem_list+' => 'Alle Dateisysteme in diesem NAS',
));
//
@@ -396,7 +397,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PC' => 'PC',
'Class:PC+' => '',
'Class:PC/ComplementaryName' => '%1$s - %2$s~~',
'Class:PC/ComplementaryName' => '%1$s - %2$s',
'Class:PC/Attribute:osfamily_id' => 'OS-Familie',
'Class:PC/Attribute:osfamily_id+' => '',
'Class:PC/Attribute:osfamily_name' => 'OS-Familienname',
@@ -412,9 +413,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PC/Attribute:type' => 'Typ',
'Class:PC/Attribute:type+' => '',
'Class:PC/Attribute:type/Value:desktop' => 'Desktop',
'Class:PC/Attribute:type/Value:desktop+' => '',
'Class:PC/Attribute:type/Value:desktop+' => 'Desktop',
'Class:PC/Attribute:type/Value:laptop' => 'Laptop',
'Class:PC/Attribute:type/Value:laptop+' => '',
'Class:PC/Attribute:type/Value:laptop+' => 'Laptop',
));
//
@@ -424,7 +425,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Printer' => 'Drucker',
'Class:Printer+' => '',
'Class:Printer/ComplementaryName' => '%1$s - %2$s~~',
'Class:Printer/ComplementaryName' => '%1$s - %2$s',
));
//
@@ -434,7 +435,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PowerConnection' => 'Stromverbindung',
'Class:PowerConnection+' => '',
'Class:PowerConnection/ComplementaryName' => '%1$s - %2$s~~',
'Class:PowerConnection/ComplementaryName' => '%1$s - %2$s',
));
//
@@ -444,9 +445,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PowerSource' => 'Stromquelle',
'Class:PowerSource+' => '',
'Class:PowerSource/ComplementaryName' => '%1$s - %2$s~~',
'Class:PowerSource/ComplementaryName' => '%1$s - %2$s',
'Class:PowerSource/Attribute:pdus_list' => 'PDUs',
'Class:PowerSource/Attribute:pdus_list+' => 'All the PDUs using this power source~~',
'Class:PowerSource/Attribute:pdus_list+' => 'Alle PDUs, die diese Stromquelle nutzen',
));
//
@@ -456,7 +457,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PDU' => 'PDU',
'Class:PDU+' => '',
'Class:PDU/ComplementaryName' => '%1$s - %2$s - %3$s - %4$s~~',
'Class:PDU/ComplementaryName' => '%1$s - %2$s - %3$s - %4$s',
'Class:PDU/Attribute:rack_id' => 'Rack',
'Class:PDU/Attribute:rack_id+' => '',
'Class:PDU/Attribute:rack_name' => 'Rack-Name',
@@ -474,7 +475,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Peripheral' => 'Peripheriegerät',
'Class:Peripheral+' => '',
'Class:Peripheral/ComplementaryName' => '%1$s - %2$s~~',
'Class:Peripheral/ComplementaryName' => '%1$s - %2$s',
));
//
@@ -484,7 +485,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Enclosure' => 'Enclosure',
'Class:Enclosure+' => '',
'Class:Enclosure/ComplementaryName' => '%1$s - %2$s - %3$s~~',
'Class:Enclosure/ComplementaryName' => '%1$s - %2$s - %3$s',
'Class:Enclosure/Attribute:rack_id' => 'Rack',
'Class:Enclosure/Attribute:rack_id+' => '',
'Class:Enclosure/Attribute:rack_name' => 'Rack-Name',
@@ -492,7 +493,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Enclosure/Attribute:nb_u' => 'Höheneinheiten',
'Class:Enclosure/Attribute:nb_u+' => '',
'Class:Enclosure/Attribute:device_list' => 'Geräte',
'Class:Enclosure/Attribute:device_list+' => 'All the devices in this enclosure~~',
'Class:Enclosure/Attribute:device_list+' => 'Alle Geräte in diesem Enclosure',
));
//
@@ -503,9 +504,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:ApplicationSolution' => 'Anwendungslösung',
'Class:ApplicationSolution+' => '',
'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs',
'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'All the configuration items that compose this application solution~~',
'Class:ApplicationSolution/Attribute:functionalcis_list+' => 'Alle CIs, aus denen diese Anwendungslösung besteht',
'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Business-Prozesse',
'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'All the business processes depending on this application solution~~',
'Class:ApplicationSolution/Attribute:businessprocess_list+' => 'Alle Geschäftsprozesse, die von dieser Anwendungslösung abhängen',
'Class:ApplicationSolution/Attribute:status' => 'Status',
'Class:ApplicationSolution/Attribute:status+' => '',
'Class:ApplicationSolution/Attribute:status/Value:active' => 'aktiv',
@@ -526,7 +527,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:BusinessProcess' => 'Business-Prozess',
'Class:BusinessProcess+' => '',
'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Anwendungslösungen',
'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'All the application solutions that impact this business process~~',
'Class:BusinessProcess/Attribute:applicationsolutions_list+' => 'Alle Anwendungslösungen, die sich auf diesen Geschäftsprozess auswirken',
'Class:BusinessProcess/Attribute:status' => 'Status',
'Class:BusinessProcess/Attribute:status+' => '',
'Class:BusinessProcess/Attribute:status/Value:active' => 'aktiv',
@@ -572,7 +573,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Middleware' => 'Middleware',
'Class:Middleware+' => '',
'Class:Middleware/Attribute:middlewareinstance_list' => 'Middleware-Instanzen',
'Class:Middleware/Attribute:middlewareinstance_list+' => 'All the middleware instances provided by this middleware~~',
'Class:Middleware/Attribute:middlewareinstance_list+' => 'Alle Middleware-Instanzen, die von dieser Middleware bereitgestellt werden',
));
//
@@ -583,7 +584,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:DBServer' => 'DB Server',
'Class:DBServer+' => '',
'Class:DBServer/Attribute:dbschema_list' => 'DB Schemata',
'Class:DBServer/Attribute:dbschema_list+' => 'All the database schemas for this DB server~~',
'Class:DBServer/Attribute:dbschema_list+' => 'Alle Datenbankschemata für diesen DB-Server',
));
//
@@ -594,7 +595,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:WebServer' => 'Web Server',
'Class:WebServer+' => '',
'Class:WebServer/Attribute:webapp_list' => 'Webapplikationen',
'Class:WebServer/Attribute:webapp_list+' => 'All the web applications available on this web server~~',
'Class:WebServer/Attribute:webapp_list+' => 'Alle auf diesem Webserver verfügbaren Webanwendungen',
));
//
@@ -622,7 +623,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:MiddlewareInstance' => 'Middleware-Instanz',
'Class:MiddlewareInstance+' => '',
'Class:MiddlewareInstance/ComplementaryName' => '%1$s - %2$s~~',
'Class:MiddlewareInstance/ComplementaryName' => '%1$s - %2$s',
'Class:MiddlewareInstance/Attribute:middleware_id' => 'Middleware',
'Class:MiddlewareInstance/Attribute:middleware_id+' => '',
'Class:MiddlewareInstance/Attribute:middleware_name' => 'Middleware-Name',
@@ -636,7 +637,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:DatabaseSchema' => 'Datenbank-Schema',
'Class:DatabaseSchema+' => '',
'Class:DatabaseSchema/ComplementaryName' => '%1$s - %2$s~~',
'Class:DatabaseSchema/ComplementaryName' => '%1$s - %2$s',
'Class:DatabaseSchema/Attribute:dbserver_id' => 'DB-Server',
'Class:DatabaseSchema/Attribute:dbserver_id+' => '',
'Class:DatabaseSchema/Attribute:dbserver_name' => 'DB-Servername',
@@ -650,7 +651,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:WebApplication' => 'Webapplikation',
'Class:WebApplication+' => '',
'Class:WebApplication/ComplementaryName' => '%1$s - %2$s~~',
'Class:WebApplication/ComplementaryName' => '%1$s - %2$s',
'Class:WebApplication/Attribute:webserver_id' => 'Webserver',
'Class:WebApplication/Attribute:webserver_id+' => '',
'Class:WebApplication/Attribute:webserver_name' => 'Webservername',
@@ -677,8 +678,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:VirtualDevice/Attribute:status/Value:production+' => '',
'Class:VirtualDevice/Attribute:status/Value:stock' => 'Lager',
'Class:VirtualDevice/Attribute:status/Value:stock+' => '',
'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Logical Volumes',
'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'All the logical volumes used by this device~~',
'Class:VirtualDevice/Attribute:logicalvolumes_list' => 'Logische Volumes',
'Class:VirtualDevice/Attribute:logicalvolumes_list+' => 'Alle von diesem Gerät verwendeten logischen Volumes',
));
//
@@ -689,7 +690,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:VirtualHost' => 'Host',
'Class:VirtualHost+' => '',
'Class:VirtualHost/Attribute:virtualmachine_list' => 'Virtuelle Maschinen',
'Class:VirtualHost/Attribute:virtualmachine_list+' => 'All the virtual machines hosted by this host~~',
'Class:VirtualHost/Attribute:virtualmachine_list+' => 'Alle virtuellen Maschinen, die von diesem Host gehostet werden',
));
//
@@ -717,7 +718,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Farm' => 'Farm',
'Class:Farm+' => '',
'Class:Farm/Attribute:hypervisor_list' => 'Hypervisoren',
'Class:Farm/Attribute:hypervisor_list+' => 'All the hypervisors that compose this farm~~',
'Class:Farm/Attribute:hypervisor_list+' => 'Alle Hypervisoren, aus denen diese Farm besteht',
'Class:Farm/Attribute:redundancy' => 'Hochverfügbarkeit',
'Class:Farm/Attribute:redundancy/disabled' => 'Die Farm läuft, wenn alle Hypervisoren laufen.',
'Class:Farm/Attribute:redundancy/count' => 'Die Farm läuft, wenn mindestens %1$s Hypervisor(en) läuft/laufen.',
@@ -731,7 +732,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:VirtualMachine' => 'Virtuelle Maschine',
'Class:VirtualMachine+' => '',
'Class:VirtualMachine/ComplementaryName' => '%1$s - %2$s~~',
'Class:VirtualMachine/ComplementaryName' => '%1$s - %2$s',
'Class:VirtualMachine/Attribute:virtualhost_id' => 'Host',
'Class:VirtualMachine/Attribute:virtualhost_id+' => '',
'Class:VirtualMachine/Attribute:virtualhost_name' => 'Hostname',
@@ -755,7 +756,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:VirtualMachine/Attribute:managementip' => 'Management-IP',
'Class:VirtualMachine/Attribute:managementip+' => '',
'Class:VirtualMachine/Attribute:logicalinterface_list' => 'Netzwerk-Interfaces',
'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'All the logical network interfaces~~',
'Class:VirtualMachine/Attribute:logicalinterface_list+' => 'Alle logischen Netzwerk-Interfaces',
));
//
@@ -780,9 +781,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:LogicalVolume/Attribute:storagesystem_name' => 'Storage-Systemname',
'Class:LogicalVolume/Attribute:storagesystem_name+' => '',
'Class:LogicalVolume/Attribute:servers_list' => 'Server',
'Class:LogicalVolume/Attribute:servers_list+' => 'All the servers using this volume~~',
'Class:LogicalVolume/Attribute:servers_list+' => 'Alle Server, die dieses Volume verwenden',
'Class:LogicalVolume/Attribute:virtualdevices_list' => 'Virtuelle Geräte',
'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'All the virtual devices using this volume~~',
'Class:LogicalVolume/Attribute:virtualdevices_list+' => 'Alle virtuellen Maschinen, die dieses Volume verwenden',
));
//
@@ -792,7 +793,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkServerToVolume' => 'Verknüpfung Server/Volume',
'Class:lnkServerToVolume+' => '',
'Class:lnkServerToVolume/Name' => '%1$s / %2$s~~',
'Class:lnkServerToVolume/Name' => '%1$s / %2$s',
'Class:lnkServerToVolume/Attribute:volume_id' => 'Volume',
'Class:lnkServerToVolume/Attribute:volume_id+' => '',
'Class:lnkServerToVolume/Attribute:volume_name' => 'Volume-Name',
@@ -812,7 +813,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkVirtualDeviceToVolume' => 'Verknüpfung Virtuelles Gerät/Volume',
'Class:lnkVirtualDeviceToVolume+' => '',
'Class:lnkVirtualDeviceToVolume/Name' => '%1$s / %2$s~~',
'Class:lnkVirtualDeviceToVolume/Name' => '%1$s / %2$s',
'Class:lnkVirtualDeviceToVolume/Attribute:volume_id' => 'Volume',
'Class:lnkVirtualDeviceToVolume/Attribute:volume_id+' => '',
'Class:lnkVirtualDeviceToVolume/Attribute:volume_name' => 'Volume-Name',
@@ -832,7 +833,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkSanToDatacenterDevice' => 'Verknüpfung SAN/Datacenter-Gerät',
'Class:lnkSanToDatacenterDevice+' => '',
'Class:lnkSanToDatacenterDevice/Name' => '%1$s / %2$s~~',
'Class:lnkSanToDatacenterDevice/Name' => '%1$s / %2$s',
'Class:lnkSanToDatacenterDevice/Attribute:san_id' => 'SAN-Switch',
'Class:lnkSanToDatacenterDevice/Attribute:san_id+' => '',
'Class:lnkSanToDatacenterDevice/Attribute:san_name' => 'SAN-Switch-Name',
@@ -894,7 +895,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Software' => 'Software',
'Class:Software+' => '',
'Class:Software/ComplementaryName' => '%1$s - %2$s~~',
'Class:Software/ComplementaryName' => '%1$s - %2$s',
'Class:Software/Attribute:name' => 'Name',
'Class:Software/Attribute:name+' => '',
'Class:Software/Attribute:vendor' => 'Hersteller',
@@ -902,7 +903,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Software/Attribute:version' => 'Version',
'Class:Software/Attribute:version+' => '',
'Class:Software/Attribute:documents_list' => 'Dokumente',
'Class:Software/Attribute:documents_list+' => 'All the documents linked to this software~~',
'Class:Software/Attribute:documents_list+' => 'Alle mit dieser Software verknüpften Dokumente',
'Class:Software/Attribute:type' => 'Typ',
'Class:Software/Attribute:type+' => '',
'Class:Software/Attribute:type/Value:DBServer' => 'DB-Server',
@@ -916,11 +917,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Software/Attribute:type/Value:WebServer' => 'Webserver',
'Class:Software/Attribute:type/Value:WebServer+' => '',
'Class:Software/Attribute:softwareinstance_list' => 'Software-Instanzen',
'Class:Software/Attribute:softwareinstance_list+' => 'All the software instances for this software~~',
'Class:Software/Attribute:softwareinstance_list+' => 'Alle Software-Instanzen für diese Software',
'Class:Software/Attribute:softwarepatch_list' => 'Software-Patches',
'Class:Software/Attribute:softwarepatch_list+' => 'All the patchs for this software~~',
'Class:Software/Attribute:softwarepatch_list+' => 'Alle Software-Patches für diese Software',
'Class:Software/Attribute:softwarelicence_list' => 'Softwarelizenzen',
'Class:Software/Attribute:softwarelicence_list+' => 'All the licenses for this software~~',
'Class:Software/Attribute:softwarelicence_list+' => 'Alle Lizenzen für diese Software',
));
//
@@ -933,7 +934,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Patch/Attribute:name' => 'Name',
'Class:Patch/Attribute:name+' => '',
'Class:Patch/Attribute:documents_list' => 'Dokumente',
'Class:Patch/Attribute:documents_list+' => 'All the documents linked to this patch~~',
'Class:Patch/Attribute:documents_list+' => 'Alle Dokumente, die mit diesem Patch verknüpft sind',
'Class:Patch/Attribute:description' => 'Beschreibung',
'Class:Patch/Attribute:description+' => '',
'Class:Patch/Attribute:finalclass' => 'Typ',
@@ -948,7 +949,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:OSPatch' => 'OS-Patch',
'Class:OSPatch+' => '',
'Class:OSPatch/Attribute:functionalcis_list' => 'Geräte',
'Class:OSPatch/Attribute:functionalcis_list+' => 'All the systems where this patch is installed~~',
'Class:OSPatch/Attribute:functionalcis_list+' => 'Alle Systeme, auf denen dieser Patch installiert ist',
'Class:OSPatch/Attribute:osversion_id' => 'OS Version',
'Class:OSPatch/Attribute:osversion_id+' => '',
'Class:OSPatch/Attribute:osversion_name' => 'OS-Versionsname',
@@ -967,7 +968,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:SoftwarePatch/Attribute:software_name' => 'Software-Name',
'Class:SoftwarePatch/Attribute:software_name+' => '',
'Class:SoftwarePatch/Attribute:softwareinstances_list' => 'Software-Instanzen',
'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'All the systems where this software patch is installed~~',
'Class:SoftwarePatch/Attribute:softwareinstances_list+' => 'Alle Systeme, auf denen dieser Software-Patch installiert ist',
));
//
@@ -980,7 +981,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Licence/Attribute:name' => 'Name',
'Class:Licence/Attribute:name+' => '',
'Class:Licence/Attribute:documents_list' => 'Dokumente',
'Class:Licence/Attribute:documents_list+' => 'All the documents linked to this license~~',
'Class:Licence/Attribute:documents_list+' => 'Alle mit dieser Lizenz verknüpften Dokumente',
'Class:Licence/Attribute:org_id' => 'Besitzer',
'Class:Licence/Attribute:org_id+' => '',
'Class:Licence/Attribute:organization_name' => 'Organisationsname',
@@ -1002,7 +1003,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Licence/Attribute:perpetual/Value:yes' => 'ja',
'Class:Licence/Attribute:perpetual/Value:yes+' => 'ja',
'Class:Licence/Attribute:finalclass' => 'Typ',
'Class:Licence/Attribute:finalclass+' => '',
'Class:Licence/Attribute:finalclass+' => 'Name der instanziierbaren Klasse',
));
//
@@ -1012,15 +1013,15 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:OSLicence' => 'OS-Lizenz',
'Class:OSLicence+' => '',
'Class:OSLicence/ComplementaryName' => '%1$s - %2$s~~',
'Class:OSLicence/ComplementaryName' => '%1$s - %2$s',
'Class:OSLicence/Attribute:osversion_id' => 'OS-Version',
'Class:OSLicence/Attribute:osversion_id+' => '',
'Class:OSLicence/Attribute:osversion_name' => 'OS-Versionsname',
'Class:OSLicence/Attribute:osversion_name+' => '',
'Class:OSLicence/Attribute:virtualmachines_list' => 'Virtuelle Maschinen',
'Class:OSLicence/Attribute:virtualmachines_list+' => 'All the virtual machines where this license is used~~',
'Class:OSLicence/Attribute:virtualmachines_list+' => 'Alle virtuellen Maschinen, auf denen diese Lizenz verwendet wird',
'Class:OSLicence/Attribute:servers_list' => 'Server',
'Class:OSLicence/Attribute:servers_list+' => 'All the servers where this license is used~~',
'Class:OSLicence/Attribute:servers_list+' => 'Alle Server, auf denen diese Lizenz verwendet wird',
));
//
@@ -1030,13 +1031,13 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:SoftwareLicence' => 'Software-Lizenz',
'Class:SoftwareLicence+' => '',
'Class:SoftwareLicence/ComplementaryName' => '%1$s - %2$s~~',
'Class:SoftwareLicence/ComplementaryName' => '%1$s - %2$s',
'Class:SoftwareLicence/Attribute:software_id' => 'Software',
'Class:SoftwareLicence/Attribute:software_id+' => '',
'Class:SoftwareLicence/Attribute:software_name' => 'Software-Name',
'Class:SoftwareLicence/Attribute:software_name+' => '',
'Class:SoftwareLicence/Attribute:softwareinstance_list' => 'Software-Instanzen',
'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'All the systems where this license is used~~',
'Class:SoftwareLicence/Attribute:softwareinstance_list+' => 'Alle Systeme, in denen diese Lizenz verwendet wird',
));
//
@@ -1046,7 +1047,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkDocumentToLicence' => 'Verknüpfung Dokument/Lizenz',
'Class:lnkDocumentToLicence+' => '',
'Class:lnkDocumentToLicence/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToLicence/Name' => '%1$s / %2$s',
'Class:lnkDocumentToLicence/Attribute:licence_id' => 'Lizenz',
'Class:lnkDocumentToLicence/Attribute:licence_id+' => '',
'Class:lnkDocumentToLicence/Attribute:licence_name' => 'Lizenz-Name',
@@ -1087,7 +1088,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Brand' => 'Marke',
'Class:Brand+' => '',
'Class:Brand/Attribute:physicaldevices_list' => 'Physische Geräte',
'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand~~',
'Class:Brand/Attribute:physicaldevices_list+' => 'Alle physischen Geräte dieser Marke',
'Class:Brand/UniquenessRule:name+' => 'Der Name muss eindeutig sein',
'Class:Brand/UniquenessRule:name' => 'Diese Marke existiert bereits',
));
@@ -1099,7 +1100,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Model' => 'Modell',
'Class:Model+' => '',
'Class:Model/ComplementaryName' => '%1$s - %2$s~~',
'Class:Model/ComplementaryName' => '%1$s - %2$s',
'Class:Model/Attribute:brand_id' => 'Marke',
'Class:Model/Attribute:brand_id+' => '',
'Class:Model/Attribute:brand_name' => 'Markenname',
@@ -1107,43 +1108,43 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Model/Attribute:type' => 'Gerätetyp',
'Class:Model/Attribute:type+' => '',
'Class:Model/Attribute:type/Value:PowerSource' => 'Stromquelle',
'Class:Model/Attribute:type/Value:PowerSource+' => '',
'Class:Model/Attribute:type/Value:PowerSource+' => 'Stromquelle',
'Class:Model/Attribute:type/Value:DiskArray' => 'Plattenarray',
'Class:Model/Attribute:type/Value:DiskArray+' => '',
'Class:Model/Attribute:type/Value:DiskArray+' => 'Plattenarray',
'Class:Model/Attribute:type/Value:Enclosure' => 'Enclosure',
'Class:Model/Attribute:type/Value:Enclosure+' => '',
'Class:Model/Attribute:type/Value:Enclosure+' => 'Enclosure',
'Class:Model/Attribute:type/Value:IPPhone' => 'IP-Telefon',
'Class:Model/Attribute:type/Value:IPPhone+' => '',
'Class:Model/Attribute:type/Value:IPPhone+' => 'IP-Telefon',
'Class:Model/Attribute:type/Value:MobilePhone' => 'Mobiltelefon',
'Class:Model/Attribute:type/Value:MobilePhone+' => '',
'Class:Model/Attribute:type/Value:MobilePhone+' => 'Mobiltelefon',
'Class:Model/Attribute:type/Value:NAS' => 'NAS',
'Class:Model/Attribute:type/Value:NAS+' => '',
'Class:Model/Attribute:type/Value:NAS+' => 'NAS',
'Class:Model/Attribute:type/Value:NetworkDevice' => 'Netzwerkgerät',
'Class:Model/Attribute:type/Value:NetworkDevice+' => '',
'Class:Model/Attribute:type/Value:NetworkDevice+' => 'Netzwerkgerät',
'Class:Model/Attribute:type/Value:PC' => 'PC',
'Class:Model/Attribute:type/Value:PC+' => '',
'Class:Model/Attribute:type/Value:PC+' => 'PC',
'Class:Model/Attribute:type/Value:PDU' => 'PDU',
'Class:Model/Attribute:type/Value:PDU+' => '',
'Class:Model/Attribute:type/Value:PDU+' => 'PDU',
'Class:Model/Attribute:type/Value:Peripheral' => 'Peripheriegeräte',
'Class:Model/Attribute:type/Value:Peripheral+' => '',
'Class:Model/Attribute:type/Value:Peripheral+' => 'Peripheriegeräte',
'Class:Model/Attribute:type/Value:Printer' => 'Drucker',
'Class:Model/Attribute:type/Value:Printer+' => '',
'Class:Model/Attribute:type/Value:Printer+' => 'Drucker',
'Class:Model/Attribute:type/Value:Rack' => 'Rack',
'Class:Model/Attribute:type/Value:Rack+' => '',
'Class:Model/Attribute:type/Value:Rack+' => 'Rack',
'Class:Model/Attribute:type/Value:SANSwitch' => 'SAN-Switch',
'Class:Model/Attribute:type/Value:SANSwitch+' => '',
'Class:Model/Attribute:type/Value:SANSwitch+' => 'SAN-Switch',
'Class:Model/Attribute:type/Value:Server' => 'Server',
'Class:Model/Attribute:type/Value:Server+' => '',
'Class:Model/Attribute:type/Value:Server+' => 'Server',
'Class:Model/Attribute:type/Value:StorageSystem' => 'Storage-System',
'Class:Model/Attribute:type/Value:StorageSystem+' => '',
'Class:Model/Attribute:type/Value:StorageSystem+' => 'Storage-System',
'Class:Model/Attribute:type/Value:Tablet' => 'Tablet',
'Class:Model/Attribute:type/Value:Tablet+' => '',
'Class:Model/Attribute:type/Value:Tablet+' => 'Tablet',
'Class:Model/Attribute:type/Value:TapeLibrary' => 'Tape-Library',
'Class:Model/Attribute:type/Value:TapeLibrary+' => '',
'Class:Model/Attribute:type/Value:TapeLibrary+' => 'Tape-Library',
'Class:Model/Attribute:type/Value:Phone' => 'Telefon',
'Class:Model/Attribute:type/Value:Phone+' => '',
'Class:Model/Attribute:type/Value:Phone+' => 'Telefon',
'Class:Model/Attribute:physicaldevices_list' => 'Physische Geräte',
'Class:Model/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this model~~',
'Class:Model/Attribute:physicaldevices_list+' => 'Alle physischen Geräte, die diesem Modell entsprechen',
'Class:Model/UniquenessRule:name_brand+' => 'Der Modellname für eine Marke muss eindeutig sein',
'Class:Model/UniquenessRule:name_brand' => 'Es existiert bereits ein Modell mit diesem Namen für diese Marke',
));
@@ -1156,7 +1157,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:NetworkDeviceType' => 'Netzwerkgerätetyp',
'Class:NetworkDeviceType+' => '',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list' => 'Netzwerkgeräte',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'All the network devices corresponding to this type~~',
'Class:NetworkDeviceType/Attribute:networkdevicesdevices_list+' => 'Alle Netzwerkgeräte, die diesem Typ entsprechen',
));
//
@@ -1179,7 +1180,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkDocumentToPatch' => 'Verknüpfung Dokument/Patch',
'Class:lnkDocumentToPatch+' => '',
'Class:lnkDocumentToPatch/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToPatch/Name' => '%1$s / %2$s',
'Class:lnkDocumentToPatch/Attribute:patch_id' => 'Patch',
'Class:lnkDocumentToPatch/Attribute:patch_id+' => '',
'Class:lnkDocumentToPatch/Attribute:patch_name' => 'Patch-Name',
@@ -1197,7 +1198,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkSoftwareInstanceToSoftwarePatch' => 'Verknüpfung Software-Instanz/Softeware-Patch',
'Class:lnkSoftwareInstanceToSoftwarePatch+' => '',
'Class:lnkSoftwareInstanceToSoftwarePatch/Name' => '%1$s / %2$s~~',
'Class:lnkSoftwareInstanceToSoftwarePatch/Name' => '%1$s / %2$s',
'Class:lnkSoftwareInstanceToSoftwarePatch/Attribute:softwarepatch_id' => 'Software-Patch',
'Class:lnkSoftwareInstanceToSoftwarePatch/Attribute:softwarepatch_id+' => '',
'Class:lnkSoftwareInstanceToSoftwarePatch/Attribute:softwarepatch_name' => 'Software-Patch-Name',
@@ -1215,7 +1216,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkFunctionalCIToOSPatch' => 'Verknüpfung FunctionalCI/OS-Patch',
'Class:lnkFunctionalCIToOSPatch+' => '',
'Class:lnkFunctionalCIToOSPatch/Name' => '%1$s / %2$s~~',
'Class:lnkFunctionalCIToOSPatch/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_id' => 'OS-Patch',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_id+' => '',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_name' => 'OS-Patch-Name',
@@ -1233,7 +1234,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkDocumentToSoftware' => 'Verknüpfung Dokument/Software',
'Class:lnkDocumentToSoftware+' => '',
'Class:lnkDocumentToSoftware/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToSoftware/Name' => '%1$s / %2$s',
'Class:lnkDocumentToSoftware/Attribute:software_id' => 'Software',
'Class:lnkDocumentToSoftware/Attribute:software_id+' => '',
'Class:lnkDocumentToSoftware/Attribute:software_name' => 'Software-Name',
@@ -1251,8 +1252,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Subnet' => 'Subnetz',
'Class:Subnet+' => '',
'Class:Subnet/Name' => '%1$s/%2$s~~',
'Class:Subnet/ComplementaryName' => '%1$s - %2$s~~',
'Class:Subnet/Name' => '%1$s/%2$s',
'Class:Subnet/ComplementaryName' => '%1$s - %2$s',
'Class:Subnet/Attribute:description' => 'Beschreibung',
'Class:Subnet/Attribute:description+' => '',
'Class:Subnet/Attribute:subnet_name' => 'Subnetzname',
@@ -1297,7 +1298,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkSubnetToVLAN' => 'Verknüpfung Subnetz/VLAN',
'Class:lnkSubnetToVLAN+' => '',
'Class:lnkSubnetToVLAN/Name' => '%1$s / %2$s~~',
'Class:lnkSubnetToVLAN/Name' => '%1$s / %2$s',
'Class:lnkSubnetToVLAN/Attribute:subnet_id' => 'Subnetz',
'Class:lnkSubnetToVLAN/Attribute:subnet_id+' => '',
'Class:lnkSubnetToVLAN/Attribute:subnet_ip' => 'Subnetz-IP',
@@ -1320,7 +1321,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:NetworkInterface/Attribute:name' => 'Name',
'Class:NetworkInterface/Attribute:name+' => '',
'Class:NetworkInterface/Attribute:finalclass' => 'Typ',
'Class:NetworkInterface/Attribute:finalclass+' => '',
'Class:NetworkInterface/Attribute:finalclass+' => 'Name der instanziierbaren Klasse',
));
//
@@ -1351,7 +1352,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:PhysicalInterface' => 'Physisches Interface',
'Class:PhysicalInterface+' => '',
'Class:PhysicalInterface/Name' => '%2$s %1$s~~',
'Class:PhysicalInterface/Name' => '%2$s %1$s',
'Class:PhysicalInterface/Attribute:connectableci_id' => 'Gerät',
'Class:PhysicalInterface/Attribute:connectableci_id+' => '',
'Class:PhysicalInterface/Attribute:connectableci_name' => 'Gerätename',
@@ -1367,7 +1368,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkPhysicalInterfaceToVLAN' => 'Verknüpfung Physisches Interface / VLAN',
'Class:lnkPhysicalInterfaceToVLAN+' => '',
'Class:lnkPhysicalInterfaceToVLAN/Name' => '%1$s %2$s / %3$s~~',
'Class:lnkPhysicalInterfaceToVLAN/Name' => '%1$s %2$s / %3$s',
'Class:lnkPhysicalInterfaceToVLAN/Attribute:physicalinterface_id' => 'Physisches Interface',
'Class:lnkPhysicalInterfaceToVLAN/Attribute:physicalinterface_id+' => '',
'Class:lnkPhysicalInterfaceToVLAN/Attribute:physicalinterface_name' => 'Physisches Interface Name',
@@ -1422,7 +1423,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkConnectableCIToNetworkDevice' => 'Verknüpfung ConnectableCI/NetworkDevice',
'Class:lnkConnectableCIToNetworkDevice+' => '',
'Class:lnkConnectableCIToNetworkDevice/Name' => '%1$s / %2$s~~',
'Class:lnkConnectableCIToNetworkDevice/Name' => '%1$s / %2$s',
'Class:lnkConnectableCIToNetworkDevice/Attribute:networkdevice_id' => 'Netzwerkgerät',
'Class:lnkConnectableCIToNetworkDevice/Attribute:networkdevice_id+' => '',
'Class:lnkConnectableCIToNetworkDevice/Attribute:networkdevice_name' => 'Netzwerkgerät-Name',
@@ -1450,7 +1451,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkApplicationSolutionToFunctionalCI' => 'Verknüpfung Anwendungslösung/FunctionalCI',
'Class:lnkApplicationSolutionToFunctionalCI+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkApplicationSolutionToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_id' => 'Anwendungslösung',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_id+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_name' => 'Anwendungslösungs-Name',
@@ -1468,7 +1469,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkApplicationSolutionToBusinessProcess' => 'Verknüpfung Anwendungslösung/Business-Prozess',
'Class:lnkApplicationSolutionToBusinessProcess+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Name' => '%1$s / %2$s~~',
'Class:lnkApplicationSolutionToBusinessProcess/Name' => '%1$s / %2$s',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id' => 'Business-Prozess',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_name' => 'Business-Prozess-Name',
@@ -1486,7 +1487,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Group' => 'Gruppe',
'Class:Group+' => '',
'Class:Group/ComplementaryName' => '%1$s - %2$s~~',
'Class:Group/ComplementaryName' => '%1$s - %2$s',
'Class:Group/Attribute:name' => 'Name',
'Class:Group/Attribute:name+' => '',
'Class:Group/Attribute:status' => 'Status',
@@ -1510,7 +1511,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Group/Attribute:parent_name' => 'Name',
'Class:Group/Attribute:parent_name+' => '',
'Class:Group/Attribute:ci_list' => 'Verbundene CIs',
'Class:Group/Attribute:ci_list+' => 'All the configuration items linked to this group~~',
'Class:Group/Attribute:ci_list+' => 'Alle mit dieser Gruppe verknüpften CIs',
'Class:Group/Attribute:parent_id_friendlyname' => 'Parent-Gruppe',
'Class:Group/Attribute:parent_id_friendlyname+' => '',
));
@@ -1522,7 +1523,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkGroupToCI' => 'Gruppe/CI',
'Class:lnkGroupToCI+' => '',
'Class:lnkGroupToCI/Name' => '%1$s / %2$s~~',
'Class:lnkGroupToCI/Name' => '%1$s / %2$s',
'Class:lnkGroupToCI/Attribute:group_id' => 'Gruppe',
'Class:lnkGroupToCI/Attribute:group_id+' => '',
'Class:lnkGroupToCI/Attribute:group_name' => 'Name',
@@ -1544,7 +1545,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Server:otherinfo' => 'Sonstige Informationen',
'Server:power' => 'Stromversorgung',
'Class:Subnet/Tab:IPUsage' => 'IP-Nutzung',
'Class:Subnet/Tab:IPUsage+' => 'Which IP within this Subnet are used or not~~',
'Class:Subnet/Tab:IPUsage+' => 'Welche IPs innerhalb dieses Subnetzes verwendet werden oder nicht',
'Class:Subnet/Tab:IPUsage-explain' => 'Interfaces mit einer IP in der Range: <em>%1$s</em> bis <em>%2$s</em>',
'Class:Subnet/Tab:FreeIPs' => 'Freie IPs',
'Class:Subnet/Tab:FreeIPs-count' => 'Freie IPs: %1$s',
@@ -1560,7 +1561,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkDocumentToFunctionalCI' => 'Verknüpfung Dokument/FunctionalCI',
'Class:lnkDocumentToFunctionalCI+' => '',
'Class:lnkDocumentToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_id' => 'FunctionalCI',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_name' => 'FunctionalCI-Name',

View File

@@ -81,7 +81,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkContactToFunctionalCI' => 'Lien Contact / CI Fonctionel',
'Class:lnkContactToFunctionalCI+' => '',
'Class:lnkContactToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkContactToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_id' => 'CI',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkContactToFunctionalCI/Attribute:functionalci_name' => 'Nom CI',
@@ -138,7 +138,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PhysicalDevice' => 'Matériel physique',
'Class:PhysicalDevice+' => '',
'Class:PhysicalDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:PhysicalDevice/ComplementaryName' => '%1$s - %2$s',
'Class:PhysicalDevice/Attribute:serialnumber' => 'Numéro de série',
'Class:PhysicalDevice/Attribute:serialnumber+' => '',
'Class:PhysicalDevice/Attribute:location_id' => 'Site',
@@ -178,7 +178,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Rack' => 'Rack',
'Class:Rack+' => '',
'Class:Rack/ComplementaryName' => '%1$s - %2$s~~',
'Class:Rack/ComplementaryName' => '%1$s - %2$s',
'Class:Rack/Attribute:nb_u' => 'NB Unité',
'Class:Rack/Attribute:nb_u+' => '',
'Class:Rack/Attribute:device_list' => 'Matériels',
@@ -245,7 +245,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:ConnectableCI' => 'CI connecté',
'Class:ConnectableCI+' => '',
'Class:ConnectableCI/ComplementaryName' => '%1$s - %2$s~~',
'Class:ConnectableCI/ComplementaryName' => '%1$s - %2$s',
'Class:ConnectableCI/Attribute:networkdevice_list' => 'Equipements réseaux',
'Class:ConnectableCI/Attribute:networkdevice_list+' => 'Tous les équipements réseaux connectés à ce matériel',
'Class:ConnectableCI/Attribute:physicalinterface_list' => 'Interfaces réseaux',
@@ -259,7 +259,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:DatacenterDevice' => 'Matériel Datacenter',
'Class:DatacenterDevice+' => '',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s',
'Class:DatacenterDevice/Attribute:rack_id' => 'Rack',
'Class:DatacenterDevice/Attribute:rack_id+' => '',
'Class:DatacenterDevice/Attribute:rack_name' => 'Nom Rack',
@@ -298,7 +298,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:NetworkDevice' => 'Equipement réseau',
'Class:NetworkDevice+' => '',
'Class:NetworkDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:NetworkDevice/ComplementaryName' => '%1$s - %2$s',
'Class:NetworkDevice/Attribute:networkdevicetype_id' => 'Type',
'Class:NetworkDevice/Attribute:networkdevicetype_id+' => '',
'Class:NetworkDevice/Attribute:networkdevicetype_name' => 'Nom Type',
@@ -320,7 +320,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Server' => 'Serveur',
'Class:Server+' => '',
'Class:Server/ComplementaryName' => '%1$s - %2$s~~',
'Class:Server/ComplementaryName' => '%1$s - %2$s',
'Class:Server/Attribute:osfamily_id' => 'Famille OS',
'Class:Server/Attribute:osfamily_id+' => '',
'Class:Server/Attribute:osfamily_name' => 'Nom Famille OS',
@@ -348,7 +348,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:StorageSystem' => 'Système de stockage',
'Class:StorageSystem+' => '',
'Class:StorageSystem/ComplementaryName' => '%1$s - %2$s~~',
'Class:StorageSystem/ComplementaryName' => '%1$s - %2$s',
'Class:StorageSystem/Attribute:logicalvolume_list' => 'Volumes logiques',
'Class:StorageSystem/Attribute:logicalvolume_list+' => 'Tous les volumes logiques dans ce système de stockage',
));
@@ -360,7 +360,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:SANSwitch' => 'Switch SAN',
'Class:SANSwitch+' => '',
'Class:SANSwitch/ComplementaryName' => '%1$s - %2$s~~',
'Class:SANSwitch/ComplementaryName' => '%1$s - %2$s',
'Class:SANSwitch/Attribute:datacenterdevice_list' => 'Matériels connectés',
'Class:SANSwitch/Attribute:datacenterdevice_list+' => 'Tous les matériels connectés à ce switch SAN',
));
@@ -372,7 +372,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:TapeLibrary' => 'Bandothèque',
'Class:TapeLibrary+' => '',
'Class:TapeLibrary/ComplementaryName' => '%1$s - %2$s~~',
'Class:TapeLibrary/ComplementaryName' => '%1$s - %2$s',
'Class:TapeLibrary/Attribute:tapes_list' => 'Bandes',
'Class:TapeLibrary/Attribute:tapes_list+' => 'Toutes les bandes dans cette bandothèque',
));
@@ -384,7 +384,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:NAS' => 'NAS',
'Class:NAS+' => '',
'Class:NAS/ComplementaryName' => '%1$s - %2$s~~',
'Class:NAS/ComplementaryName' => '%1$s - %2$s',
'Class:NAS/Attribute:nasfilesystem_list' => 'Systèmes de fichier NAS',
'Class:NAS/Attribute:nasfilesystem_list+' => 'Tous les systèmes de fichier dans ce NAS',
));
@@ -396,7 +396,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PC' => 'PC',
'Class:PC+' => '',
'Class:PC/ComplementaryName' => '%1$s - %2$s~~',
'Class:PC/ComplementaryName' => '%1$s - %2$s',
'Class:PC/Attribute:osfamily_id' => 'Famille OS',
'Class:PC/Attribute:osfamily_id+' => '',
'Class:PC/Attribute:osfamily_name' => 'Nom Famille OS',
@@ -424,7 +424,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Printer' => 'Imprimante',
'Class:Printer+' => '',
'Class:Printer/ComplementaryName' => '%1$s - %2$s~~',
'Class:Printer/ComplementaryName' => '%1$s - %2$s',
));
//
@@ -434,7 +434,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PowerConnection' => 'Connexion électrique',
'Class:PowerConnection+' => '',
'Class:PowerConnection/ComplementaryName' => '%1$s - %2$s~~',
'Class:PowerConnection/ComplementaryName' => '%1$s - %2$s',
));
//
@@ -444,7 +444,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PowerSource' => 'Arrivée électrique',
'Class:PowerSource+' => '',
'Class:PowerSource/ComplementaryName' => '%1$s - %2$s~~',
'Class:PowerSource/ComplementaryName' => '%1$s - %2$s',
'Class:PowerSource/Attribute:pdus_list' => 'PDUs',
'Class:PowerSource/Attribute:pdus_list+' => 'Toutes les PDUs de cette arrivée électrique',
));
@@ -456,7 +456,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PDU' => 'PDU',
'Class:PDU+' => '',
'Class:PDU/ComplementaryName' => '%1$s - %2$s - %3$s - %4$s~~',
'Class:PDU/ComplementaryName' => '%1$s - %2$s - %3$s - %4$s',
'Class:PDU/Attribute:rack_id' => 'Rack',
'Class:PDU/Attribute:rack_id+' => '',
'Class:PDU/Attribute:rack_name' => 'Nom rack',
@@ -474,7 +474,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Peripheral' => 'Périphérique',
'Class:Peripheral+' => '',
'Class:Peripheral/ComplementaryName' => '%1$s - %2$s~~',
'Class:Peripheral/ComplementaryName' => '%1$s - %2$s',
));
//
@@ -484,7 +484,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Enclosure' => 'Chassis',
'Class:Enclosure+' => '',
'Class:Enclosure/ComplementaryName' => '%1$s - %2$s - %3$s~~',
'Class:Enclosure/ComplementaryName' => '%1$s - %2$s - %3$s',
'Class:Enclosure/Attribute:rack_id' => 'Rack',
'Class:Enclosure/Attribute:rack_id+' => '',
'Class:Enclosure/Attribute:rack_name' => 'Nom rack',
@@ -603,7 +603,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PCSoftware' => 'Logiciel PC',
'Class:PCSoftware+' => '~~',
'Class:PCSoftware+' => 'Application logicielle sur PC',
));
//
@@ -622,7 +622,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:MiddlewareInstance' => 'Instance Middleware',
'Class:MiddlewareInstance+' => '',
'Class:MiddlewareInstance/ComplementaryName' => '%1$s - %2$s~~',
'Class:MiddlewareInstance/ComplementaryName' => '%1$s - %2$s',
'Class:MiddlewareInstance/Attribute:middleware_id' => 'Middleware',
'Class:MiddlewareInstance/Attribute:middleware_id+' => '',
'Class:MiddlewareInstance/Attribute:middleware_name' => 'Nom Middleware',
@@ -636,7 +636,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:DatabaseSchema' => 'Instance de base de données',
'Class:DatabaseSchema+' => '',
'Class:DatabaseSchema/ComplementaryName' => '%1$s - %2$s~~',
'Class:DatabaseSchema/ComplementaryName' => '%1$s - %2$s',
'Class:DatabaseSchema/Attribute:dbserver_id' => 'Serveur de base de données',
'Class:DatabaseSchema/Attribute:dbserver_id+' => '',
'Class:DatabaseSchema/Attribute:dbserver_name' => 'Nom Serveur de base de données',
@@ -650,7 +650,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:WebApplication' => 'Application Web',
'Class:WebApplication+' => '',
'Class:WebApplication/ComplementaryName' => '%1$s - %2$s~~',
'Class:WebApplication/ComplementaryName' => '%1$s - %2$s',
'Class:WebApplication/Attribute:webserver_id' => 'Serveur Web',
'Class:WebApplication/Attribute:webserver_id+' => '',
'Class:WebApplication/Attribute:webserver_name' => 'Nom Serveur Web',
@@ -731,7 +731,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:VirtualMachine' => 'Machine virtuelle',
'Class:VirtualMachine+' => '',
'Class:VirtualMachine/ComplementaryName' => '%1$s - %2$s~~',
'Class:VirtualMachine/ComplementaryName' => '%1$s - %2$s',
'Class:VirtualMachine/Attribute:virtualhost_id' => 'vCluster / Hyperviseur',
'Class:VirtualMachine/Attribute:virtualhost_id+' => '',
'Class:VirtualMachine/Attribute:virtualhost_name' => 'Nom Host',
@@ -792,7 +792,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkServerToVolume' => 'Lien Serveur / Volume',
'Class:lnkServerToVolume+' => '',
'Class:lnkServerToVolume/Name' => '%1$s / %2$s~~',
'Class:lnkServerToVolume/Name' => '%1$s / %2$s',
'Class:lnkServerToVolume/Attribute:volume_id' => 'Volume logique',
'Class:lnkServerToVolume/Attribute:volume_id+' => '',
'Class:lnkServerToVolume/Attribute:volume_name' => 'Nom Volume logique',
@@ -812,7 +812,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkVirtualDeviceToVolume' => 'Lien Device virtuel / Volume',
'Class:lnkVirtualDeviceToVolume+' => '',
'Class:lnkVirtualDeviceToVolume/Name' => '%1$s / %2$s~~',
'Class:lnkVirtualDeviceToVolume/Name' => '%1$s / %2$s',
'Class:lnkVirtualDeviceToVolume/Attribute:volume_id' => 'Volume logique',
'Class:lnkVirtualDeviceToVolume/Attribute:volume_id+' => '',
'Class:lnkVirtualDeviceToVolume/Attribute:volume_name' => 'Nom Volume logique',
@@ -832,7 +832,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkSanToDatacenterDevice' => 'Lien San / Device',
'Class:lnkSanToDatacenterDevice+' => '',
'Class:lnkSanToDatacenterDevice/Name' => '%1$s / %2$s~~',
'Class:lnkSanToDatacenterDevice/Name' => '%1$s / %2$s',
'Class:lnkSanToDatacenterDevice/Attribute:san_id' => 'Switch SAN',
'Class:lnkSanToDatacenterDevice/Attribute:san_id+' => '',
'Class:lnkSanToDatacenterDevice/Attribute:san_name' => 'Nom Switch SAN',
@@ -894,7 +894,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Software' => 'Logiciel',
'Class:Software+' => '',
'Class:Software/ComplementaryName' => '%1$s - %2$s~~',
'Class:Software/ComplementaryName' => '%1$s - %2$s',
'Class:Software/Attribute:name' => 'Nom',
'Class:Software/Attribute:name+' => '',
'Class:Software/Attribute:vendor' => 'Vendeur',
@@ -1012,7 +1012,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:OSLicence' => 'Licence OS',
'Class:OSLicence+' => '',
'Class:OSLicence/ComplementaryName' => '%1$s - %2$s~~',
'Class:OSLicence/ComplementaryName' => '%1$s - %2$s',
'Class:OSLicence/Attribute:osversion_id' => 'Version OS',
'Class:OSLicence/Attribute:osversion_id+' => '',
'Class:OSLicence/Attribute:osversion_name' => 'Nom Version OS',
@@ -1030,7 +1030,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:SoftwareLicence' => 'Licence Logiciel',
'Class:SoftwareLicence+' => '',
'Class:SoftwareLicence/ComplementaryName' => '%1$s - %2$s~~',
'Class:SoftwareLicence/ComplementaryName' => '%1$s - %2$s',
'Class:SoftwareLicence/Attribute:software_id' => 'Logiciel',
'Class:SoftwareLicence/Attribute:software_id+' => '',
'Class:SoftwareLicence/Attribute:software_name' => 'Nom Logiciel',
@@ -1046,7 +1046,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkDocumentToLicence' => 'Lien Document / Licence',
'Class:lnkDocumentToLicence+' => '',
'Class:lnkDocumentToLicence/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToLicence/Name' => '%1$s / %2$s',
'Class:lnkDocumentToLicence/Attribute:licence_id' => 'Licence',
'Class:lnkDocumentToLicence/Attribute:licence_id+' => '',
'Class:lnkDocumentToLicence/Attribute:licence_name' => 'Nom Licence',
@@ -1099,7 +1099,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Model' => 'Modèle',
'Class:Model+' => '',
'Class:Model/ComplementaryName' => '%1$s - %2$s~~',
'Class:Model/ComplementaryName' => '%1$s - %2$s',
'Class:Model/Attribute:brand_id' => 'Marque',
'Class:Model/Attribute:brand_id+' => '',
'Class:Model/Attribute:brand_name' => 'Nom marque',
@@ -1179,7 +1179,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkDocumentToPatch' => 'Lien Document / Patch',
'Class:lnkDocumentToPatch+' => '',
'Class:lnkDocumentToPatch/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToPatch/Name' => '%1$s / %2$s',
'Class:lnkDocumentToPatch/Attribute:patch_id' => 'Patch',
'Class:lnkDocumentToPatch/Attribute:patch_id+' => '',
'Class:lnkDocumentToPatch/Attribute:patch_name' => 'Nom patch',
@@ -1197,7 +1197,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkSoftwareInstanceToSoftwarePatch' => 'Lien Instance logiciel / Patch logiciel',
'Class:lnkSoftwareInstanceToSoftwarePatch+' => '',
'Class:lnkSoftwareInstanceToSoftwarePatch/Name' => '%1$s / %2$s~~',
'Class:lnkSoftwareInstanceToSoftwarePatch/Name' => '%1$s / %2$s',
'Class:lnkSoftwareInstanceToSoftwarePatch/Attribute:softwarepatch_id' => 'Patch logiciel',
'Class:lnkSoftwareInstanceToSoftwarePatch/Attribute:softwarepatch_id+' => '',
'Class:lnkSoftwareInstanceToSoftwarePatch/Attribute:softwarepatch_name' => 'Nom patch logiciel',
@@ -1215,7 +1215,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkFunctionalCIToOSPatch' => 'Lien CI Fonctionel / Patch OS',
'Class:lnkFunctionalCIToOSPatch+' => '',
'Class:lnkFunctionalCIToOSPatch/Name' => '%1$s / %2$s~~',
'Class:lnkFunctionalCIToOSPatch/Name' => '%1$s / %2$s',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_id' => 'Patch OS',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_id+' => '',
'Class:lnkFunctionalCIToOSPatch/Attribute:ospatch_name' => 'Nom Patch OS',
@@ -1233,7 +1233,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkDocumentToSoftware' => 'Lien Document / Logiciel',
'Class:lnkDocumentToSoftware+' => '',
'Class:lnkDocumentToSoftware/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToSoftware/Name' => '%1$s / %2$s',
'Class:lnkDocumentToSoftware/Attribute:software_id' => 'Logiciel',
'Class:lnkDocumentToSoftware/Attribute:software_id+' => '',
'Class:lnkDocumentToSoftware/Attribute:software_name' => 'Nom logiciel',
@@ -1251,12 +1251,12 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Subnet' => 'Subnet',
'Class:Subnet+' => '',
'Class:Subnet/Name' => '%1$s/%2$s~~',
'Class:Subnet/ComplementaryName' => '%1$s - %2$s~~',
'Class:Subnet/Name' => '%1$s/%2$s',
'Class:Subnet/ComplementaryName' => '%1$s - %2$s',
'Class:Subnet/Attribute:description' => 'Description',
'Class:Subnet/Attribute:description+' => '',
'Class:Subnet/Attribute:subnet_name' => 'Nom de subnet',
'Class:Subnet/Attribute:subnet_name+' => '~~',
'Class:Subnet/Attribute:subnet_name+' => '',
'Class:Subnet/Attribute:org_id' => 'Organisation',
'Class:Subnet/Attribute:org_id+' => '',
'Class:Subnet/Attribute:org_name' => 'Nom organisation',
@@ -1297,7 +1297,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkSubnetToVLAN' => 'Lien Subnet / VLAN',
'Class:lnkSubnetToVLAN+' => '',
'Class:lnkSubnetToVLAN/Name' => '%1$s / %2$s~~',
'Class:lnkSubnetToVLAN/Name' => '%1$s / %2$s',
'Class:lnkSubnetToVLAN/Attribute:subnet_id' => 'Subnet',
'Class:lnkSubnetToVLAN/Attribute:subnet_id+' => '',
'Class:lnkSubnetToVLAN/Attribute:subnet_ip' => 'Subnet IP',
@@ -1351,7 +1351,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:PhysicalInterface' => 'Interface physique',
'Class:PhysicalInterface+' => '',
'Class:PhysicalInterface/Name' => '%2$s %1$s~~',
'Class:PhysicalInterface/Name' => '%2$s %1$s',
'Class:PhysicalInterface/Attribute:connectableci_id' => 'Matériel',
'Class:PhysicalInterface/Attribute:connectableci_id+' => '',
'Class:PhysicalInterface/Attribute:connectableci_name' => 'Nom matériel',
@@ -1367,7 +1367,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkPhysicalInterfaceToVLAN' => 'Lien Interface réseau / VLAN',
'Class:lnkPhysicalInterfaceToVLAN+' => '',
'Class:lnkPhysicalInterfaceToVLAN/Name' => '%1$s %2$s / %3$s~~',
'Class:lnkPhysicalInterfaceToVLAN/Name' => '%1$s %2$s / %3$s',
'Class:lnkPhysicalInterfaceToVLAN/Attribute:physicalinterface_id' => 'Interface réseau',
'Class:lnkPhysicalInterfaceToVLAN/Attribute:physicalinterface_id+' => '',
'Class:lnkPhysicalInterfaceToVLAN/Attribute:physicalinterface_name' => 'Nom interface réseau',
@@ -1422,7 +1422,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkConnectableCIToNetworkDevice' => 'Lien Device / Equipement réseau',
'Class:lnkConnectableCIToNetworkDevice+' => '',
'Class:lnkConnectableCIToNetworkDevice/Name' => '%1$s / %2$s~~',
'Class:lnkConnectableCIToNetworkDevice/Name' => '%1$s / %2$s',
'Class:lnkConnectableCIToNetworkDevice/Attribute:networkdevice_id' => 'Equipement réseau',
'Class:lnkConnectableCIToNetworkDevice/Attribute:networkdevice_id+' => '',
'Class:lnkConnectableCIToNetworkDevice/Attribute:networkdevice_name' => 'Nom Equipement réseau',
@@ -1450,7 +1450,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkApplicationSolutionToFunctionalCI' => 'Lien Solution Applicative / CI Fonctionel',
'Class:lnkApplicationSolutionToFunctionalCI+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkApplicationSolutionToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_id' => 'Solution applicative',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_id+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_name' => 'Nom Solution applicative',
@@ -1468,7 +1468,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkApplicationSolutionToBusinessProcess' => 'Lien Solution Applicative / Processus métier',
'Class:lnkApplicationSolutionToBusinessProcess+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Name' => '%1$s / %2$s~~',
'Class:lnkApplicationSolutionToBusinessProcess/Name' => '%1$s / %2$s',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id' => 'Processus métier',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_name' => 'Nom Processus métier',
@@ -1486,7 +1486,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:Group' => 'Groupe',
'Class:Group+' => '',
'Class:Group/ComplementaryName' => '%1$s - %2$s~~',
'Class:Group/ComplementaryName' => '%1$s - %2$s',
'Class:Group/Attribute:name' => 'Nom',
'Class:Group/Attribute:name+' => '',
'Class:Group/Attribute:status' => 'Etat',
@@ -1522,7 +1522,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkGroupToCI' => 'Lien Groupe / CI',
'Class:lnkGroupToCI+' => '',
'Class:lnkGroupToCI/Name' => '%1$s / %2$s~~',
'Class:lnkGroupToCI/Name' => '%1$s / %2$s',
'Class:lnkGroupToCI/Attribute:group_id' => 'Groupe',
'Class:lnkGroupToCI/Attribute:group_id+' => '',
'Class:lnkGroupToCI/Attribute:group_name' => 'Nom du groupe',
@@ -1560,7 +1560,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkDocumentToFunctionalCI' => 'Lien Document / CI Fonctionel',
'Class:lnkDocumentToFunctionalCI+' => '',
'Class:lnkDocumentToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_id' => 'CI',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkDocumentToFunctionalCI/Attribute:functionalci_name' => 'Nom CI',

View File

@@ -127,8 +127,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:FunctionalCI/Attribute:applicationsolution_list+' => '此配置项依赖的所有应用方案',
'Class:FunctionalCI/Attribute:softwares_list' => '软件',
'Class:FunctionalCI/Attribute:softwares_list+' => '此配置项上已安装的所有软件',
'Class:FunctionalCI/Attribute:finalclass' => '二级配置项',
'Class:FunctionalCI/Attribute:finalclass+' => 'Name of the final class',
'Class:FunctionalCI/Attribute:finalclass' => '类型',
'Class:FunctionalCI/Attribute:finalclass+' => '根本属性的名称',
'Class:FunctionalCI/Tab:OpenedTickets' => '活跃的工单',
'Class:FunctionalCI/Tab:OpenedTickets+' => 'Active Tickets which are impacting this functional CI~~',
));
@@ -149,8 +149,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:PhysicalDevice/Attribute:location_name+' => '',
'Class:PhysicalDevice/Attribute:status' => '状态',
'Class:PhysicalDevice/Attribute:status+' => '',
'Class:PhysicalDevice/Attribute:status/Value:implementation' => '上线',
'Class:PhysicalDevice/Attribute:status/Value:implementation+' => '上线',
'Class:PhysicalDevice/Attribute:status/Value:implementation' => '生效',
'Class:PhysicalDevice/Attribute:status/Value:implementation+' => '生效',
'Class:PhysicalDevice/Attribute:status/Value:obsolete' => '废弃',
'Class:PhysicalDevice/Attribute:status/Value:obsolete+' => '废弃',
'Class:PhysicalDevice/Attribute:status/Value:production' => '生产',
@@ -178,15 +178,15 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Rack' => '机',
'Class:Rack' => '机',
'Class:Rack+' => '',
'Class:Rack/ComplementaryName' => '%1$s - %2$s~~',
'Class:Rack/Attribute:nb_u' => '机高度',
'Class:Rack/Attribute:nb_u' => '机高度',
'Class:Rack/Attribute:nb_u+' => '',
'Class:Rack/Attribute:device_list' => '设备',
'Class:Rack/Attribute:device_list+' => '此机托管的所有物理设备',
'Class:Rack/Attribute:enclosure_list' => '机',
'Class:Rack/Attribute:enclosure_list+' => '此机上的所有机',
'Class:Rack/Attribute:device_list+' => '此机托管的所有物理设备',
'Class:Rack/Attribute:enclosure_list' => '机',
'Class:Rack/Attribute:enclosure_list+' => '此机上的所有机',
));
//
@@ -194,7 +194,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:TelephonyCI' => '电讯配置项',
'Class:TelephonyCI' => '通讯项',
'Class:TelephonyCI+' => '',
'Class:TelephonyCI/Attribute:phonenumber' => '电话号码',
'Class:TelephonyCI/Attribute:phonenumber+' => '',
@@ -262,13 +262,13 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:DatacenterDevice' => '数据中心设备',
'Class:DatacenterDevice+' => '',
'Class:DatacenterDevice/ComplementaryName' => '%1$s - %2$s~~',
'Class:DatacenterDevice/Attribute:rack_id' => '机',
'Class:DatacenterDevice/Attribute:rack_id' => '机',
'Class:DatacenterDevice/Attribute:rack_id+' => '',
'Class:DatacenterDevice/Attribute:rack_name' => '机名称',
'Class:DatacenterDevice/Attribute:rack_name' => '机名称',
'Class:DatacenterDevice/Attribute:rack_name+' => '',
'Class:DatacenterDevice/Attribute:enclosure_id' => '机',
'Class:DatacenterDevice/Attribute:enclosure_id' => '机',
'Class:DatacenterDevice/Attribute:enclosure_id+' => '',
'Class:DatacenterDevice/Attribute:enclosure_name' => '机名称',
'Class:DatacenterDevice/Attribute:enclosure_name' => '机名称',
'Class:DatacenterDevice/Attribute:enclosure_name+' => '',
'Class:DatacenterDevice/Attribute:nb_u' => '高度',
'Class:DatacenterDevice/Attribute:nb_u+' => '',
@@ -282,9 +282,9 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:DatacenterDevice/Attribute:powerB_id+' => '',
'Class:DatacenterDevice/Attribute:powerB_name' => '电源B名称',
'Class:DatacenterDevice/Attribute:powerB_name+' => '',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => '光纤口',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '此设备的所有光纤口',
'Class:DatacenterDevice/Attribute:san_list' => 'SANs',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list' => '光纤口',
'Class:DatacenterDevice/Attribute:fiberinterfacelist_list+' => '此设备的所有光纤口',
'Class:DatacenterDevice/Attribute:san_list' => 'SAN',
'Class:DatacenterDevice/Attribute:san_list+' => '所有连接到这台设备的SAN交换机',
'Class:DatacenterDevice/Attribute:redundancy' => '冗余',
'Class:DatacenterDevice/Attribute:redundancy/count' => '此设备运行正常至少需要一路电源 (A 或 B)',
@@ -459,9 +459,9 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:PDU' => 'PDU',
'Class:PDU+' => '',
'Class:PDU/ComplementaryName' => '%1$s - %2$s - %3$s - %4$s~~',
'Class:PDU/Attribute:rack_id' => '机',
'Class:PDU/Attribute:rack_id' => '机',
'Class:PDU/Attribute:rack_id+' => '',
'Class:PDU/Attribute:rack_name' => '机名称',
'Class:PDU/Attribute:rack_name' => '机名称',
'Class:PDU/Attribute:rack_name+' => '',
'Class:PDU/Attribute:powerstart_id' => '上级电源',
'Class:PDU/Attribute:powerstart_id+' => '',
@@ -484,17 +484,17 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Enclosure' => '机',
'Class:Enclosure' => '机',
'Class:Enclosure+' => '',
'Class:Enclosure/ComplementaryName' => '%1$s - %2$s - %3$s~~',
'Class:Enclosure/Attribute:rack_id' => '机',
'Class:Enclosure/Attribute:rack_id' => '机',
'Class:Enclosure/Attribute:rack_id+' => '',
'Class:Enclosure/Attribute:rack_name' => '机名称',
'Class:Enclosure/Attribute:rack_name' => '机名称',
'Class:Enclosure/Attribute:rack_name+' => '',
'Class:Enclosure/Attribute:nb_u' => '高度',
'Class:Enclosure/Attribute:nb_u+' => '',
'Class:Enclosure/Attribute:device_list' => '设备',
'Class:Enclosure/Attribute:device_list+' => '此机的所有设备',
'Class:Enclosure/Attribute:device_list+' => '此机的所有设备',
));
//
@@ -671,8 +671,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:VirtualDevice+' => '',
'Class:VirtualDevice/Attribute:status' => '状态',
'Class:VirtualDevice/Attribute:status+' => '',
'Class:VirtualDevice/Attribute:status/Value:implementation' => '上线',
'Class:VirtualDevice/Attribute:status/Value:implementation+' => '上线',
'Class:VirtualDevice/Attribute:status/Value:implementation' => '生效',
'Class:VirtualDevice/Attribute:status/Value:implementation+' => '生效',
'Class:VirtualDevice/Attribute:status/Value:obsolete' => '废弃',
'Class:VirtualDevice/Attribute:status/Value:obsolete+' => '废弃',
'Class:VirtualDevice/Attribute:status/Value:production' => '生产',
@@ -699,7 +699,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Hypervisor' => 'Hypervisor',
'Class:Hypervisor' => '虚拟机管理器',
'Class:Hypervisor+' => '',
'Class:Hypervisor/Attribute:farm_id' => '集群',
'Class:Hypervisor/Attribute:farm_id+' => '',
@@ -718,12 +718,12 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Farm' => '集群',
'Class:Farm+' => '',
'Class:Farm/Attribute:hypervisor_list' => 'Hypervisor',
'Class:Farm/Attribute:hypervisor_list+' => '集群由哪些Hypervisor 组成',
'Class:Farm/Attribute:hypervisor_list' => '虚拟机管理器',
'Class:Farm/Attribute:hypervisor_list+' => '集群由哪些虚拟机管理器组成',
'Class:Farm/Attribute:redundancy' => '高可用性',
'Class:Farm/Attribute:redundancy/disabled' => '所有Hypervisor 正常,集群才正常',
'Class:Farm/Attribute:redundancy/count' => '至少 %1$s 个Hypervisor 是正常的,集群才是正常的',
'Class:Farm/Attribute:redundancy/percent' => '至少 %1$s %% 的Hypervisor 是正常的,集群才正常',
'Class:Farm/Attribute:redundancy/disabled' => '所有虚拟机管理器正常,集群才正常',
'Class:Farm/Attribute:redundancy/count' => '至少 %1$s 个虚拟机管理器是正常的,集群才是正常的',
'Class:Farm/Attribute:redundancy/percent' => '至少 %1$s %% 的虚拟机管理器是正常的,集群才正常',
));
//
@@ -938,8 +938,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Patch/Attribute:documents_list+' => '此补丁关联的所有文档',
'Class:Patch/Attribute:description' => '描述',
'Class:Patch/Attribute:description+' => '',
'Class:Patch/Attribute:finalclass' => '补丁子类别',
'Class:Patch/Attribute:finalclass+' => 'Name of the final class',
'Class:Patch/Attribute:finalclass' => '补丁类型',
'Class:Patch/Attribute:finalclass+' => '根本属性的名称',
));
//
@@ -1003,8 +1003,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Licence/Attribute:perpetual/Value:no+' => '否',
'Class:Licence/Attribute:perpetual/Value:yes' => '是',
'Class:Licence/Attribute:perpetual/Value:yes+' => '是',
'Class:Licence/Attribute:finalclass' => '许可证子类别',
'Class:Licence/Attribute:finalclass+' => 'Name of the final class',
'Class:Licence/Attribute:finalclass' => '许可证类型',
'Class:Licence/Attribute:finalclass+' => '根本属性的名称',
));
//
@@ -1112,8 +1112,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Model/Attribute:type/Value:PowerSource+' => '电源',
'Class:Model/Attribute:type/Value:DiskArray' => '磁盘阵列',
'Class:Model/Attribute:type/Value:DiskArray+' => '磁盘阵列',
'Class:Model/Attribute:type/Value:Enclosure' => '机',
'Class:Model/Attribute:type/Value:Enclosure+' => '机',
'Class:Model/Attribute:type/Value:Enclosure' => '机',
'Class:Model/Attribute:type/Value:Enclosure+' => '机',
'Class:Model/Attribute:type/Value:IPPhone' => 'IP电话',
'Class:Model/Attribute:type/Value:IPPhone+' => 'IP电话',
'Class:Model/Attribute:type/Value:MobilePhone' => '手机',
@@ -1130,8 +1130,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Model/Attribute:type/Value:Peripheral+' => '配件',
'Class:Model/Attribute:type/Value:Printer' => '打印机',
'Class:Model/Attribute:type/Value:Printer+' => '打印机',
'Class:Model/Attribute:type/Value:Rack' => '机',
'Class:Model/Attribute:type/Value:Rack+' => '机',
'Class:Model/Attribute:type/Value:Rack' => '机',
'Class:Model/Attribute:type/Value:Rack+' => '机',
'Class:Model/Attribute:type/Value:SANSwitch' => 'SAN交换机',
'Class:Model/Attribute:type/Value:SANSwitch+' => 'SAN交换机',
'Class:Model/Attribute:type/Value:Server' => '服务器',
@@ -1321,8 +1321,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:NetworkInterface+' => '',
'Class:NetworkInterface/Attribute:name' => '名称',
'Class:NetworkInterface/Attribute:name+' => '',
'Class:NetworkInterface/Attribute:finalclass' => '网卡子类别',
'Class:NetworkInterface/Attribute:finalclass+' => 'Name of the final class',
'Class:NetworkInterface/Attribute:finalclass' => '网卡类型',
'Class:NetworkInterface/Attribute:finalclass+' => '根本属性的名称',
));
//
@@ -1336,7 +1336,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:IPInterface/Attribute:ipaddress+' => '',
'Class:IPInterface/Attribute:macaddress' => 'MAC地址',
'Class:IPInterface/Attribute:macaddress+' => '',
'Class:IPInterface/Attribute:comment' => '注',
'Class:IPInterface/Attribute:comment' => '注',
'Class:IPInterface/Attribute:coment+' => '',
'Class:IPInterface/Attribute:ipgateway' => '网关',
'Class:IPInterface/Attribute:ipgateway+' => '',
@@ -1403,7 +1403,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:FiberChannelInterface' => '光纤通道接口',
'Class:FiberChannelInterface' => '光纤接口',
'Class:FiberChannelInterface+' => '',
'Class:FiberChannelInterface/Attribute:speed' => '速率',
'Class:FiberChannelInterface/Attribute:speed+' => '',
@@ -1493,8 +1493,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Group/Attribute:name+' => '',
'Class:Group/Attribute:status' => '状态',
'Class:Group/Attribute:status+' => '',
'Class:Group/Attribute:status/Value:implementation' => '上线',
'Class:Group/Attribute:status/Value:implementation+' => '上线',
'Class:Group/Attribute:status/Value:implementation' => '生效',
'Class:Group/Attribute:status/Value:implementation+' => '生效',
'Class:Group/Attribute:status/Value:obsolete' => '废弃',
'Class:Group/Attribute:status/Value:obsolete+' => '废弃',
'Class:Group/Attribute:status/Value:production' => '生产',

View File

@@ -25,7 +25,7 @@
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:ConfigEditor' => 'Konfiguration',
'config-edit-title' => 'Konfigurations-Editor',
'config-edit-intro' => 'Seien sie bei der Bearbeitung der Konfigurationsdatei sehr vorsichtig.',
'config-edit-intro' => 'Achtung: Eine falsche Konfiguration kann dazu führen, dass '.ITOP_APPLICATION_SHORT.' für alle Benutzer unbenutzbar ist!',
'config-apply' => 'Anwenden (Ctrl+S)',
'config-apply-title' => 'Anwenden (Ctrl+S)',
'config-cancel' => 'Zurücksetzen',
@@ -36,8 +36,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'config-parse-error' => 'Zeile %2$d: %1$s.<br/>Die Datei wurde nicht aktualisiert.',
'config-current-line' => 'Editiere Zeile: %1$s',
'config-saved-warning-db-password' => 'Die Konfiguration wurde gespeichert. Das Backup wird NICHT funktionieren, im Datenbankpasswort sind unzulässige Zeichen enthalten.',
'config-error-transaction' => 'Error: invalid Transaction ID. The configuration was <b>NOT</b> modified.~~',
'config-error-file-changed' => 'Error: The Configuration file has changed since you opened it and cannot be saved. Refresh and apply your changes again.~~',
'config-not-allowed-in-demo' => 'Sorry, '.ITOP_APPLICATION_SHORT.' is in <b>demonstration mode</b>: the configuration file cannot be edited.~~',
'config-interactive-not-allowed' => ITOP_APPLICATION_SHORT.' interactive edition of the configuration as been disabled. See <code>\'config_editor\' => \'disabled\'</code> in the configuration file.~~',
'config-error-transaction' => 'Fehler: Ungültige Transaction ID. Die Konfiguration wurde <b>NICHT</b> modifiziert.',
'config-error-file-changed' => 'Fehler: Die Konfigurationsdatei hat sich seit dem Öffnen geändert und kann nicht gespeichert werden. Aktualisieren Sie die Datei und wenden Sie Ihre Änderungen erneut an.',
'config-not-allowed-in-demo' => 'Entschuldigung, '.ITOP_APPLICATION_SHORT.' befindet sich im <b>Demo-Modus</b>: Die Konfigurationsdatei kann nicht bearbeitet werden.',
'config-interactive-not-allowed' => 'Die interaktive Bearbeitung der '.ITOP_APPLICATION_SHORT.' Konfiguration wurde deaktiviert. Siehe <code>\'config_editor\' => \'disabled\'</code> in der Konfigurationsdatei.',
));

View File

@@ -51,7 +51,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'iTopUpdate:UI:WarningReadOnlyDuringUpdate' => 'Während des Upgrades läuft die Anwendung im read-only Modus',
'iTopUpdate:UI:Status' => 'Status',
'iTopUpdate:UI:Action' => 'Update',
'iTopUpdate:UI:Setup' => ITOP_APPLICATION_SHORT.' Setup~~',
'iTopUpdate:UI:Setup' => ITOP_APPLICATION_SHORT.' Setup',
'iTopUpdate:UI:History' => 'Versionshistorie',
'iTopUpdate:UI:Progress' => 'Upgradefortschritt',
'iTopUpdate:UI:DoBackup:Label' => 'Backup von Dateien und Datenbank',
@@ -70,9 +70,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'iTopUpdate:UI:CanCoreUpdate:No' => 'Anwendungsupgrade nicht möglich: %1$s',
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Vorsicht: App-Upgrade kann fehlschlagen: %1$s',
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Einige angepasste Dateien wurden erkannt</b>, eine Teil-Update kann nicht ausgeführt werden.<br/>Befolgen Sie das <a target="_blank" href="%2$s">Verfahren</a>, um Ihr iTop manuell zu aktualisieren. Sie müssen das <a href="%1$s">Setup</a> benutzen, um Ihre Applikation zu aktualisieren.<br />',
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
'iTopUpdate:UI:SetupLaunch' => 'Launch '.ITOP_APPLICATION_SHORT.' Setup~~',
'iTopUpdate:UI:SetupLaunchConfirm' => 'This will launch '.ITOP_APPLICATION_SHORT.' setup, are you sure?~~',
'iTopUpdate:UI:CheckInProgress' => 'Bitte warten Sie während der Integritätsprüfung',
'iTopUpdate:UI:SetupLaunch' => 'Starte '.ITOP_APPLICATION_SHORT.' Setup',
'iTopUpdate:UI:SetupLaunchConfirm' => 'Hiermit wird der '.ITOP_APPLICATION_SHORT.' Setup, sind Sie sicher?',
// Setup Messages
'iTopUpdate:UI:SetupMessage:Ready' => 'Bereit zum Upgrade',

View File

@@ -51,7 +51,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'iTopUpdate:UI:WarningReadOnlyDuringUpdate' => 'Pendant toute la durée de la mise à jour, l\'application sera en lecture seule.',
'iTopUpdate:UI:Status' => 'Versions installées',
'iTopUpdate:UI:Action' => 'Mettre à jour',
'iTopUpdate:UI:Setup' => ITOP_APPLICATION_SHORT.' Setup~~',
'iTopUpdate:UI:Setup' => ITOP_APPLICATION_SHORT.' Setup',
'iTopUpdate:UI:History' => 'Historique des versions',
'iTopUpdate:UI:Progress' => 'Progression de la mise à jour',
'iTopUpdate:UI:DoBackup:Label' => 'Sauvegarde de la base de données',
@@ -71,8 +71,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Attention : la mise à jour de l\'application peut échouer : %1$s',
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Des fichiers modifiés ont été détectés</b>, une mise à jour partielle ne peut pas être effectuée.<br />Suivez la <a target="_blank" href="%2$s"> procedure</a> pour mettre à jour manuellement votre iTop. Vous devez utiliser la page <a href="%1$s">d\'installation</a> pour mettre à jour l\'application.',
'iTopUpdate:UI:CheckInProgress' => 'Veuillez patienter pendant la vérification d\'intégrité',
'iTopUpdate:UI:SetupLaunch' => 'Launch '.ITOP_APPLICATION_SHORT.' Setup~~',
'iTopUpdate:UI:SetupLaunchConfirm' => 'This will launch '.ITOP_APPLICATION_SHORT.' setup, are you sure?~~',
'iTopUpdate:UI:SetupLaunch' => 'Lancer le Setup',
'iTopUpdate:UI:SetupLaunchConfirm' => 'This will launch '.ITOP_APPLICATION_SHORT.' setup, are you sure?',
// Setup Messages
'iTopUpdate:UI:SetupMessage:Ready' => 'Prêt pour l\\installation',

View File

@@ -44,8 +44,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="enclosure_list" xsi:type="AttributeLinkedSet">
<linked_class>Enclosure</linked_class>
@@ -53,8 +51,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -255,8 +251,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>
@@ -613,8 +607,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>

View File

@@ -176,8 +176,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods/>

View File

@@ -55,7 +55,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:FAQCategory/Attribute:name' => 'Name',
'Class:FAQCategory/Attribute:name+' => '',
'Class:FAQCategory/Attribute:faq_list' => 'FAQs',
'Class:FAQCategory/Attribute:faq_list+' => 'All the frequently asked questions related to this category~~',
'Class:FAQCategory/Attribute:faq_list+' => 'Alle FAQ-Einträge (frequently asked questions) verknüpft mit dieser Kategorie',
));
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:ProblemManagement' => 'Problem Management',

View File

@@ -58,7 +58,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:FAQ/Attribute:category_id+' => '',
'Class:FAQ/Attribute:category_name' => '类别名称',
'Class:FAQ/Attribute:category_name+' => '',
'Class:FAQ/Attribute:error_code' => '错误码',
'Class:FAQ/Attribute:error_code' => '错误码',
'Class:FAQ/Attribute:error_code+' => '',
'Class:FAQ/Attribute:key_words' => '关键字',
'Class:FAQ/Attribute:key_words+' => '',

View File

@@ -24,7 +24,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
// Errors
'FilesInformation:Error:MissingFile' => 'Fehlende Datei: %1$s',
'FilesInformation:Error:CorruptedFile' => 'Datei %1$s ist beschädigt',
'FilesInformation:Error:ListCorruptedFile' => 'File(s) corrupted: %1$s~~',
'FilesInformation:Error:ListCorruptedFile' => 'Beschädigte Datei(en): %1$s',
'FilesInformation:Error:CantWriteToFile' => 'Datei %1$s kann nicht geschrieben werden',
));

View File

@@ -458,8 +458,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="child_incidents_list" xsi:type="AttributeLinkedSet">
<linked_class>Incident</linked_class>
@@ -467,8 +465,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="public_log" xsi:type="AttributeCaseLog">
<sql>public_log</sql>

View File

@@ -28,17 +28,17 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:Incident:Overview' => 'Übersicht',
'Menu:Incident:Overview+' => '',
'Menu:NewIncident' => 'Neuer Incident',
'Menu:NewIncident+' => '',
'Menu:NewIncident+' => 'Einen neuen Incident dokumentieren',
'Menu:SearchIncidents' => 'Nach Incidents suchen',
'Menu:SearchIncidents+' => '',
'Menu:SearchIncidents+' => 'Suche nach einem bestehendem Incident',
'Menu:Incident:Shortcuts' => 'Shortcuts',
'Menu:Incident:Shortcuts+' => '',
'Menu:Incident:MyIncidents' => 'Mir zugewiesene Incidents',
'Menu:Incident:MyIncidents+' => '',
'Menu:Incident:MyIncidents+' => 'Incidents die mir als Bearbeiter zugewiesen sind',
'Menu:Incident:EscalatedIncidents' => 'Eskalierte Incidents',
'Menu:Incident:EscalatedIncidents+' => '',
'Menu:Incident:EscalatedIncidents+' => 'Incidents die eskaliert sind',
'Menu:Incident:OpenIncidents' => 'Alle offenen Incidents',
'Menu:Incident:OpenIncidents+' => '',
'Menu:Incident:OpenIncidents+' => 'Alle offenen Incidents',
'UI-IncidentManagementOverview-IncidentByPriority-last-14-days' => 'Incidents der letzten 14 Tage nach Priorität',
'UI-IncidentManagementOverview-Last-14-days' => 'Anzahl Incidents der letzten 14 Tage',
'UI-IncidentManagementOverview-OpenIncidentByStatus' => 'Offene Incidents nach Status',
@@ -83,7 +83,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Incident/Attribute:status/Value:closed' => 'Geschlossen',
'Class:Incident/Attribute:status/Value:closed+' => '',
'Class:Incident/Attribute:impact' => 'Auswirkung',
'Class:Incident/Attribute:impact+' => '',
'Class:Incident/Attribute:impact+' => 'Die Auswirkung gibt die Schwere des Vorfalls an, oft geschätzt durch die Anzahl der Betroffenen',
'Class:Incident/Attribute:impact/Value:1' => 'Eine Abteilung',
'Class:Incident/Attribute:impact/Value:1+' => '',
'Class:Incident/Attribute:impact/Value:2' => 'Ein Service',
@@ -101,7 +101,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Incident/Attribute:priority/Value:4' => 'Niedrig',
'Class:Incident/Attribute:priority/Value:4+' => '',
'Class:Incident/Attribute:urgency' => 'Dringlichkeit',
'Class:Incident/Attribute:urgency+' => '',
'Class:Incident/Attribute:urgency+' => 'Wie schnell der Vorfall behandelt werden muss',
'Class:Incident/Attribute:urgency/Value:1' => 'Kritisch',
'Class:Incident/Attribute:urgency/Value:1+' => '',
'Class:Incident/Attribute:urgency/Value:2' => 'Hoch',
@@ -112,18 +112,18 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Incident/Attribute:urgency/Value:4+' => '',
'Class:Incident/Attribute:origin' => 'Herkunft',
'Class:Incident/Attribute:origin+' => '',
'Class:Incident/Attribute:origin/Value:in_person' => 'In-person~~',
'Class:Incident/Attribute:origin/Value:in_person+' => 'Incident created following a face-to-face discussion~~',
'Class:Incident/Attribute:origin/Value:chat' => 'Chat~~',
'Class:Incident/Attribute:origin/Value:chat+' => 'Incident created following a ~~',
'Class:Incident/Attribute:origin/Value:in_person' => 'Persönlich',
'Class:Incident/Attribute:origin/Value:in_person+' => 'Incident auf Basis einer Diskussion im direkten Gespräch',
'Class:Incident/Attribute:origin/Value:chat' => 'Chat',
'Class:Incident/Attribute:origin/Value:chat+' => 'Incident auf Basis einer Diskussion in einem Chat',
'Class:Incident/Attribute:origin/Value:mail' => 'Mail',
'Class:Incident/Attribute:origin/Value:mail+' => '',
'Class:Incident/Attribute:origin/Value:mail+' => 'Incident auf Basis einer empfangenen Mail',
'Class:Incident/Attribute:origin/Value:monitoring' => 'Monitoring',
'Class:Incident/Attribute:origin/Value:monitoring+' => '',
'Class:Incident/Attribute:origin/Value:monitoring+' => 'Incident auf Basis eines Monitoring-Events',
'Class:Incident/Attribute:origin/Value:phone' => 'Telefon',
'Class:Incident/Attribute:origin/Value:phone+' => '',
'Class:Incident/Attribute:origin/Value:phone+' => 'Incident auf Basis eines Telefonanrufs',
'Class:Incident/Attribute:origin/Value:portal' => 'Portal',
'Class:Incident/Attribute:origin/Value:portal+' => '',
'Class:Incident/Attribute:origin/Value:portal+' => 'Incident, der über das Portal erstellt wurde',
'Class:Incident/Attribute:service_id' => 'Service',
'Class:Incident/Attribute:service_id+' => '',
'Class:Incident/Attribute:service_name' => 'Service-Name',
@@ -169,7 +169,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Incident/Attribute:resolution_code' => 'Lösungs-Code',
'Class:Incident/Attribute:resolution_code+' => '',
'Class:Incident/Attribute:resolution_code/Value:assistance' => 'Unterstützung',
'Class:Incident/Attribute:resolution_code/Value:assistance+' => '',
'Class:Incident/Attribute:resolution_code/Value:assistance+' => 'Was wurde unternommen, um den Incident zu beheben?',
'Class:Incident/Attribute:resolution_code/Value:bug fixed' => 'Bugfix',
'Class:Incident/Attribute:resolution_code/Value:bug fixed+' => '',
'Class:Incident/Attribute:resolution_code/Value:hardware repair' => 'Hardware-Reparatur',
@@ -201,7 +201,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Incident/Attribute:related_request_list' => 'Kind-Requests',
'Class:Incident/Attribute:related_request_list+' => '',
'Class:Incident/Attribute:child_incidents_list' => 'Abgeleitete Incidents',
'Class:Incident/Attribute:child_incidents_list+' => 'All the child incidents related to this incident~~',
'Class:Incident/Attribute:child_incidents_list+' => 'Alle abgeleiteten Incidents, die mit diesem Incident verknüpft sind',
'Class:Incident/Attribute:public_log' => 'Öffentliches Log',
'Class:Incident/Attribute:public_log+' => '',
'Class:Incident/Attribute:user_satisfaction' => 'Benutzerzufriedenheit',
@@ -216,7 +216,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Incident/Attribute:user_satisfaction/Value:4+' => '',
'Class:Incident/Attribute:user_comment' => 'Benutzer-Kommentar',
'Class:Incident/Attribute:user_comment+' => '',
'Class:Incident/Attribute:parent_incident_id_friendlyname' => 'Parent-Incident-Friendly Name',
'Class:Incident/Attribute:parent_incident_id_friendlyname' => 'Parent-Incident Anzeigename',
'Class:Incident/Attribute:parent_incident_id_friendlyname+' => '',
'Class:Incident/Stimulus:ev_assign' => 'Zuweisen',
'Class:Incident/Stimulus:ev_assign+' => '',

View File

@@ -66,11 +66,11 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:status+' => '',
'Class:Incident/Attribute:status/Value:new' => '新建',
'Class:Incident/Attribute:status/Value:new+' => '',
'Class:Incident/Attribute:status/Value:escalated_tto' => '已升级响应时间',
'Class:Incident/Attribute:status/Value:escalated_tto' => '已升级TTO',
'Class:Incident/Attribute:status/Value:escalated_tto+' => '',
'Class:Incident/Attribute:status/Value:assigned' => '已分配',
'Class:Incident/Attribute:status/Value:assigned+' => '',
'Class:Incident/Attribute:status/Value:escalated_ttr' => '已升级解决时间',
'Class:Incident/Attribute:status/Value:escalated_ttr' => '已升级TTR',
'Class:Incident/Attribute:status/Value:escalated_ttr+' => '',
'Class:Incident/Attribute:status/Value:waiting_for_approval' => '等待批准',
'Class:Incident/Attribute:status/Value:waiting_for_approval+' => '',
@@ -90,8 +90,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:impact/Value:3+' => '',
'Class:Incident/Attribute:priority' => '优先级',
'Class:Incident/Attribute:priority+' => '',
'Class:Incident/Attribute:priority/Value:1' => '非常高',
'Class:Incident/Attribute:priority/Value:1+' => '非常高',
'Class:Incident/Attribute:priority/Value:1' => '紧急',
'Class:Incident/Attribute:priority/Value:1+' => '紧急',
'Class:Incident/Attribute:priority/Value:2' => '高',
'Class:Incident/Attribute:priority/Value:2+' => '高',
'Class:Incident/Attribute:priority/Value:3' => '中',
@@ -100,8 +100,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:priority/Value:4+' => '低',
'Class:Incident/Attribute:urgency' => '紧急度',
'Class:Incident/Attribute:urgency+' => '',
'Class:Incident/Attribute:urgency/Value:1' => '非常高',
'Class:Incident/Attribute:urgency/Value:1+' => '非常高',
'Class:Incident/Attribute:urgency/Value:1' => '紧急',
'Class:Incident/Attribute:urgency/Value:1+' => '紧急',
'Class:Incident/Attribute:urgency/Value:2' => '高',
'Class:Incident/Attribute:urgency/Value:2+' => '高',
'Class:Incident/Attribute:urgency/Value:3' => '中',
@@ -136,7 +136,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:escalation_flag/Value:no+' => '否',
'Class:Incident/Attribute:escalation_flag/Value:yes' => '是',
'Class:Incident/Attribute:escalation_flag/Value:yes+' => '是',
'Class:Incident/Attribute:escalation_reason' => '热门',
'Class:Incident/Attribute:escalation_reason' => '升级原因',
'Class:Incident/Attribute:escalation_reason+' => '',
'Class:Incident/Attribute:assignment_date' => '分配日期',
'Class:Incident/Attribute:assignment_date+' => '',
@@ -146,21 +146,21 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:last_pending_date+' => '',
'Class:Incident/Attribute:cumulatedpending' => '累计待定',
'Class:Incident/Attribute:cumulatedpending+' => '',
'Class:Incident/Attribute:tto' => '响应时间',
'Class:Incident/Attribute:tto+' => '',
'Class:Incident/Attribute:ttr' => '解决时间',
'Class:Incident/Attribute:ttr+' => '',
'Class:Incident/Attribute:tto_escalation_deadline' => '响应时间截止',
'Class:Incident/Attribute:tto' => 'TTO',
'Class:Incident/Attribute:tto+' => '响应时间',
'Class:Incident/Attribute:ttr' => 'TTR',
'Class:Incident/Attribute:ttr+' => '解决时限',
'Class:Incident/Attribute:tto_escalation_deadline' => 'TTO截止日期',
'Class:Incident/Attribute:tto_escalation_deadline+' => '',
'Class:Incident/Attribute:sla_tto_passed' => '超过SLA响应时间',
'Class:Incident/Attribute:sla_tto_passed' => 'SLA TTO 合格',
'Class:Incident/Attribute:sla_tto_passed+' => '',
'Class:Incident/Attribute:sla_tto_over' => 'SLA响应时间结束',
'Class:Incident/Attribute:sla_tto_over' => 'SLA TTO 超时',
'Class:Incident/Attribute:sla_tto_over+' => '',
'Class:Incident/Attribute:ttr_escalation_deadline' => '解决时间截止',
'Class:Incident/Attribute:ttr_escalation_deadline' => 'TTR截止日期',
'Class:Incident/Attribute:ttr_escalation_deadline+' => '',
'Class:Incident/Attribute:sla_ttr_passed' => '超过SLA解决时间',
'Class:Incident/Attribute:sla_ttr_passed' => 'SLA TTR 合格',
'Class:Incident/Attribute:sla_ttr_passed+' => '',
'Class:Incident/Attribute:sla_ttr_over' => 'SLA解决时间结束',
'Class:Incident/Attribute:sla_ttr_over' => 'SLA TTR 超时',
'Class:Incident/Attribute:sla_ttr_over+' => '',
'Class:Incident/Attribute:time_spent' => '耗时',
'Class:Incident/Attribute:time_spent+' => '',
@@ -182,7 +182,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:resolution_code/Value:training+' => '培训',
'Class:Incident/Attribute:solution' => '解决方案',
'Class:Incident/Attribute:solution+' => '',
'Class:Incident/Attribute:pending_reason' => '待定原因',
'Class:Incident/Attribute:pending_reason' => '待定原因',
'Class:Incident/Attribute:pending_reason+' => '',
'Class:Incident/Attribute:parent_incident_id' => '父级事件',
'Class:Incident/Attribute:parent_incident_id+' => '',
@@ -198,8 +198,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Attribute:parent_problem_ref+' => '~~',
'Class:Incident/Attribute:related_request_list' => '相关需求',
'Class:Incident/Attribute:related_request_list+' => '此事件相关的所有需求',
'Class:Incident/Attribute:child_incidents_list' => '衍生事件',
'Class:Incident/Attribute:child_incidents_list+' => '此事件相关的所有事件',
'Class:Incident/Attribute:child_incidents_list' => '事件',
'Class:Incident/Attribute:child_incidents_list+' => '此事件相关的所有衍生事件',
'Class:Incident/Attribute:public_log' => '评论',
'Class:Incident/Attribute:public_log+' => '',
'Class:Incident/Attribute:user_satisfaction' => '用户满意度',
@@ -234,8 +234,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Incident/Stimulus:ev_close+' => '',
'Class:Incident/Stimulus:ev_reopen' => '重新打开',
'Class:Incident/Stimulus:ev_reopen+' => '',
'Class:Incident/Error:CannotAssignParentIncidentIdToSelf' => '不能分配父级事件给自己',
'Class:Incident/Error:CannotAssignParentIncidentIdToSelf' => '无法分配父级事件给自己',
'Class:Incident/Method:ResolveChildTickets' => '解决子工单',
'Class:Incident/Method:ResolveChildTickets+' => '级联解决子Ticket(事件自动解决),调整以下内容保持一: 服务, 团队, 办理人, 解决方案',
'Class:Incident/Method:ResolveChildTickets+' => '递归解决子工单(自动解决),调整相关字段与父级工单保持一: 服务, 团队, 办理人, 解决方案',
'Tickets:Related:OpenIncidents' => '打开的事件',
));

View File

@@ -122,7 +122,6 @@
<count_max>0</count_max>
<ext_key_to_remote>functionalci_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="document_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkDocumentToError</linked_class>
@@ -131,7 +130,6 @@
<count_max>0</count_max>
<ext_key_to_remote>document_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<methods/>

View File

@@ -24,7 +24,7 @@
*/
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:KnownError' => 'Known Error',
'Class:KnownError+' => 'Dokumentierter Fehler für ein Issue',
'Class:KnownError+' => 'Dokumentierter Fehler für ein Problem',
'Class:KnownError/Attribute:name' => 'Name',
'Class:KnownError/Attribute:name+' => '',
'Class:KnownError/Attribute:org_id' => 'Kunde',
@@ -62,9 +62,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:KnownError/Attribute:version' => 'Version',
'Class:KnownError/Attribute:version+' => '',
'Class:KnownError/Attribute:ci_list' => 'CIs',
'Class:KnownError/Attribute:ci_list+' => 'All the configuration items that are related to this known error~~',
'Class:KnownError/Attribute:ci_list+' => 'Alle CIs, die mit diesem Known Error verknüpft sind',
'Class:KnownError/Attribute:document_list' => 'Dokumente',
'Class:KnownError/Attribute:document_list+' => 'All the documents linked to this known error~~',
'Class:KnownError/Attribute:document_list+' => 'Alle Dokumente, die mit diesem Known Error verknüpft sind',
));
//
@@ -74,7 +74,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkErrorToFunctionalCI' => 'Verknüpfung KnownError/FunctionalCI',
'Class:lnkErrorToFunctionalCI+' => '',
'Class:lnkErrorToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkErrorToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id' => 'CI',
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_name' => 'CI-Name',
@@ -94,7 +94,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkDocumentToError' => 'Verknüpfung Dokumente/KnownError',
'Class:lnkDocumentToError+' => '',
'Class:lnkDocumentToError/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToError/Name' => '%1$s / %2$s',
'Class:lnkDocumentToError/Attribute:document_id' => 'Dokument',
'Class:lnkDocumentToError/Attribute:document_id+' => '',
'Class:lnkDocumentToError/Attribute:document_name' => 'Dokumentname',
@@ -112,9 +112,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:ProblemManagement+' => 'Problem Management',
'Menu:Problem:Shortcuts' => 'Shortcuts',
'Menu:NewError' => 'Neuer Known Error',
'Menu:NewError+' => '',
'Menu:NewError+' => 'Neuen Known Error dokumentieren',
'Menu:SearchError' => 'Nach Known Error suchen',
'Menu:SearchError+' => '',
'Menu:SearchError+' => 'Nach dokumentierten Fehlern suchen',
'Menu:Problem:KnownErrors' => 'Alle Known Errors',
'Menu:Problem:KnownErrors+' => 'Alle Known Errors',
));

View File

@@ -74,7 +74,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkErrorToFunctionalCI' => 'Lien Erreur / CI',
'Class:lnkErrorToFunctionalCI+' => 'Lien entre une erreur et un ci',
'Class:lnkErrorToFunctionalCI/Name' => '%1$s / %2$s~~',
'Class:lnkErrorToFunctionalCI/Name' => '%1$s / %2$s',
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id' => 'CI',
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkErrorToFunctionalCI/Attribute:functionalci_name' => 'Nom CI',
@@ -94,7 +94,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
Dict::Add('FR FR', 'French', 'Français', array(
'Class:lnkDocumentToError' => 'Lien Documents / Errors',
'Class:lnkDocumentToError+' => 'Lien entre un document et une erreur',
'Class:lnkDocumentToError/Name' => '%1$s / %2$s~~',
'Class:lnkDocumentToError/Name' => '%1$s / %2$s',
'Class:lnkDocumentToError/Attribute:document_id' => 'Document',
'Class:lnkDocumentToError/Attribute:document_id+' => '',
'Class:lnkDocumentToError/Attribute:document_name' => 'Nom Document',

View File

@@ -66,7 +66,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:KnownError/Attribute:workaround+' => '',
'Class:KnownError/Attribute:solution' => '解决方案',
'Class:KnownError/Attribute:solution+' => '',
'Class:KnownError/Attribute:error_code' => '错误码',
'Class:KnownError/Attribute:error_code' => '错误码',
'Class:KnownError/Attribute:error_code+' => '',
'Class:KnownError/Attribute:domain' => '类型',
'Class:KnownError/Attribute:domain+' => '',

View File

@@ -112,8 +112,6 @@
<ext_key_to_me>oauth_client_id</ext_key_to_me>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<methods>
@@ -232,6 +230,7 @@ HTML
$this->Set('refresh_token', $oAccessToken->getRefreshToken());
}
$this->Set('status', 'active');
$this->AllowWrite();
$this->DBUpdate();
}
]]></code>

View File

@@ -9,20 +9,20 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
'Menu:CreateMailbox' => 'Mailpostfach erstellen...',
'Menu:OAuthClient' => 'OAuth-Client',
'Menu:OAuthClient+' => '',
'Menu:GenerateTokens' => 'Zugriffs-Token generieren...',
'Menu:RegenerateTokens' => 'Zugriffs-Token neu generieren...',
'Menu:GenerateTokens' => 'Zugriffstoken generieren...',
'Menu:RegenerateTokens' => 'Zugriffstoken neu generieren...',
'itop-oauth-client/Operation:CreateMailBox/Title' => 'Mailpostfach-Erstellung',
'itop-oauth-client:UsedForSMTP' => 'Dieser OAuth-Client wird für SMTP verwendet',
'itop-oauth-client:TestSMTP' => 'Mail-Versand testen',
'itop-oauth-client:MissingOAuthClient' => 'Fehlender OAuth-Client für den Benutzernamen %1$s',
'itop-oauth-client:Message:MissingToken' => 'Bitte Zugriffs-Token generieren bevor der OAuth-Client verwendet wird',
'itop-oauth-client:Message:RegenerateToken' => 'Regenerate access token to to take into account the changes~~',
'itop-oauth-client:Message:TokenCreated' => 'Zugriffs-Token erstellt',
'itop-oauth-client:Message:TokenRecreated' => 'Zugriffs-Token neu erstellt',
'itop-oauth-client:Message:TokenError' => 'Access token not generated due to server error~~',
'OAuthClient:Name/UseForSMTPMustBeUnique' => 'The combination Login (%1$s) and Use for SMTP (%2$s) has already be used for OAuth Client~~',
'OAuthClient:baseinfo' => 'Base Information~~',
'OAuthClient:scope' => 'Scope~~',
'itop-oauth-client:Message:MissingToken' => 'Bitte Zugriffstoken generieren bevor der OAuth-Client verwendet wird',
'itop-oauth-client:Message:RegenerateToken' => 'Generieren Sie das Zugriffstoken neu, um die Änderungen zu berücksichtigen',
'itop-oauth-client:Message:TokenCreated' => 'Zugriffstoken erstellt',
'itop-oauth-client:Message:TokenRecreated' => 'Zugriffstoken neu erstellt',
'itop-oauth-client:Message:TokenError' => 'Das Zugriffstoken wurde aufgrund eines Serverfehlers nicht generiert.',
'OAuthClient:Name/UseForSMTPMustBeUnique' => 'Die Kombination aus "Login" (%1$s) und "Verwendung für SMTP" (%2$s) existiert bereits.',
'OAuthClient:baseinfo' => 'Allgemeine Informationen',
'OAuthClient:scope' => 'Scope',
]);
//
@@ -37,26 +37,30 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
'Class:OAuthClient/Attribute:name+' => '',
'Class:OAuthClient/Attribute:scope' => 'Scope',
'Class:OAuthClient/Attribute:scope+' => '',
'Class:OAuthClient/Attribute:status' => 'Status~~',
'Class:OAuthClient/Attribute:status+' => 'After creation, use the action “Generate access token” to be able to use this OAuth client~~',
'Class:OAuthClient/Attribute:status/Value:active' => 'Access token generated~~',
'Class:OAuthClient/Attribute:status/Value:inactive' => 'No Access token~~',
'Class:OAuthClient/Attribute:status' => 'Status',
'Class:OAuthClient/Attribute:status+' => 'Führen Sie nach der Objekterstellung die Aktion "Zugriffstoken generieren..." aus, um diesen oAuth-Client zu aktivieren.',
'Class:OAuthClient/Attribute:status/Value:active' => 'Zugriffstoken erstellt',
'Class:OAuthClient/Attribute:status/Value:inactive' => 'Kein Zugriffstoken',
'Class:OAuthClient/Attribute:description' => 'Beschreibung',
'Class:OAuthClient/Attribute:description+' => '',
'Class:OAuthClient/Attribute:client_id' => 'Client ID',
'Class:OAuthClient/Attribute:client_id+' => '',
'Class:OAuthClient/Attribute:client_id+' => 'Eine lange Zeichenfolge, die durch den oAuth2-Provider bereitgestellt wird',
'Class:OAuthClient/Attribute:client_secret' => 'Client Secret',
'Class:OAuthClient/Attribute:client_secret+' => '',
'Class:OAuthClient/Attribute:client_secret+' => 'Eine weitere lange Zeichenfolge, die durch den oAuth2-Provider bereitgestellt wird',
'Class:OAuthClient/Attribute:refresh_token' => 'Erneuerungs-Token',
'Class:OAuthClient/Attribute:refresh_token+' => '',
'Class:OAuthClient/Attribute:refresh_token_expiration' => 'Erneuerungs-Token Ablaufzeitpunkt',
'Class:OAuthClient/Attribute:refresh_token_expiration+' => '',
'Class:OAuthClient/Attribute:token' => 'Zugriffs-Token',
'Class:OAuthClient/Attribute:token' => 'Zugriffstoken',
'Class:OAuthClient/Attribute:token+' => '',
'Class:OAuthClient/Attribute:token_expiration' => 'Zugriffs-Token Ablaufszeitpunkt',
'Class:OAuthClient/Attribute:token_expiration' => 'Zugriffstoken Ablaufszeitpunkt',
'Class:OAuthClient/Attribute:token_expiration+' => '',
'Class:OAuthClient/Attribute:redirect_url' => 'Umleitungs-URL',
'Class:OAuthClient/Attribute:redirect_url+' => '',
'Class:OAuthClient/Attribute:redirect_url+' => <<<EOF
Diese URL muss in die oAuth2-Konfiguration des Providers kopiert werden.
Löschen Sie das Feld, um den Standardwert neu zu berechnen.
EOF
,
'Class:OAuthClient/Attribute:mailbox_list' => 'Mailpostfächer',
'Class:OAuthClient/Attribute:mailbox_list+' => ''
]);
@@ -68,24 +72,24 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:OAuthClientAzure' => 'OAuth-Client für Microsoft Azure',
'Class:OAuthClientAzure/Name' => '%1$s (%2$s)',
'Class:OAuthClientAzure/Attribute:scope' => 'Scope~~',
'Class:OAuthClientAzure/Attribute:scope+' => 'Usually default selection is appropriate~~',
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP' => 'SMTP~~',
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP+' => '~~',
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP' => 'IMAP~~',
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP+' => '~~',
'Class:OAuthClientAzure/Attribute:advanced_scope' => 'Advanced scope~~',
'Class:OAuthClientAzure/Attribute:advanced_scope+' => 'As soon as you enter something here it takes precedence on the “Scope” selection which is then ignored~~',
'Class:OAuthClientAzure/Attribute:used_scope' => 'Used scope~~',
'Class:OAuthClientAzure/Attribute:used_scope+' => '~~',
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple' => 'Simple~~',
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple+' => '~~',
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced' => 'Advanced~~',
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced+' => '~~',
'Class:OAuthClientAzure/Attribute:used_for_smtp' => 'Used for SMTP~~',
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails~~',
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Yes~~',
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'No~~',
'Class:OAuthClientAzure/Attribute:scope' => 'Scope',
'Class:OAuthClientAzure/Attribute:scope+' => 'Normalerweise ist die Standardauswahl ausreichend.',
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP' => 'SMTP',
'Class:OAuthClientAzure/Attribute:scope/Value:SMTP+' => '',
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP' => 'IMAP',
'Class:OAuthClientAzure/Attribute:scope/Value:IMAP+' => '',
'Class:OAuthClientAzure/Attribute:advanced_scope' => 'Erweiterter Scope',
'Class:OAuthClientAzure/Attribute:advanced_scope+' => 'Sobald Sie hier etwas eingeben, hat es Vorrang vor der Auswahl im Feld "Scope", die dann ignoriert wird.',
'Class:OAuthClientAzure/Attribute:used_scope' => 'Angewendeter Scope',
'Class:OAuthClientAzure/Attribute:used_scope+' => '',
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple' => 'Einfach',
'Class:OAuthClientAzure/Attribute:used_scope/Value:simple+' => '',
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced' => 'Erweitert',
'Class:OAuthClientAzure/Attribute:used_scope/Value:advanced+' => '',
'Class:OAuthClientAzure/Attribute:used_for_smtp' => 'Verwendung für SMTP',
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'Mindestens ein oAuth-Client muss dieses Flag auf "Ja" gesetzt haben, um über diesen Weg Mails durch iTop senden zu lassen.',
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Ja',
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'Nein',
));
//
@@ -95,22 +99,22 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:OAuthClientGoogle' => 'OAuth-Client für Google',
'Class:OAuthClientGoogle/Name' => '%1$s (%2$s)',
'Class:OAuthClientGoogle/Attribute:scope' => 'Scope~~',
'Class:OAuthClientGoogle/Attribute:scope+' => 'Usually default selection is appropriate~~',
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP' => 'SMTP~~',
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP+' => '~~',
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP' => 'IMAP~~',
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP+' => '~~',
'Class:OAuthClientGoogle/Attribute:advanced_scope' => 'Advanced scope~~',
'Class:OAuthClientGoogle/Attribute:advanced_scope+' => 'As soon as you enter something here it takes precedence on the “Scope” selection which is then ignored~~',
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Used scope~~',
'Class:OAuthClientGoogle/Attribute:used_scope+' => '~~',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Simple~~',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple+' => '~~',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Advanced~~',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '~~',
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Used for SMTP~~',
'Class:OAuthClientGoogle/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails~~',
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:yes' => 'Yes~~',
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:no' => 'No~~',
'Class:OAuthClientGoogle/Attribute:scope' => 'Scope',
'Class:OAuthClientGoogle/Attribute:scope+' => 'Normalerweise ist die Standardauswahl ausreichend.',
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP' => 'SMTP',
'Class:OAuthClientGoogle/Attribute:scope/Value:SMTP+' => '',
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP' => 'IMAP',
'Class:OAuthClientGoogle/Attribute:scope/Value:IMAP+' => '',
'Class:OAuthClientGoogle/Attribute:advanced_scope' => 'Erweiterter Scope',
'Class:OAuthClientGoogle/Attribute:advanced_scope+' => 'Sobald Sie hier etwas eingeben, hat es Vorrang vor der Auswahl im Feld "Scope", die dann ignoriert wird.',
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Angewendeter Scope',
'Class:OAuthClientGoogle/Attribute:used_scope+' => '',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Einfach',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple+' => '',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Erweitert',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '',
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Verwendung für SMTP',
'Class:OAuthClientGoogle/Attribute:used_for_smtp+' => 'Mindestens ein oAuth-Client muss dieses Flag auf "Ja" gesetzt haben, um über diesen Weg Mails durch iTop senden zu lassen.',
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:yes' => 'Ja',
'Class:OAuthClientGoogle/Attribute:used_for_smtp/Value:no' => 'Nein',
));

View File

@@ -109,7 +109,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'Class:OAuthClientGoogle/Attribute:used_scope' => 'Niveaux d\'accès utilisés',
'Class:OAuthClientGoogle/Attribute:used_scope+' => '',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple' => 'Simple',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple+' => '~~',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:simple+' => '',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced' => 'Avancé',
'Class:OAuthClientGoogle/Attribute:used_scope/Value:advanced+' => '',
'Class:OAuthClientGoogle/Attribute:used_for_smtp' => 'Utilisé pour SMTP',

View File

@@ -11,6 +11,7 @@ use Combodo\iTop\Application\TwigBase\Controller\Controller;
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
use Dict;
use IssueLog;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use MetaModel;
use utils;
use WebPage;
@@ -65,13 +66,15 @@ class AjaxOauthClientController extends Controller
}
if (isset($aQuery['code'])) {
$sCode = $aQuery['code'];
$oAccessToken = OAuthClientProviderFactory::GetAccessTokenFromCode($oOAuthClient, $sCode);
$oOAuthClient->SetAccessToken($oAccessToken);
$aResult['status'] = 'success';
try {
$oAccessToken = OAuthClientProviderFactory::GetAccessTokenFromCode($oOAuthClient, $sCode);
$oOAuthClient->SetAccessToken($oAccessToken);
$aResult['status'] = 'success';
}
catch (IdentityProviderException $e) {
$aResult['status'] = 'error';
$aResult['error_description'] = $e->getMessage();
}
}
} else {
$aResult['status'] = 'error';

View File

@@ -36,17 +36,17 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Error:HTTP:400' => '请求错误',
'Error:HTTP:401' => '认证错误',
'Error:HTTP:404' => '页面找不到',
'Error:HTTP:500' => 'Oops! 发生了一个错误.',
'Error:HTTP:500' => 'Oops! 发生了错误.',
'Error:HTTP:GetHelp' => '如果问题仍然存在,请联系管理员.',
'Error:XHR:Fail' => '无法加载数据, 请联系管理员',
'Portal:ErrorUserLoggedOut' => '您已退出,请重新登录.',
'Portal:Datatables:Language:Processing' => '请稍后...',
'Portal:Datatables:Language:Search' => '过滤器:',
'Portal:Datatables:Language:Search' => '筛选器:',
'Portal:Datatables:Language:LengthMenu' => '每页显示 _MENU_ 项',
'Portal:Datatables:Language:ZeroRecords' => '没有结果',
'Portal:Datatables:Language:Info' => '第 _PAGE_ 页,共 _PAGES_ 页',
'Portal:Datatables:Language:InfoEmpty' => '没有信息',
'Portal:Datatables:Language:InfoFiltered' => '最多过滤 _MAX_ 项',
'Portal:Datatables:Language:InfoFiltered' => '最多筛选 _MAX_ 项',
'Portal:Datatables:Language:EmptyTable' => '表格中没有数据',
'Portal:Datatables:Language:DisplayLength:All' => '全部',
'Portal:Datatables:Language:Paginate:First' => '首页',

View File

@@ -87,6 +87,12 @@ $(function()
// Submit event from the form should be treated as a click on the submit button
// as it processes things before sending the request
this.element.on('submit', function(oEvent) {
// N°6500 Abort if event doesn't come from this form
// eg. Extensions like "approval-base" add a sub (HTML) form in the buttons sections of this (conceptual) form, which can cause the submit of that sub form to be catched here first and therefore go to unexpected behavior.
if (oEvent.target !== oEvent.currentTarget) {
return;
}
me._onSubmitClick(oEvent);
});
},

View File

@@ -783,7 +783,7 @@ class ObjectFormManager extends FormManager
{
// Note: We can't do this in AttributeExternalKey::MakeFormField() in the Field::SetOnFinalizeCallback() because at this point we have no information about the portal scope and ignore_silos flag, hence it always applies silos.
// As a workaround we have to manually check if the field's current value is among the scope
$oField->VerifyCurrentValue();
$oField->ResetCurrentValueIfNotAmongAllowedValues();
}
// - Field that require processing on their subfields
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SubFormField')))
@@ -820,7 +820,7 @@ class ObjectFormManager extends FormManager
if (in_array(get_class($oCustomField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField')))
{
/** @var \Combodo\iTop\Form\Field\SelectObjectField $oCustomField */
$oCustomField->VerifyCurrentValue();
$oCustomField->ResetCurrentValueIfNotAmongAllowedValues();
}
}
}

View File

@@ -34,7 +34,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Brick:Portal:NewRequest:Title' => '新建工单',
'Brick:Portal:NewRequest:Title+' => '<p>需要帮助?</p><p>选择子服务,然后提交工单给我们的支持团队.</p>',
'Brick:Portal:OngoingRequests:Title' => '正在处理的工单',
'Brick:Portal:OngoingRequests:Title+' => '<p>跟踪正在处理的工单.</p><p>查询进度, 添加留言, 添加附件, 确认解决方案.</p>',
'Brick:Portal:OngoingRequests:Title+' => '<p>跟踪正在处理的工单.</p><p>查询进度, 添加评论, 添加附件, 确认解决方案.</p>',
'Brick:Portal:OngoingRequests:Tab:OnGoing' => '正在处理',
'Brick:Portal:OngoingRequests:Tab:Resolved' => '已解决',
'Brick:Portal:ClosedRequests:Title' => '已关闭的工单',

View File

@@ -215,8 +215,6 @@
<edit_mode>add_only</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="related_request_list" xsi:type="AttributeLinkedSet">
<linked_class>UserRequest</linked_class>
@@ -224,8 +222,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="related_incident_list" xsi:type="AttributeLinkedSet">
<linked_class>Incident</linked_class>
@@ -233,8 +229,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
</fields>
<lifecycle>

View File

@@ -24,16 +24,16 @@
*/
Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:ProblemManagement' => 'Problem Management',
'Menu:ProblemManagement+' => 'Problem Management',
'Menu:ProblemManagement+' => '',
'Menu:Problem:Overview' => 'Übersicht',
'Menu:Problem:Overview+' => 'Übersicht',
'Menu:Problem:Overview+' => '',
'Menu:NewProblem' => 'Neues Problem',
'Menu:NewProblem+' => 'Neues Problem',
'Menu:NewProblem+' => '',
'Menu:SearchProblems' => 'Nach Problemen suchen',
'Menu:SearchProblems+' => 'Nach Problemen suchen',
'Menu:SearchProblems+' => '',
'Menu:Problem:Shortcuts' => 'Shortcuts',
'Menu:Problem:MyProblems' => 'Meine Probleme',
'Menu:Problem:MyProblems+' => 'Meine Probleme',
'Menu:Problem:MyProblems+' => '',
'Menu:Problem:OpenProblems' => 'Alle offenen Probleme',
'Menu:Problem:OpenProblems+' => 'Alle offenen (noch nicht geschlossenen) Probleme',
'UI-ProblemManagementOverview-ProblemByService' => 'Probleme nach Service',
@@ -110,11 +110,11 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Problem/Attribute:resolution_date' => 'Datum der Lösung',
'Class:Problem/Attribute:resolution_date+' => '',
'Class:Problem/Attribute:knownerrors_list' => 'Bekannte Fehler',
'Class:Problem/Attribute:knownerrors_list+' => 'All the known errors that are linked to this problem~~',
'Class:Problem/Attribute:knownerrors_list+' => 'Alle bekannten Fehler verknüpft mit diesem Problem',
'Class:Problem/Attribute:related_request_list' => 'Verwandte Requests',
'Class:Problem/Attribute:related_request_list+' => 'All the requests that are related to this problem~~',
'Class:Problem/Attribute:related_request_list+' => 'Alle Benutzeranfragen verknüpft mit diesem Problem',
'Class:Problem/Attribute:related_incident_list' => 'Verknüpfte Incidents',
'Class:Problem/Attribute:related_incident_list+' => 'Alle Incidents, die mit diesem Problem verknüpft sind',
'Class:Problem/Attribute:related_incident_list+' => 'Alle Incidents verknüpft mit diesem Problem',
'Class:Problem/Stimulus:ev_assign' => 'Zuweisen',
'Class:Problem/Stimulus:ev_assign+' => '',
'Class:Problem/Stimulus:ev_reassign' => 'Neu zuweisen',

View File

@@ -103,8 +103,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Problem/Attribute:impact/Value:3+' => '',
'Class:Problem/Attribute:urgency' => '紧急度',
'Class:Problem/Attribute:urgency+' => '',
'Class:Problem/Attribute:urgency/Value:1' => '非常高',
'Class:Problem/Attribute:urgency/Value:1+' => '非常高',
'Class:Problem/Attribute:urgency/Value:1' => '紧急',
'Class:Problem/Attribute:urgency/Value:1+' => '紧急',
'Class:Problem/Attribute:urgency/Value:2' => '高',
'Class:Problem/Attribute:urgency/Value:2+' => '高',
'Class:Problem/Attribute:urgency/Value:3' => '中',
@@ -113,8 +113,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:Problem/Attribute:urgency/Value:4+' => '低',
'Class:Problem/Attribute:priority' => '优先级',
'Class:Problem/Attribute:priority+' => '',
'Class:Problem/Attribute:priority/Value:1' => '非常高',
'Class:Problem/Attribute:priority/Value:1+' => '非常高',
'Class:Problem/Attribute:priority/Value:1' => '紧急',
'Class:Problem/Attribute:priority/Value:1+' => '紧急',
'Class:Problem/Attribute:priority/Value:2' => '高',
'Class:Problem/Attribute:priority/Value:2+' => '高',
'Class:Problem/Attribute:priority/Value:3' => '中',

View File

@@ -125,6 +125,7 @@
<group id="Audit" _delta="define">
<classes>
<!-- This class list is also present in AdminTools group -->
<class id="AuditDomain"/>
<class id="AuditCategory"/>
<class id="AuditRule"/>
<class id="ResourceRunQueriesMenu"/>
@@ -166,6 +167,7 @@
<class id="URP_UserProfile"/>
<class id="URP_Profiles"/>
<!-- Audit group -->
<class id="AuditDomain"/>
<class id="AuditCategory"/>
<class id="AuditRule"/>
<!-- Query group -->

View File

@@ -519,8 +519,6 @@
<edit_mode>add_remove</edit_mode>
<count_min>0</count_min>
<count_max>0</count_max>
<relation_type>link</relation_type>
<read_only>false</read_only>
</field>
<field id="public_log" xsi:type="AttributeCaseLog">
<sql>public_log</sql>

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