Compare commits

..

138 Commits

Author SHA1 Message Date
Eric Espie
d2434c64d4 Doc for iTop 3.1 2022-09-19 13:59:37 +02:00
Eric Espie
3bfd3560a6 Merge branch 'develop' into feature/faf_doc_twig_blocks 2022-09-19 11:37:00 +02:00
Eric Espie
ae98a86e9b Dynamic year in copyright 2022-03-11 10:43:28 +01:00
Eric Espie
428b57e270 Moved from recommonmark to MyST 2022-03-10 13:40:21 +01:00
Eric Espie
2fe05a3947 correct directory for UI documentation 2022-03-10 13:23:40 +01:00
Eric Espie
99b4aa65ff link to GitHub 2022-03-10 13:19:38 +01:00
Eric Espie
dc1476359c Changed documentation build target 2022-03-10 13:16:50 +01:00
Eric Espie
703f3b0b6b Changed documentation build target 2022-03-10 13:14:15 +01:00
Eric Espie
bc6d7ccf19 Changed documentation build target 2022-03-10 13:13:40 +01:00
Eric Espie
fb5704e470 example 2022-03-10 10:26:00 +01:00
Eric Espie
354a15e8dc example 2022-03-10 10:19:55 +01:00
Eric Espie
f0d28bf1b6 example 2022-03-10 10:10:56 +01:00
Eric Espie
727414f165 reworked documentation 2022-03-10 08:43:34 +01:00
Eric Espie
f9560005f4 cleanup for linux 2022-03-10 08:34:31 +01:00
Eric Espie
c7fc7ed2b9 Added support for multi-versions 2022-03-08 17:17:42 +01:00
Eric Espie
d9fbfcc26a Added suport for multi-versions 2022-03-08 17:12:32 +01:00
Eric Espie
634650ff37 * Changed version
* Removed sources
2022-03-08 15:40:01 +01:00
Eric Espie
d357b3195d Changed version 2022-03-08 15:28:30 +01:00
Eric Espie
eae33807e1 Merge branch 'develop' into feature/faf_doc_twig_blocks 2022-03-08 15:07:48 +01:00
Eric Espie
63c8558523 Update description 2021-10-20 14:10:30 +02:00
Eric Espie
9775b70703 tutorial enhancements 2021-10-08 16:44:38 +02:00
Eric Espie
c4ef26f92a presentation and tutorial enhancements 2021-10-08 16:34:26 +02:00
Eric Espie
43150860c4 Merge branch 'develop' into feature/faf_doc_twig_blocks 2021-10-08 15:37:35 +02:00
Eric Espie
5f309350df Doc update 2021-09-28 17:39:51 +02:00
Eric Espie
6e9c6eeb23 Doc update 2021-09-28 17:35:33 +02:00
bruno-ds
c02f3202d9 update for linux 2021-09-28 16:29:12 +02:00
Eric Espie
513b671c4e Merge branch 'develop' into feature/faf_doc_twig_blocks 2021-09-28 14:26:12 +02:00
Eric
4a837fff64 Button doc updated 2021-07-23 10:22:09 +02:00
Eric
d3529f7443 Merge branch 'develop' into feature/faf_doc_twig_blocks 2021-07-20 17:57:42 +02:00
Eric
5fa85eb05a FAF: Documentation UI Twig Blocks 2021-06-18 18:00:14 +02:00
Eric
8edc7c7ce0 Merge branch 'develop' into feature/faf_doc_twig_blocks
# Conflicts:
#	core/pdfbulkexport.class.inc.php
#	css/backoffice/components/_datatable.scss
#	css/backoffice/components/_field.scss
#	datamodels/2.x/itop-structure/precompiled-themes/fullmoon/main.css
#	datamodels/2.x/itop-structure/precompiled-themes/test-red/main.css
#	dictionaries/de.dictionary.itop.ui.php
#	js/search/search_form_handler.js
#	sources/application/UI/Base/Component/DataTable/DataTableUIBlockFactory.php
#	templates/base/components/datatable/layout.ready.js.twig
#	webservices/export-v2.php
2021-06-18 17:22:04 +02:00
Eric
38dcc29569 FAF: Documentation UI Twig Blocks - HTML result 2021-06-04 12:17:33 +02:00
Eric
5da54f2525 FAF: Documentation UI Twig Blocks - Comments in class variables 2021-06-04 12:14:44 +02:00
Eric
39c1286aa6 ♻️ rework of Select UIBlock with labels 2021-06-04 11:59:26 +02:00
Stephen Abello
f4839ef88f Fix block loader style for datatables 2021-06-04 11:59:26 +02:00
Stephen Abello
df9872cfd8 Fix collapsible section widget being called before dependency was loaded 2021-06-04 11:59:25 +02:00
Molkobain
2cf249f58a Update precompiled themes 2021-06-04 11:59:25 +02:00
Molkobain
57d2e85a7b Fix iTopWebPage::DisableBreadCrumb() not working since 3.0 rework 2021-06-04 11:59:25 +02:00
Molkobain
ccad70e8ee SCSS: Replace font global redefinition with more accurate overloads (only size, only weight, ...) to simplify styles inheritance 2021-06-04 11:59:25 +02:00
Molkobain
674d2a261e Attribute file: Fix delete button not on the same line as the filename 2021-06-04 11:59:25 +02:00
Molkobain
5530c3cef2 SCSS: Add font size variables / helpers 2021-06-04 11:59:25 +02:00
Molkobain
08d7e086a1 SCSS: Fix base font 2021-06-04 11:59:25 +02:00
Molkobain
ddad4717ff SCSS: Add font weight variables / helpers 2021-06-04 11:59:24 +02:00
Stephen Abello
0d35f20bf4 Fix non existing variable usage 2021-06-04 11:59:24 +02:00
Stephen Abello
725bbbeb4f Restyle block loader 2021-06-04 11:59:24 +02:00
Stephen Abello
6108d86a2b Remove trailing quote 2021-06-04 11:59:24 +02:00
Stephen Abello
f0205002bc N°3914 Fix configure this list button alignment and add background color to selected fields 2021-06-04 11:59:24 +02:00
Stephen Abello
4834998179 N°3914 Fix highlighted rows highlighting following rows too 2021-06-04 11:59:24 +02:00
Stephen Abello
595174e38e N°3914 Fix add criteria buttons style 2021-06-04 11:59:24 +02:00
Molkobain
fd49f6b2c4 N°4022 - Fix scroll not working on search menu nodes 2021-06-04 11:59:24 +02:00
Molkobain
e9c168a4d1 N°4022 - Rework search page to improve UX and usable height 2021-06-04 11:59:23 +02:00
Molkobain
e931b5ef9b Update CONTRIBUTING.md with thanks stickers (#213)
* Update CONTRIBUTING.md with thanks stickers

* Update CONTRIBUTING.md

Co-authored-by: Pierre Goiffon <pierre.goiffon@combodo.com>

Co-authored-by: Pierre Goiffon <pierre.goiffon@combodo.com>
2021-06-04 11:59:23 +02:00
Pierre Goiffon
d62f05e7a9 💡 Fix phpdoc for \MenuBlock::GetEnumAllowedActions 2021-06-04 11:59:23 +02:00
Stephen Abello
56494bc97f N°4049 Remove dashlet list free will 👾 2021-06-04 11:59:23 +02:00
Stephen Abello
497d77d89c N°4048 Correctly set default sorting on lists 2021-06-04 11:59:23 +02:00
Molkobain
0659639b53 Fix regression introduced by c6b8526d: FormTable not working in edition 2021-06-04 11:59:23 +02:00
Stephen Abello
67332837ad N°3927 Fix Attachments delete button 2021-06-04 11:59:23 +02:00
Pierre Goiffon
0957b55883 N°4047 skip test generating a PHP notice
Will be fixed later
2021-06-04 11:59:22 +02:00
Stephen Abello
232b91bbfe N°3932 Fix button style for hierarchical key selector 2021-06-04 11:59:22 +02:00
Stephen Abello
4362ef7a2d N°3914 Fix search from external key widget 2021-06-04 11:59:22 +02:00
Molkobain
1eae9ff876 Update precompiled themes 2021-06-04 11:59:22 +02:00
Molkobain
4b69a52a64 Fix regression in AJAX calls introduced by c6b8526d 2021-06-04 11:59:21 +02:00
Molkobain
31e72d5631 Switch page class to non deprecated 2021-06-04 11:59:21 +02:00
Molkobain
7a79293cb4 N°4021 - Fix header jumping out of sticky positioning when getting near some tabs
Reason: DataTables' dynamic height cannot work we a static "duration" (height) based on the initial panel's height
2021-06-04 11:59:21 +02:00
Molkobain
a490efe7fa N°4021 - Add support for tab container for the sticky header 2021-06-04 11:59:21 +02:00
Molkobain
15c92440fb PHPDoc 2021-06-04 11:59:21 +02:00
Molkobain
7d8710770a UIBlock: Add external JS/CSS files (optional) inheritance
This way we ensure that a block always have the external resources from its ancestors as this will be necessary most of the time. From now on, the JS widget of the blocks will inherit from a common ancestor to factorize some mechanisms that are duplicates at many levels.
This can be disabled in a particular block by overloading the INCLUDE_ANCESTORS_DEFAULT_XXX_FILES constants in which case, only the external files of the block itself will be included.
2021-06-04 11:59:21 +02:00
Molkobain
344890f84e JsonPage: Add option to output only the data, typically when feeding a third party lib that doesn't understand our structuration 2021-06-04 11:59:21 +02:00
Molkobain
27c87236cf Panel: Fix scrollable tabs with sticky header 2021-06-04 11:59:21 +02:00
Molkobain
4b0a3a001c N°4021 - Change approach for sticky header, use the ScrollMagic lib as in the scrolling tabs to use the same abstraction level everywhere 2021-06-04 11:59:20 +02:00
Molkobain
c00987d1e9 SCSS: Add 2 helpers classes to make elements transparent or opaque 2021-06-04 11:59:20 +02:00
Molkobain
bf37bfbd2d SCSS: Improve container space occupation 2021-06-04 11:59:20 +02:00
Molkobain
deb3dcbb73 SCSS: Improve panel space occupation by removing unnecessary margins 2021-06-04 11:59:20 +02:00
Eric
6e001141a8 FAF: Documentation UI Twig Blocks - support @see in comments 2021-06-01 09:01:56 +02:00
Eric
2f0ad03070 FAF: Documentation UI Twig Blocks 2021-05-31 14:52:42 +02:00
Eric
94fbb91ad2 FAF: Documentation UI Twig Blocks (get @see comments) 2021-05-31 13:42:30 +02:00
Eric
9a9856fb0d FAF: Documentation UI Twig Blocks 2021-05-31 11:55:50 +02:00
Eric
c22f7e07e0 FAF: Documentation UI Twig Blocks 2021-05-31 10:33:20 +02:00
Eric
9c89687ed4 FAF: Documentation UI Twig Blocks 2021-05-31 09:09:50 +02:00
Eric
7a82ac5580 FAF: Documentation UI Twig Blocks 2021-05-31 08:52:21 +02:00
Eric
96bf56b51c FAF: Documentation UI Twig Blocks 2021-05-30 11:45:13 +02:00
Eric
862e49ba4e FAF: Documentation UI Twig Blocks 2021-05-29 11:46:15 +02:00
Eric
b87afed08a FAF: Documentation UI Twig Blocks 2021-05-28 22:46:30 +02:00
Eric
541231ee5e FAF: Documentation UI Twig Blocks 2021-05-28 18:08:15 +02:00
Eric
185b927a9c PHP doc 2021-05-28 18:06:26 +02:00
Thomas Casteleyn
607038dbc6 🌐 Update Dutch dictionaries for 3.0 (#199)
* Update UI components

* Global cleanup

* Update UI layouts

* Update UI pages

* Update core dictionaries

* Minor change

* Fix newline

* Conform with English text

* Applied changes suggested by @jbostoen

* Changed to capital as in original English value
2021-05-28 17:35:16 +02:00
Stephen Abello
94d05c0b71 N°3914 Fix tagset taking too much space in lists 2021-05-28 17:35:15 +02:00
Stephen Abello
c173535104 N°3914 Fix portal tables getting backoffice markup for enum attributes 2021-05-28 17:35:15 +02:00
Stephen Abello
b74b43727d N°3914 Fix class friendlyname in lists using class aliases 2021-05-28 17:35:15 +02:00
Stephen Abello
9cf776e7a4 N°3914 Correctly remove entries from linksets' datatable 2021-05-28 17:35:15 +02:00
Stephen Abello
d006131dba N°3914 Display label on "Add criterion" button when there's no criterion. Add tooltips to "Add criterion" and "Refresh" button 2021-05-28 17:35:15 +02:00
Eric
c0e1f9dcc0 N°2214 Add PHP check in CLI scripts (fix some checks and title) 2021-05-28 17:35:15 +02:00
Stephen Abello
da7d3731dc N°3914 Add row highlight colors to Datatables block when an object has a triggered tto/ttr 2021-05-28 17:35:15 +02:00
Stephen Abello
8fb2faa53f N°3914 Harmonize linkset display 2021-05-28 17:35:15 +02:00
Stephen Abello
eb08d679e1 N°3914 Hide lists pagination when there's only 1 page 2021-05-28 17:35:14 +02:00
Stephen Abello
b280b28450 N°3914 Fix lists header and data being misaligned when resizing them 2021-05-28 17:35:14 +02:00
Molkobain
fe8e71fb40 SCSS: Fix field badge display being in 2 lines 2021-05-28 17:35:14 +02:00
Molkobain
5c2f479977 Update precompiled themes 2021-05-28 17:35:14 +02:00
Molkobain
0c045b6a62 SCSS: Add fallback fonts to minimize visual glitch while Raleway is not loaded 2021-05-28 17:35:14 +02:00
Molkobain
6aad57f4b6 SCSS: Fix large field not taking whole width 2021-05-28 17:35:13 +02:00
Stephen Abello
11afccb012 N°3923 Cleanup css files 2021-05-28 17:35:13 +02:00
Stephen Abello
9c476d8609 N°3923 Fix up, down, enter key usage in ext key widget 2021-05-28 17:35:13 +02:00
Stephen Abello
86510502a4 N°3923 Hide caret in autocomplete ext key input 2021-05-28 17:35:13 +02:00
Stephen Abello
d493def6d7 N°3923 Vertical align ext key action buttons 2021-05-28 17:35:13 +02:00
Molkobain
324fe50a86 Update precompiled themes 2021-05-28 17:35:13 +02:00
Molkobain
48c6ff8bb6 Code cleanup
- "v-resizable" class is not used anymore in the UI
- Logoff menu is now handled in a dedicated block
- Caselog headers are now handled in a dedicated block
2021-05-28 17:35:12 +02:00
Molkobain
d77b10978e Code cleanup: Remove unused methods from early implementation 2021-05-28 17:35:12 +02:00
Molkobain
3eec045b67 N°4021 - Introduce sticky header for panels and object details (tab container to be done) 2021-05-28 17:35:12 +02:00
Molkobain
3b20dfcae5 SCSS: Fix base content layout not behaving the same way as the one with side content 2021-05-28 17:35:12 +02:00
Molkobain
4379e49f3b SCSS: Fix import ordering of the custom root folders 2021-05-28 17:35:12 +02:00
Molkobain
dd26b40f12 SCSS: Add more variables for jQuery UI 2021-05-28 17:35:12 +02:00
Molkobain
59b439ead0 Code format 2021-05-28 17:35:12 +02:00
Stephen Abello
471ec86c82 N°3923 Fix date picker widget not initialized in ajax forms 2021-05-28 17:35:12 +02:00
Stephen Abello
2a71a3f153 N°3914 Fix configure this list "sort fields" feature 2021-05-28 17:35:11 +02:00
Stephen Abello
4e82e9a580 N°3914 Fix modal backdrop on lists' "configure this list" modal 2021-05-28 17:35:11 +02:00
Molkobain
5a4cb9a133 List: Remove vertical scrolling for all lists except dashlets 2021-05-28 17:35:11 +02:00
Molkobain
3384ed23bc Fix modal title displaying behind closing "X" on long titles 2021-05-28 17:35:11 +02:00
Molkobain
3c20a417ad Code format 2021-05-28 17:35:11 +02:00
Molkobain
8df9afdce2 List: Fix height / scroll for linkedsets add items modal 2021-05-28 17:35:11 +02:00
Pierre Goiffon
27cdabe383 📝 CONTRIBUTING : add "allow edits from maintainers" PR option 2021-05-28 17:35:10 +02:00
Molkobain
f46cf9ed2c Update precompiled themes 2021-05-28 17:35:10 +02:00
Molkobain
4cf141b433 Field: Rework on the SCSS file
- Fix button being too large on AttributeImage
- Reorganize the classes a bit
2021-05-28 17:35:10 +02:00
Molkobain
75aeb4245b Remove index variable from foreach as it was misleading ($sClass does not contain classes but a numeric index) 2021-05-28 17:35:10 +02:00
Molkobain
e9d4ecc85c N°3171 - Rollback on the AttributeExternalKey::GetPrerequisites() as it was introducing more regressions than fixes (acf0548c) 2021-05-28 17:35:10 +02:00
Stephen Abello
cd9c637244 N°3914 Harmonize advanced search's external key search buttons style and positions on modals and fix add button id 2021-05-28 17:35:10 +02:00
Stephen Abello
f079a9bebb N°3914 Harmonize external key / linksets buttons style and positions on modals 2021-05-28 17:35:09 +02:00
Stephen Abello
4f05ac25f5 Fix indirect links block height 2021-05-28 17:35:09 +02:00
Molkobain
560b104d64 N°1964 - Add informative message on dashboard when its container (eg. an object) is currently in edition 2021-05-28 17:35:09 +02:00
Molkobain
23b67f9fd7 Fix text decoration icon size being too big 2021-05-28 17:35:09 +02:00
Pierre Goiffon
1fbb94e265 Protect \iApplicationUIExtension::EnumAllowedActions uses (#214)
Some impl just return null while we expect to have an array... This is causing PHP notices in lots of iTop instances with modules implementing this method incorrectly !

This modification get rid of the notice and : 
* add a log (warning level) indicating the impl classes
* if dev env, then throw an exception after browsing all impl (so you get a complete invalid impl list)

Note : since iTop 2.7.0 you should use \AbstractApplicationUIExtension instead of implementing the whole interface !
2021-05-28 17:35:09 +02:00
Molkobain
8b591a5c0a N°3956 - Fix AJAX error when creating an object which has a linkedset with a friendlyname composed of its own external keys' friendlynames 🤪 2021-05-28 17:35:09 +02:00
Eric
33bd83d680 FAF: Documentation UI Twig Blocks 2021-05-28 17:28:12 +02:00
Eric
f90799d046 FAF: Documentation UI Twig Blocks 2021-05-28 07:53:08 +02:00
Eric
6191719f50 FAF: Documentation UI Twig Blocks 2021-05-25 18:19:47 +02:00
Eric
d3580dd2c7 FAF: Documentation UI Twig Blocks 2021-05-18 18:06:50 +02:00
Eric
e246e79eeb FAF: Documentation UI Twig Blocks 2021-05-18 17:53:05 +02:00
Eric
9405eae922 FAF: Documentation UI Twig Blocks 2021-05-18 16:42:21 +02:00
Eric
05e15bd9c0 FAF: Documentation UI Twig Blocks 2021-05-18 16:32:59 +02:00
756 changed files with 25843 additions and 70847 deletions

View File

@@ -27,7 +27,6 @@ A UI component is a unitary block used to display information in iTop console.
Input/Select/SelectOption
Panel/Panel
Spinner/Spinner
Template/Template
Title/Title
Toolbar/Toolbar
Toolbar/ToolbarSpacer/ToolbarSpacer

View File

@@ -29,21 +29,19 @@ Twig Tag
:Type:
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ForResult <DataTableForResult>` | @param \WebPage $oPage |
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ForObject <DataTableForObject>` | @param \WebPage $oPage |
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ActionRowToolbarTemplate <DataTableActionRowToolbarTemplate>` | Make a row actions toolbar template. |
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ForRendering <DataTableForRendering>` | Make a basis Panel component |
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ForRenderingObject <DataTableForRenderingObject>` | @param string $sListId |
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ForStaticData <DataTableForStaticData>` | @param string $sTitle |
+---------------------------------------------------------------------+--------------------------------------+
| :ref:`ForForm <DataTableForForm>` | @param string $sRef |
+---------------------------------------------------------------------+--------------------------------------+
+---------------------------------------------------------+------------------------------+
| :ref:`ForResult <DataTableForResult>` | @param \WebPage $oPage |
+---------------------------------------------------------+------------------------------+
| :ref:`ForObject <DataTableForObject>` | @param \WebPage $oPage |
+---------------------------------------------------------+------------------------------+
| :ref:`ForRendering <DataTableForRendering>` | Make a basis Panel component |
+---------------------------------------------------------+------------------------------+
| :ref:`ForRenderingObject <DataTableForRenderingObject>` | @param string $sListId |
+---------------------------------------------------------+------------------------------+
| :ref:`ForStaticData <DataTableForStaticData>` | @param string $sTitle |
+---------------------------------------------------------+------------------------------+
| :ref:`ForForm <DataTableForForm>` | @param string $sRef |
+---------------------------------------------------------+------------------------------+
.. _DataTableForResult:
@@ -95,25 +93,6 @@ DataTable ForObject
| aExtraParams | | optional | array () | |
+--------------+-------------+-----------+----------+--+
.. _DataTableActionRowToolbarTemplate:
DataTable ActionRowToolbarTemplate
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:syntax:
.. code-block:: twig
{% UIDataTable ActionRowToolbarTemplate {oTable:value} %}
Content Goes Here
{% EndUIDataTable %}
:parameters:
+--------+----------+-----------+--+-----------------------------------------------------------+
| oTable | iUIBlock | mandatory | | datatable object that needs to use tTableRowActions trait |
+--------+----------+-----------+--+-----------------------------------------------------------+
.. _DataTableForRendering:
DataTable ForRendering
@@ -169,29 +148,27 @@ DataTable ForStaticData
.. code-block:: twig
{% UIDataTable ForStaticData {sTitle:'value', aColumns:{name:value, name:value}, aData:{name:value, name:value}, sId:'value', aExtraParams:{name:value, name:value}, sFilter:'value', aOptions:{name:value, name:value}, aRowActions:{name:value, name:value}} %}
{% UIDataTable ForStaticData {sTitle:'value', aColumns:{name:value, name:value}, aData:{name:value, name:value}, sId:'value', aExtraParams:{name:value, name:value}, sFilter:'value', aOptions:{name:value, name:value}} %}
Content Goes Here
{% EndUIDataTable %}
:parameters:
+--------------+--------+-----------+----------+--------------+
| sTitle | string | mandatory | | |
+--------------+--------+-----------+----------+--------------+
| aColumns | array | mandatory | | |
+--------------+--------+-----------+----------+--------------+
| aData | array | mandatory | | |
+--------------+--------+-----------+----------+--------------+
| sId | string | optional | NULL | |
+--------------+--------+-----------+----------+--------------+
| aExtraParams | array | optional | array () | |
+--------------+--------+-----------+----------+--------------+
| sFilter | string | optional | '' | |
+--------------+--------+-----------+----------+--------------+
| aOptions | array | optional | array () | |
+--------------+--------+-----------+----------+--------------+
| aRowActions | array | optional | NULL | @since 3.1.0 |
+--------------+--------+-----------+----------+--------------+
+--------------+--------+-----------+----------+--+
| sTitle | string | mandatory | | |
+--------------+--------+-----------+----------+--+
| aColumns | array | mandatory | | |
+--------------+--------+-----------+----------+--+
| aData | array | mandatory | | |
+--------------+--------+-----------+----------+--+
| sId | string | optional | NULL | |
+--------------+--------+-----------+----------+--+
| aExtraParams | array | optional | array () | |
+--------------+--------+-----------+----------+--+
| sFilter | string | optional | '' | |
+--------------+--------+-----------+----------+--+
| aOptions | array | optional | array () | |
+--------------+--------+-----------+----------+--+
.. _DataTableForForm:
@@ -202,23 +179,21 @@ DataTable ForForm
.. code-block:: twig
{% UIDataTable ForForm {sRef:'value', aColumns:{name:value, name:value}, aData:{name:value, name:value}, sFilter:'value', aRowActions:{name:value, name:value}} %}
{% UIDataTable ForForm {sRef:'value', aColumns:{name:value, name:value}, aData:{name:value, name:value}, sFilter:'value'} %}
Content Goes Here
{% EndUIDataTable %}
:parameters:
+-------------+--------+-----------+----------+--------------+
| sRef | string | mandatory | | |
+-------------+--------+-----------+----------+--------------+
| aColumns | array | mandatory | | |
+-------------+--------+-----------+----------+--------------+
| aData | array | optional | array () | |
+-------------+--------+-----------+----------+--------------+
| sFilter | string | optional | '' | |
+-------------+--------+-----------+----------+--------------+
| aRowActions | array | optional | NULL | @since 3.1.0 |
+-------------+--------+-----------+----------+--------------+
+----------+--------+-----------+----------+--+
| sRef | string | mandatory | | |
+----------+--------+-----------+----------+--+
| aColumns | array | mandatory | | |
+----------+--------+-----------+----------+--+
| aData | array | optional | array () | |
+----------+--------+-----------+----------+--+
| sFilter | string | optional | '' | |
+----------+--------+-----------+----------+--+
DataTable common parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -266,8 +241,6 @@ DataTable common parameters
+-----------------------------+----------+------------------------------------------------------------+
| ResultColumns | | |
+-----------------------------+----------+------------------------------------------------------------+
| RowActions | array | |
+-----------------------------+----------+------------------------------------------------------------+
| SubBlocks | array | |
+-----------------------------+----------+------------------------------------------------------------+

View File

@@ -1,92 +0,0 @@
.. Copyright (C) 2010-2022 Combodo SARL
.. http://opensource.org/licenses/AGPL-3.0
.. _Template:
Template
========
Class Template
----
.. include:: /manual/Component/Template/TemplateAdditionalDescription.rst
----
Twig Tag
--------
:Tag: **UITemplate**
:Syntax:
.. code-block:: twig
{% UITemplate Type {Parameters} %}
Content Goes Here
{% EndUITemplate %}
:Type:
+------------------------------------+---------------------------+
| :ref:`Standard <TemplateStandard>` | Make a Template component |
+------------------------------------+---------------------------+
.. _TemplateStandard:
Template Standard
^^^^^^^^^^^^^^^^^
:syntax:
.. code-block:: twig
{% UITemplate Standard {sId:'value'} %}
Content Goes Here
{% EndUITemplate %}
:parameters:
+-----+--------+-----------+--+--+
| sId | string | mandatory | | |
+-----+--------+-----------+--+--+
Template common parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^
+-----------------------------+----------+------------------------------------------------------------+
| AddCSSClass | string | CSS class to add to the generated html block |
+-----------------------------+----------+------------------------------------------------------------+
| AddCSSClasses | array | like <code>['ibo-is-hidden', 'ibo-alert--body']</code> |
+-----------------------------+----------+------------------------------------------------------------+
| AddCssFileRelPath | string | |
+-----------------------------+----------+------------------------------------------------------------+
| AddDeferredBlock | iUIBlock | |
+-----------------------------+----------+------------------------------------------------------------+
| AddHtml | string | |
+-----------------------------+----------+------------------------------------------------------------+
| AddJsFileRelPath | string | |
+-----------------------------+----------+------------------------------------------------------------+
| AddMultipleCssFilesRelPaths | array | |
+-----------------------------+----------+------------------------------------------------------------+
| AddMultipleJsFilesRelPaths | array | |
+-----------------------------+----------+------------------------------------------------------------+
| AddSubBlock | iUIBlock | |
+-----------------------------+----------+------------------------------------------------------------+
| CSSClasses | array | like <code>['ibo-is-hidden', 'ibo-alert--body']</code> |
+-----------------------------+----------+------------------------------------------------------------+
| DataAttributes | array | Array of data attributes in the format ['name' => 'value'] |
+-----------------------------+----------+------------------------------------------------------------+
| DeferredBlocks | array | |
+-----------------------------+----------+------------------------------------------------------------+
| HasForcedDiv | bool | |
+-----------------------------+----------+------------------------------------------------------------+
| IsHidden | bool | |
+-----------------------------+----------+------------------------------------------------------------+
| SubBlocks | array | |
+-----------------------------+----------+------------------------------------------------------------+
----
.. include:: /manual/Component/Template/TemplateFooter.rst

View File

@@ -1,12 +0,0 @@
.. Copyright (C) 2010-2022 Combodo SARL
.. http://opensource.org/licenses/AGPL-3.0
Output
------
No output provided yet
.. example of image
.. image:: /manual/Component/Template/Template.png

View File

@@ -1,11 +0,0 @@
.. Copyright (C) 2010-2022 Combodo SARL
.. http://opensource.org/licenses/AGPL-3.0
Examples
--------
No examples provided yet
.. example of image
.. image:: /manual/Component/Template/Template.png

1
.gitignore vendored
View File

@@ -146,3 +146,4 @@ local.properties
.cache-main
.scala_dependencies
.worksheet
/.doc/UI/build/doctrees/

View File

@@ -10,8 +10,7 @@
* Usage :
* `php .make\release\update-xml.php "1.7"`
*
* @since 2.7.0 simple version change using regexp (not doing conversion)
* @since 3.1.0 N°5405 now does a real conversion
* @since 2.7.0
******************************************************************************/

View File

@@ -174,21 +174,10 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater
*/
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
{
require_once APPROOT.'setup/itopdesignformat.class.inc.php';
$oFileXml = new DOMDocument();
/** @noinspection PhpComposerExtensionStubsInspection */
libxml_clear_errors();
$oFileXml->formatOutput = true;
$oFileXml->preserveWhiteSpace = false;
$oFileXml->loadXML($sFileContent);
$oFileItopFormat = new iTopDesignFormat($oFileXml);
$bConversionResult = $oFileItopFormat->Convert($sVersionLabel);
if (false === $bConversionResult) {
throw new Exception("Error when converting $sFileFullPath");
}
return $oFileItopFormat->GetXmlAsString();
return preg_replace(
'/(<itop_design .* version=")[^"]+(">)/',
'${1}'.$sVersionLabel.'${2}',
$sFileContent
);
}
}

View File

@@ -134,7 +134,7 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
When your code is working, please:
* squash as much as possible your commits,
* stash as much as possible your commits,
* rebase your branch on our repo last commit,
* create a pull request
* mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option !

View File

@@ -376,19 +376,26 @@ class ApplicationContext
{
$oAppContext = new ApplicationContext();
if (is_null($sUrlMakerClass)) {
$sUrlMakerClass = self::GetUrlMakerClass();
}
if (is_null($sUrlMakerClass))
{
$sUrlMakerClass = self::GetUrlMakerClass();
}
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
if (utils::StrLen($sUrl) > 0) {
if ($bWithNavigationContext) {
return $sUrl."&".$oAppContext->GetForLink();
} else {
return $sUrl;
}
} else {
return '';
}
if (strlen($sUrl) > 0)
{
if ($bWithNavigationContext)
{
return $sUrl."&".$oAppContext->GetForLink();
}
else
{
return $sUrl;
}
}
else
{
return '';
}
}
/**

View File

@@ -1,29 +0,0 @@
<?php
/*
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Service\EventService;
use Combodo\iTop\Service\iEventEnrolment;
class ApplicationEvents implements iEventEnrolment
{
// Startup events
const APPLICATION_EVENT_REQUEST_RECEIVED = 'APPLICATION_EVENT_REQUEST_RECEIVED';
const APPLICATION_EVENT_METAMODEL_STARTED = 'APPLICATION_EVENT_METAMODEL_STARTED';
/**
* @inheritDoc
*/
public function InitEvents()
{
EventService::RegisterEvent(self::APPLICATION_EVENT_REQUEST_RECEIVED, [
'description' => 'A request was received from the network, at this point only the session is started, the configuration is not even loaded',
], 'application');
EventService::RegisterEvent(self::APPLICATION_EVENT_METAMODEL_STARTED, [
'description' => 'The MetaModel is fully started',
], 'application');
}
}

View File

@@ -299,7 +299,6 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension
*
* @api
* @package Extensibility
* @deprecated
*/
interface iApplicationUIExtension
{
@@ -442,7 +441,6 @@ interface iApplicationUIExtension
* @api
* @package Extensibility
* @since 2.7.0
* @deprecated
*/
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
{
@@ -2094,4 +2092,4 @@ class RestUtils
interface iModuleExtension
{
public function __construct();
}
}

View File

@@ -1,6 +1,6 @@
<?php
/*
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
@@ -39,12 +39,9 @@ use Combodo\iTop\Application\UI\Base\Layout\Object\ObjectFactory;
use Combodo\iTop\Application\UI\Base\Layout\TabContainer\Tab\AjaxTab;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksViewTable;
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinksViewTable;
use Combodo\iTop\Renderer\BlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
define('OBJECT_PROPERTIES_TAB', 'ObjectProperties');
define('HILIGHT_CLASS_CRITICAL', 'red');
@@ -652,7 +649,8 @@ HTML
}
// Display mode
if (!$oAttDef->IsLinkset()) {
if (!$oAttDef->IsLinkset())
{
continue;
} // Process only linkset attributes...
@@ -663,9 +661,12 @@ HTML
$oLinkSet = $oOrmLinkSet->ToDBObjectSet(utils::ShowObsoleteData());
$iCount = $oLinkSet->Count();
if ($this->IsNew()) {
if ($this->IsNew())
{
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
} else {
}
else
{
$iFlags = $this->GetAttributeFlags($sAttCode);
}
// Adjust the flags according to user rights
@@ -710,20 +711,103 @@ HTML
$aArgs = array('this' => $this);
$bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE));
if ($bEditMode && (!$bReadOnly)) {
if ($bEditMode && (!$bReadOnly))
{
$sInputId = $this->m_iFormId.'_'.$sAttCode;
if ($oAttDef->IsIndirect())
{
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
$sTargetClass = $oLinkingAttDef->GetTargetClass();
}
else
{
$sTargetClass = $sLinkedClass;
}
$oClassIcon = new MedallionIcon(MetaModel::GetClassIcon($sTargetClass, false));
$oClassIcon->SetDescription($oAttDef->GetDescription())->AddCSSClass('ibo-block-list--medallion');
$oPage->AddUiBlock($oClassIcon);
$sDisplayValue = ''; // not used
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode,
$oAttDef, $oLinkSet, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
$this->AddToFieldsMap($sAttCode, $sInputId);
$oPage->add($sHTMLValue);
} else {
if ($oAttDef->IsIndirect()) {
$oBlockLinkViewTable = new BlockIndirectLinksViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
} else {
$oBlockLinkViewTable = new BlockDirectLinksViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
}
else
{
// Display mode
if (!$oAttDef->IsIndirect())
{
// 1:n links
$sTargetClass = $sLinkedClass;
$aDefaults = array($oAttDef->GetExtKeyToMe() => $this->GetKey());
$oAppContext = new ApplicationContext();
foreach($oAppContext->GetNames() as $sKey)
{
// The linked object inherits the parent's value for the context
if (MetaModel::IsValidAttCode($sClass, $sKey))
{
$aDefaults[$sKey] = $this->Get($sKey);
}
}
$aParams = array(
'target_attr' => $oAttDef->GetExtKeyToMe(),
'object_id' => $this->GetKey(),
'menu' => MetaModel::GetConfig()->Get('allow_menu_on_linkset'),
//'menu_actions_target' => '_blank',
'default' => $aDefaults,
'table_id' => $sClass.'_'.$sAttCode,
);
}
$oPage->AddUiBlock($oBlockLinkViewTable);
else {
// n:n links
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
$sLinkingAttCode = $oLinkingAttDef->GetCode();
$sTargetClass = $oLinkingAttDef->GetTargetClass();
// N°2334 fields to display for n:n relations
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($sTargetClass);
$aLnkAttCodesToDisplay = array_map(function ($oLnkAttDef) {
return ormLinkSet::LINK_ALIAS.'.'.$oLnkAttDef->GetCode();
},
$aLnkAttDefsToDisplay
);
if (!in_array(ormLinkSet::LINK_ALIAS.'.'.$sLinkingAttCode, $aLnkAttCodesToDisplay)) {
// we need to display a link to the remote class instance !
$aLnkAttCodesToDisplay[] = ormLinkSet::LINK_ALIAS.'.'.$sLinkingAttCode;
}
$aRemoteAttCodesToDisplay = array_map(function ($oRemoteAttDef) {
return ormLinkSet::REMOTE_ALIAS.'.'.$oRemoteAttDef->GetCode();
},
$aRemoteAttDefsToDisplay
);
$aAttCodesToDisplay = array_merge($aLnkAttCodesToDisplay, $aRemoteAttCodesToDisplay);
$sAttCodesToDisplay = implode(',', $aAttCodesToDisplay);
$aParams = array(
'link_attr' => $oAttDef->GetExtKeyToMe(),
'object_id' => $this->GetKey(),
'target_attr' => $oAttDef->GetExtKeyToRemote(),
'view_link' => false,
'menu' => false,
//'menu_actions_target' => '_blank',
// By default limit the list to speed up the initial load & display
'display_limit' => true,
'table_id' => $sClass.'_'.$sAttCode,
// N°2334 specify fields to display for n:n relations
'zlist' => false,
'extra_fields' => $sAttCodesToDisplay,
);
}
$oClassIcon = new MedallionIcon(MetaModel::GetClassIcon($sTargetClass, false));
$oClassIcon->SetDescription($oAttDef->GetDescription())->AddCSSClass('ibo-block-list--medallion');
$oPage->AddUiBlock($oClassIcon);
$oBlock = new DisplayBlock($oLinkSet->GetFilter(), 'list', false);
$oBlock->Display($oPage, 'rel_'.$sAttCode, $aParams);
}
if (array_key_exists($sAttCode, $aRedundancySettings)) {
foreach ($aRedundancySettings[$sAttCode] as $oRedundancyAttDef) {
@@ -786,10 +870,6 @@ HTML
}
}
}
// add hidden input for linkset transactions
$oInputHidden = InputUIBlockFactory::MakeForHidden('linkset_transactions_id', utils::GetNewTransactionId(), 'linkset_transactions_id');
$oPage->AddUiBlock($oInputHidden);
}
/**
@@ -2197,7 +2277,7 @@ JS
{$sValidationSpan}{$sReloadSpan}
HTML;
$oPage->add_ready_script(
<<<JS
<<<EOF
$('#$iId').closest('.field_input_text').find('.fullscreen_button').on('click', function(oEvent){
var oOriginField = $('#$iId').closest('.field_input_text');
var oClonedField = oOriginField.clone();
@@ -2210,14 +2290,7 @@ HTML;
oOriginField.find('textarea').triggerHandler('change');
});
});
// Submit host form on "Ctrl + Enter" or "Meta (Cmd) + Enter" keyboard shortcut
$('#$iId').on('keyup', function (oEvent) {
if ((oEvent.ctrlKey || oEvent.metaKey) && oEvent.key === 'Enter') {
$(this).closest('form').trigger('submit');
}
});
JS
EOF
);
break;
@@ -3560,7 +3633,7 @@ HTML;
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
$sDisplayUrl = $oDocument->GetDisplayURL(get_class($this), $this->GetKey(), $sAttCode);
$sDownloadLabel = Dict::S('UI:DownloadDocument_');
$sDownloadLabel = Dict::Format('UI:DownloadDocument_');
$sDownloadUrl = $oDocument->GetDownloadURL(get_class($this), $this->GetKey(), $sAttCode);
$sDisplayValue = <<<HTML
@@ -4406,13 +4479,13 @@ HTML;
// 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(Metamodel::REENTRANCE_TYPE_UPDATE, $this)) {
$sClass = get_class($this);
$sKey = $this->GetKey();
IssueLog::Debug("CRUD: DBUpdate $sClass::$sKey Rejected (reentrance)", LogChannels::DM_CRUD);
static $aUpdateReentrance = array();
$sKey = get_class($this).'::'.$this->GetKey();
if (array_key_exists($sKey, $aUpdateReentrance))
{
return $res;
}
$aUpdateReentrance[$sKey] = true;
try
{
@@ -4423,13 +4496,13 @@ HTML;
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
}
}
catch (Exception $e)
{
throw $e;
}
finally
{
MetaModel::StopReentranceProtection(Metamodel::REENTRANCE_TYPE_UPDATE, $this);
}
if ($this->IsModified()) {
return $this->DBUpdate();
unset($aUpdateReentrance[$sKey]);
}
return $res;
@@ -5635,117 +5708,4 @@ JS
'AttributeOneWayPassword',
);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventInsertRequested()
{
$this->FireEvent(EVENT_SERVICE_DB_INSERT_REQUESTED);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventInsertBefore()
{
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_INSERT);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventInsertAfter()
{
$this->FireEvent(EVENT_SERVICE_DB_INSERT_DONE);
}
final protected function EventComputeValues()
{
$this->FireEvent(EVENT_SERVICE_DB_COMPUTE_VALUES);
}
/**
* @param array $aEventData
*
* @return void
* @throws \CoreException
*/
final protected function EventCheckToWrite(array $aEventData)
{
$this->FireEvent(EVENT_SERVICE_DB_CHECK_TO_WRITE, $aEventData);
}
/**
* @param array $aEventData
*
* @return void
* @throws \CoreException
*/
final protected function EventCheckToDelete(array $aEventData)
{
$this->FireEvent(EVENT_SERVICE_DB_CHECK_TO_DELETE, $aEventData);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventUpdateRequested()
{
$this->FireEvent(EVENT_SERVICE_DB_UPDATE_REQUESTED);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventUpdateBefore()
{
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_UPDATE);
}
/**
* @param array $aEventData
*
* @return void
* @throws \CoreException
*/
final protected function EventUpdateAfter(array $aEventData)
{
$this->FireEvent(EVENT_SERVICE_DB_UPDATE_DONE, $aEventData);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventDeleteBefore()
{
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_DELETE);
}
/**
* @return void
* @throws \CoreException
*/
final protected function EventDeleteAfter()
{
$this->FireEvent(EVENT_SERVICE_DB_DELETE_DONE);
}
final protected function EventArchive()
{
$this->FireEvent(EVENT_SERVICE_DB_ARCHIVE);
}
final protected function EventUnarchive()
{
$this->FireEvent(EVENT_SERVICE_DB_UNARCHIVE);
}
}

View File

@@ -185,384 +185,6 @@
</style>
</menu>
</menus>
<events>
<event id="EVENT_SERVICE_DB_INSERT_REQUESTED" _delta="define">
<description>An object insert in the database has been requested. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnInsert</replaces>
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_INSERT" _delta="define">
<description>An object is about to be inserted in the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnInsert</replaces>
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_INSERT_DONE" _delta="define">
<description>An object has been inserted into the database (but not reloaded). All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterInsert</replaces>
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_UPDATE_REQUESTED" _delta="define">
<description>An object update has been requested. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnUpdate, DBObject::DoComputeValues</replaces>
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_UPDATE" _delta="define">
<description>An object is about to be updated in the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnUpdate</replaces>
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_UPDATE_DONE" _delta="define">
<description>An object has been updated into the database and reloaded. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterUpdate</replaces>
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_DELETE" _delta="define">
<description>An object is about to be deleted in the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object deleted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_DELETE_DONE" _delta="define">
<description>An object has been deleted into the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object deleted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_BEFORE_APPLY_STIMULUS" _delta="define">
<description>A stimulus is about to be applied to an object</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</event_datum>
<event_datum id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_AFTER_APPLY_STIMULUS" _delta="define">
<description>A stimulus has been applied to an object</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</event_datum>
<event_datum id="save_object">
<description>The object is asked to be saved in the database</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_APPLY_STIMULUS_FAILED" _delta="define">
<description>A stimulus has failed</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="action">
<description>The action that failed to apply the stimulus</description>
<type>string</type>
</event_datum>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</event_datum>
<event_datum id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_OBJECT_RELOAD" _delta="define">
<description>An object has been re-loaded from the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object re-loaded</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_COMPUTE_VALUES" _delta="define">
<description>An object needs to be recomputed after changes</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::ComputeValues</replaces>
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_CHECK_TO_WRITE" _delta="define">
<description>Check an object before it is written into the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::DoCheckToWrite</replaces>
<event_data>
<event_datum id="object">
<description>The object to check</description>
<type>DBObject</type>
</event_datum>
<event_datum id="error_messages">
<description>Array of strings where all the errors found during the object checking are added</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_CHECK_TO_DELETE" _delta="define">
<description>Check an object before it is deleted from the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::DoCheckToDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object to check</description>
<type>DBObject</type>
</event_datum>
<event_datum id="error_messages">
<description>Array of strings where all the errors found during the object checking are added</description>
<type>array</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ARCHIVE" _delta="define">
<description>An object has been archived</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object archived</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_UNARCHIVE" _delta="define">
<description>An object has been unarchived</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object unarchived</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DOWNLOAD_DOCUMENT" _delta="define">
<description>A document has been downloaded from the GUI</description>
<sources>
<source id="Document">Document</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object containing the document</description>
<type>DBObject</type>
</event_datum>
<event_datum id="document">
<description>The document downloaded</description>
<type>ormDocument</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_LOGIN" _delta="define">
<description>Inform the listeners about the connection states</description>
<event_data>
<event_datum id="code">
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>
<type>integer</type>
</event_datum>
<event_datum id="state">
<description>Current login state (LoginWebPage::LOGIN_STATE_CONNECTED...)</description>
<type>string</type>
</event_datum>
</event_data>
</event>
</events>
<meta>
<classes>
<class id="cmdbAbstractObject" _delta="define">

View File

@@ -1471,7 +1471,6 @@ JS
} else {
$iListId = $aExtraParams['currentId'];
}
$oBlock = DataTableUIBlockFactory::MakeForRendering($iListId, $oSet, $aExtraParams);
$oHtml->AddHtml("<tr><td>");
$oContentBlock->AddSubBlock($oBlock);
@@ -1839,7 +1838,7 @@ class MenuBlock extends DisplayBlock
if ($bIsModifyAllowed) {
$aRegularActions['UI:Menu:Modify'] = array(
'label' => Dict::S('UI:Menu:Modify'),
'url' => "{$sRootUrl}pages/$sUIPage?route=object.modify&class=$sClass&id=$id{$sContext}#",
'url' => "{$sRootUrl}pages/$sUIPage?operation=modify&class=$sClass&id=$id{$sContext}#",
) + $aActionParams;
}
if ($bIsCreationAllowed) {

View File

@@ -1,10 +0,0 @@
<?php
/*
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
class iTopXmlException extends CoreException
{
}

View File

@@ -1,13 +0,0 @@
<?php
/*
* @copyright Copyright (C) 2010-2021 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* @since 2.7.8 3.0.3 3.1.0 N°5538
*/
class MySQLTransactionNotClosedException extends MySQLException
{
}

View File

@@ -59,7 +59,6 @@ class LoginBasic extends AbstractLoginFSMExtension
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
{
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR;
}

View File

@@ -42,7 +42,6 @@ class LoginExternal extends AbstractLoginFSMExtension
$sAuthUser = $this->GetAuthUser();
if (!UserRights::CheckCredentials($sAuthUser, '', Session::Get('login_mode'), 'external'))
{
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR;
}
@@ -89,4 +88,4 @@ class LoginExternal extends AbstractLoginFSMExtension
/** @var string $sAuthUser */
return $sAuthUser; // Retrieve the value
}
}
}

View File

@@ -68,7 +68,6 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
{
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR;
}

View File

@@ -57,7 +57,6 @@ class LoginURL extends AbstractLoginFSMExtension
$sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data');
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, Session::Get('login_mode'), 'internal'))
{
$_SESSION['auth_user'] = $sAuthUser;
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR;
}
@@ -93,4 +92,4 @@ class LoginURL extends AbstractLoginFSMExtension
}
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
}
}

View File

@@ -26,8 +26,6 @@
use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Service\EventData;
use Combodo\iTop\Service\EventService;
/**
* Web page used for displaying the login form
@@ -481,13 +479,11 @@ class LoginWebPage extends NiceWebPage
$iResponse = $oLoginFSMExtensionInstance->LoginAction($sLoginState, $iErrorCode);
if ($iResponse == self::LOGIN_FSM_RETURN)
{
EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
Session::WriteClose();
return $iErrorCode; // Asked to exit FSM, generally login OK
}
if ($iResponse == self::LOGIN_FSM_ERROR)
{
EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['code' => $iErrorCode, 'state' => $sLoginState]));
$sLoginState = self::LOGIN_STATE_SET_ERROR; // Next state will be error
// An error was detected, skip the other plugins turn
break;
@@ -501,7 +497,6 @@ class LoginWebPage extends NiceWebPage
}
catch (Exception $e)
{
EventService::FireEvent(new EventData(EVENT_SERVICE_LOGIN, null, ['state' => $_SESSION['login_state']]));
IssueLog::Error($e->getTraceAsString());
static::ResetSession();
die($e->getMessage());

View File

@@ -156,7 +156,6 @@ abstract class Query extends cmdbAbstractObject
// last export information
$this->Set('export_last_date', date(AttributeDateTime::GetSQLFormat()));
$this->Set('export_last_user_id', UserRights::GetUserObject());
$this->AllowWrite(true);
$this->DBUpdate();
// increment usage counter

View File

@@ -16,14 +16,11 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Service\EventData;
use Combodo\iTop\Service\EventService;
require_once(APPROOT.'core/cmdbobject.class.inc.php');
require_once(APPROOT.'application/utils.inc.php');
require_once(APPROOT.'core/contexttag.class.inc.php');
require_once(APPROOT.'core/kpi.class.inc.php');
require_once(APPROOT.'setup/setuputils.class.inc.php');
require_once(APPROOT.'/core/cmdbobject.class.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/core/contexttag.class.inc.php');
require_once(APPROOT.'/core/kpi.class.inc.php');
/**
@@ -71,9 +68,6 @@ $oKPI = new ExecutionKPI();
Session::Start();
$oKPI->ComputeAndReport("Session Start");
EventService::InitService();
EventService::FireEvent(new EventData(ApplicationEvents::APPLICATION_EVENT_REQUEST_RECEIVED));
$sSwitchEnv = utils::ReadParam('switch_env', null);
$bAllowCache = true;
if (($sSwitchEnv != null) && file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE) &&( Session::Get('itop_env') !== $sSwitchEnv))
@@ -105,4 +99,3 @@ else
}
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
EventService::FireEvent(new EventData(ApplicationEvents::APPLICATION_EVENT_METAMODEL_STARTED));

View File

@@ -111,6 +111,23 @@ class TwigExtension
return utils::IsDevelopmentEnvironment();
}));
// Function to get configuration parameter
// Usage in twig: {{ get_config_parameter('foo') }}
$oTwigEnv->addFunction(new TwigFunction('get_config_parameter', function ($sParamName) {
$oConfig = MetaModel::GetConfig();
return $oConfig->Get($sParamName);
}));
// Function to get a module setting
// Usage in twig: {{ get_module_setting(<MODULE_CODE>, <PROPERTY_CODE> [, <DEFAULT_VALUE>]) }}
// since 3.0.0, but see N°4034 for upcoming evolutions in the 3.1
$oTwigEnv->addFunction(new TwigFunction('get_module_setting', function (string $sModuleCode, string $sPropertyCode, $defaultValue = null) {
$oConfig = MetaModel::GetConfig();
return $oConfig->GetModuleSetting($sModuleCode, $sPropertyCode, $defaultValue);
}));
// Function to get the URL of a static page in a module
// Usage in twig: {{ get_static_page_module_url('itop-my-module', 'path-to-my-page') }}
$oTwigEnv->addFunction(new TwigFunction('get_static_page_module_url', function ($sModuleName, $sPage) {

View File

@@ -4,8 +4,8 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinksEditTable;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
/**
* Class UILinksWidgetDirect
@@ -23,7 +23,6 @@ class UILinksWidgetDirect
/**
* UILinksWidgetDirect constructor.
*
* @param string $sClass
* @param string $sAttCode
* @param string $sInputId
@@ -81,10 +80,97 @@ class UILinksWidgetDirect
*/
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj)
{
$oBlock = new BlockDirectLinksEditTable($this, $this->sInputid);
$oBlock->InitTable($oPage, $oValue, $sFormPrefix);
if (empty($aArgs)) {
$aArgs = [];
}
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
switch($oLinksetDef->GetEditMode())
{
case LINKSET_EDITMODE_NONE: // The linkset is read-only
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, false /* bDisplayMenu*/);
break;
case LINKSET_EDITMODE_ADDONLY: // The only possible action is to open (in a new window) the form to create a new object
if ($oCurrentObj && !$oCurrentObj->IsNew())
{
$sTargetClass = $oLinksetDef->GetLinkedClass();
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
$sDefault = "default[$sExtKeyToMe]=".$oCurrentObj->GetKey();
$oAppContext = new ApplicationContext();
$sParams = $oAppContext->GetForLink();
$oPage->p("<a target=\"_blank\" href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=new&class=$sTargetClass&$sParams&{$sDefault}\">".Dict::Format('UI:ClickToCreateNew', Metamodel::GetName($sTargetClass))."</a>\n");
}
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, false /* bDisplayMenu*/);
break;
case LINKSET_EDITMODE_INPLACE: // The whole linkset can be edited 'in-place'
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj);
break;
case LINKSET_EDITMODE_ADDREMOVE: // The whole linkset can be edited 'in-place'
$sTargetClass = $oLinksetDef->GetLinkedClass();
$sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
$oExtKeyDef = MetaModel::GetAttributeDef($sTargetClass, $sExtKeyToMe);
$aButtons = array('add');
if ($oExtKeyDef->IsNullAllowed())
{
$aButtons = array('add', 'remove');
}
$this->DisplayEditInPlace($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aButtons);
break;
case LINKSET_EDITMODE_ACTIONS:
default:
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, true /* bDisplayMenu*/);
}
}
/**
* @param WebPage $oPage
* @param DBObjectSet $oValue
* @param array $aArgs
* @param string $sFormPrefix
* @param DBObject $oCurrentObj
* @param bool $bDisplayMenu
*
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (protected method, always called with default value)
*/
protected function DisplayAsBlock(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $bDisplayMenu)
{
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
$sTargetClass = $oLinksetDef->GetLinkedClass();
if ($oCurrentObj && $oCurrentObj->IsNew() && $bDisplayMenu)
{
$oPage->p(Dict::Format('UI:BeforeAdding_Class_ObjectsSaveThisObject', MetaModel::GetName($sTargetClass)));
}
else
{
$oFilter = new DBObjectSearch($sTargetClass);
$oFilter->AddCondition($oLinksetDef->GetExtKeyToMe(), $oCurrentObj->GetKey(),'=');
$aDefaults = array($oLinksetDef->GetExtKeyToMe() => $oCurrentObj->GetKey());
$oAppContext = new ApplicationContext();
foreach($oAppContext->GetNames() as $sKey)
{
// The linked object inherits the parent's value for the context
if (MetaModel::IsValidAttCode($this->sClass, $sKey) && $oCurrentObj)
{
$aDefaults[$sKey] = $oCurrentObj->Get($sKey);
}
}
$aParams = array(
'target_attr' => $oLinksetDef->GetExtKeyToMe(),
'object_id' => $oCurrentObj ? $oCurrentObj->GetKey() : null,
'menu' => $bDisplayMenu,
'menu_actions_target' => '_blank',
'default' => $aDefaults,
'table_id' => $this->sClass.'_'.$this->sAttCode,
);
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oPage, $this->sInputid, $aParams);
}
}
/**
@@ -143,6 +229,55 @@ class UILinksWidgetDirect
$oPage->add('</div></div>');
}
/**
* @param WebPage $oPage
* @param DBObjectSet $oValue
* @param array $aArgs
* @param string $sFormPrefix
* @param DBObject $oCurrentObj
* @param array $aButtons
*
* @since 2.7.7 3.0.1 3.1.0 N°3129 Remove default value for $aArgs for PHP 8.0 compatibility (protected method, caller already handles it)
*/
protected function DisplayEditInPlace(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
{
$aAttribs = $this->GetTableConfig();
$oValue->Rewind();
$aData = array();
while ($oLinkObj = $oValue->Fetch()) {
$aRow = array();
$aRow['form::select'] = '<input type="checkbox" class="selectList'.$this->sInputid.'" value="'.$oLinkObj->GetKey().'"/>';
foreach ($this->aZlist as $sLinkedAttCode) {
$aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
}
$aData[] = $aRow;
}
$oDiv = UIContentBlockUIBlockFactory::MakeStandard($this->sInputid, ['listContainer']);
$oPage->AddSubBlock($oDiv);
$oDatatable = DataTableUIBlockFactory::MakeForForm($this->sInputid, $aAttribs, $aData);
$oDatatable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
$oDiv->AddSubBlock($oDatatable);
$sInputName = $sFormPrefix.'attr_'.$this->sAttCode;
$aLabels = array(
'delete' => Dict::S('UI:Button:Delete'),
// 'modify' => 'Modify...' ,
'creation_title' => Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sLinkedClass)),
'create' => Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($this->sLinkedClass)),
'remove' => Dict::S('UI:Button:Remove'),
'add' => Dict::Format('UI:AddAnExisting_Class', MetaModel::GetName($this->sLinkedClass)),
'selection_title' => Dict::Format('UI:SelectionOf_Class', MetaModel::GetName($this->sLinkedClass)),
);
$oContext = new ApplicationContext();
$sSubmitUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?'.$oContext->GetForLink();
$sJSONLabels = json_encode($aLabels);
$sJSONButtons = json_encode($aButtons);
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
// Don't automatically launch the search if the table is huge
$bDoSearch = !utils::IsHighCardinality($this->sLinkedClass);
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
$oPage->add_ready_script("$('#{$this->sInputid}').directlinks({class_name: '$this->sClass', att_code: '$this->sAttCode', input_name:'$sInputName', labels: $sJSONLabels, submit_to: '$sSubmitUrl', buttons: $sJSONButtons, oWizardHelper: $sWizHelper, do_search: $sJSDoSearch});");
}
/**
* @param WebPage $oPage
* @param DBObject $oCurrentObj
@@ -298,21 +433,18 @@ HTML
{
}
public function GetTableConfig()
protected function GetTableConfig()
{
$aAttribs = array();
$aAttribs['form::select'] = array(
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);oWidget".$this->sInputid.".directlinks('instance')._onSelectChange();\" class=\"checkAll\"></input>",
'description' => Dict::S('UI:SelectAllToggle+'),
);
$aAttribs['form::select'] = array('label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->sInputid}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>", 'description' => Dict::S('UI:SelectAllToggle+'));
foreach ($this->aZlist as $sLinkedAttCode) {
foreach($this->aZlist as $sLinkedAttCode)
{
$oAttDef = MetaModel::GetAttributeDef($this->sLinkedClass, $sLinkedAttCode);
$aAttribs[$sLinkedAttCode] = array('label' => MetaModel::GetLabel($this->sLinkedClass, $sLinkedAttCode), 'description' => $oAttDef->GetOrderByHint());
}
return $aAttribs;
return $aAttribs;
}
/**
@@ -411,43 +543,12 @@ HTML
{
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
}
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue)) {
if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue))
{
$oSearch->AddCondition($sAttCode, $defaultValue);
}
}
}
}
public function GetClass(): string
{
return $this->sClass;
}
public function GetLinkedClass(): string
{
return $this->sLinkedClass;
}
public function GetAttCode(): string
{
return $this->sAttCode;
}
public function GetInputId(): string
{
return $this->sInputid;
}
public function GetNameSuffix(): string
{
return $this->sNameSuffix;
}
public function GetZList(): array
{
return $this->aZlist;
}
}

View File

@@ -6,18 +6,18 @@
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksEditTable;
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinksEdit\BlockIndirectLinksEdit;
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog\BlockObjectPickerDialog;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
require_once(APPROOT.'application/displayblock.class.inc.php');
class UILinksWidget
class UILinksWidget
{
protected $m_sClass;
protected $m_sAttCode;
protected $m_sNameSuffix;
protected $m_sInputId;
protected $m_iInputId;
protected $m_aAttributes;
protected $m_sExtKeyToRemote;
protected $m_sExtKeyToMe;
@@ -33,7 +33,7 @@ class UILinksWidget
*
* @param string $sClass
* @param string $sAttCode AttributeLinkedSetIndirect attcode
* @param string $sInputId
* @param int $iInputId
* @param string $sNameSuffix
* @param bool $bDuplicatesAllowed
*
@@ -41,14 +41,13 @@ class UILinksWidget
* @throws \DictExceptionMissingString
* @throws \Exception
*/
public function __construct($sClass, $sAttCode, $sInputId, $sNameSuffix = '', $bDuplicatesAllowed = false)
public function __construct($sClass, $sAttCode, $iInputId, $sNameSuffix = '', $bDuplicatesAllowed = false)
{
$this->m_sClass = $sClass;
$this->m_sAttCode = $sAttCode;
$this->m_sInputId = $sInputId;
$this->m_sNameSuffix = $sNameSuffix;
$this->m_iInputId = $iInputId;
$this->m_bDuplicatesAllowed = $bDuplicatesAllowed;
$this->m_aEditableFields = array();
/** @var AttributeLinkedSetIndirect $oAttDef */
@@ -64,7 +63,7 @@ class UILinksWidget
$this->m_aEditableFields = array();
$this->m_aTableConfig = array();
$this->m_aTableConfig['form::checkbox'] = array(
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_sInputId.".OnSelectChange();\">",
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_iInputId.".OnSelectChange();\">",
'description' => Dict::S('UI:SelectAllToggle+'),
);
@@ -92,13 +91,234 @@ class UILinksWidget
}
}
/**
* A one-row form for editing a link record
*
* @param WebPage $oP Web page used for the ouput
* @param DBObject $oLinkedObj Remote object
* @param DBObject|int $linkObjOrId Either the lnk object or a unique number for new link records to add
* @param array $aArgs Extra context arguments
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
* @param int $iUniqueId A unique identifier of new links
* @param boolean $bReadOnly Display link as editable or read-only. Default is false (editable)
*
* @return array The HTML fragment of the one-row form
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \Exception
*/
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId, $bReadOnly = false)
{
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
$aRow = array();
$aFieldsMap = array();
$iKey = 0;
if (is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
{
$iKey = $linkObjOrId->GetKey();
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
$sPrefix .= "[$iKey][";
$sNameSuffix = "]"; // To make a tabular form
$aArgs['prefix'] = $sPrefix;
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
$aArgs['this'] = $linkObjOrId;
if ($bReadOnly)
{
$aRow['form::checkbox'] = "";
foreach ($this->m_aEditableFields as $sFieldCode)
{
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
$aRow[$sFieldCode] = $sDisplayValue;
}
}
else
{
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
foreach ($this->m_aEditableFields as $sFieldCode)
{
$sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode);
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId);
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
}
}
$sState = $linkObjOrId->GetState();
$sRemoteKeySafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $this->m_sExtKeyToRemote);;
}
else
{
// form for creating a new record
if (is_object($linkObjOrId))
{
// New link existing only in memory
$oNewLinkObj = $linkObjOrId;
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
$oNewLinkObj->Set($this->m_sExtKeyToMe,
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
}
else
{
$iRemoteObjKey = $linkObjOrId;
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
$oNewLinkObj->Set($this->m_sExtKeyToRemote,
$oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
$oNewLinkObj->Set($this->m_sExtKeyToMe,
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
}
$sPrefix .= "[-$iUniqueId][";
$sNameSuffix = "]"; // To make a tabular form
$aArgs['prefix'] = $sPrefix;
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".($iUniqueId < 0 ? -$iUniqueId : $iUniqueId);
$aArgs['this'] = $oNewLinkObj;
$sInputValue = $iUniqueId > 0 ? "-$iUniqueId" : "$iUniqueId";
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"0\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">";
if ($iUniqueId > 0)
{
// Rows created with ajax call need OnLinkAdded call.
//
$oP->add_ready_script(
<<<EOF
PrepareWidgets();
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
EOF
);
}
else
{
// Rows added before loading the form don't have to call OnLinkAdded.
// Listeners are already present and DOM is not recreated
$iPositiveUniqueId = -$iUniqueId;
$oP->add_ready_script(<<<EOF
oWidget{$this->m_iInputId}.AddLink($iPositiveUniqueId, $iRemoteObjKey);
EOF
);
}
foreach($this->m_aEditableFields as $sFieldCode)
{
$sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode);
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId);
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
$sValue = $oNewLinkObj->Get($sFieldCode);
$oP->add_ready_script(
<<<JS
oWidget{$this->m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue');
JS
);
}
$sState = '';
$sRemoteKeySafeFieldId = $this->GetFieldId($iUniqueId, $this->m_sExtKeyToRemote);
}
if (!$bReadOnly)
{
$sExtKeyToMeId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToMe);
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
$sExtKeyToRemoteId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToRemote);
$aFieldsMap[$this->m_sExtKeyToRemote] = $sExtKeyToRemoteId;
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToRemoteId\" value=\"$iRemoteObjKey\">";
}
// Adding fields from remote class
// all fields are embedded in a span + added to $aFieldsMap array so that we can refresh them after extkey change
$aRemoteFieldsMap = [];
foreach (MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
{
$sSafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $sFieldCode);
$aRow['static::'.$sFieldCode] = "<span id='field_$sSafeFieldId'>".$oLinkedObj->GetAsHTML($sFieldCode).'</span>';
$aRemoteFieldsMap[$sFieldCode] = $sSafeFieldId;
}
// id field is needed so that remote object could be load server side
$aRemoteFieldsMap['id'] = $sRemoteKeySafeFieldId;
// Generate WizardHelper to update dependant fields
$this->AddWizardHelperInit($oP, $aArgs['wizHelper'], $this->m_sLinkedClass, $sState, $aFieldsMap);
//instantiate specific WizarHelper instance for remote class fields refresh
$bHasExtKeyUpdatingRemoteClassFields = (
array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs)
&& ($aArgs['replaceDependenciesByRemoteClassFields'])
);
if ($bHasExtKeyUpdatingRemoteClassFields)
{
$this->AddWizardHelperInit($oP, $aArgs['wizHelperRemote'], $this->m_sRemoteClass, $sState, $aRemoteFieldsMap);
}
return $aRow;
}
private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId): void
{
if (($sFieldCode === $this->m_sExtKeyToRemote))
{
// current field is the lnk extkey to the remote class
$aArgs['replaceDependenciesByRemoteClassFields'] = true;
$sRowFieldCode = 'static::key';
$aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote';
$aRemoteAttDefs = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
$aRemoteCodes = array_map(
function ($value) {
return $value->GetCode();
},
$aRemoteAttDefs
);
$aArgs['remoteCodes'] = $aRemoteCodes;
}
else
{
$aArgs['replaceDependenciesByRemoteClassFields'] = false;
$sRowFieldCode = $sFieldCode;
}
$sValue = $oLnk->Get($sFieldCode);
$sDisplayValue = $oLnk->GetEditValue($sFieldCode);
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
$aRow[$sRowFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'
.cmdbAbstractObject::GetFormElementForField(
$oP,
$this->m_sLinkedClass,
$sFieldCode,
$oAttDef,
$sValue,
$sDisplayValue,
$sSafeFieldId,
$sNameSuffix,
0,
$aArgs
)
.'</div></div></div>';
}
private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true)
{
$sFieldId = $this->m_sInputId.'_'.$sFieldCode.'['.$iLnkId.']';
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$iLnkId.']';
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
}
private function AddWizardHelperInit($oP, $sWizardHelperVarName, $sWizardHelperClass, $sState, $aFieldsMap): void
{
$iFieldsCount = count($aFieldsMap);
$sJsonFieldsMap = json_encode($aFieldsMap);
$oP->add_script(
<<<JS
var $sWizardHelperVarName = new WizardHelper('$sWizardHelperClass', '', '$sState');
$sWizardHelperVarName.SetFieldsMap($sJsonFieldsMap);
$sWizardHelperVarName.SetFieldsCount($iFieldsCount);
$sWizardHelperVarName.SetReturnNotEditableFields(true);
$sWizardHelperVarName.SetWizHelperJsVarName('$sWizardHelperVarName');
JS
);
}
/**
* Display the table with the form for editing all the links at once
@@ -136,12 +356,92 @@ class UILinksWidget
*/
public function Display(WebPage $oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj): string
{
$oBlock = new BlockIndirectLinksEditTable($this);
$oBlock->InitTable($oPage, $oValue, $aArgs, $sFormPrefix, $oCurrentObj, $this->m_aTableConfig);
$sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
$oBlock = new BlockIndirectLinksEdit("linkedset_{$sLinkedSetId}", ["ibo-block-indirect-links--edit"]);
$oBlock->sLinkedSetId = $sLinkedSetId;
$oBlock->sClass = $this->m_sClass;
$oBlock->sAttCode = $this->m_sAttCode;
$oBlock->iInputId = $this->m_iInputId;
$oBlock->sNameSuffix = $this->m_sNameSuffix;
$oBlock->bDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
$oBlock->oWizHelper = 'oWizardHelper'.$sFormPrefix;
$oBlock->sExtKeyToRemote = $this->m_sExtKeyToRemote;
// Don't automatically launch the search if the table is huge
$oBlock->bJSDoSearch = utils::IsHighCardinality($this->m_sRemoteClass) ? 'false' : 'true';
$oBlock->sFormPrefix = $sFormPrefix;
$oBlock->sRemoteClass = $this->m_sRemoteClass;
$oValue->Rewind();
$aForm = array();
$iMaxAddedId = 0;
$iAddedId = -1; // Unique id for new links
$oBlock->aRemoved = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$this->m_sAttCode}_tbd", '[]', 'raw_data'));
while ($oCurrentLink = $oValue->Fetch()) {
// We try to retrieve the remote object as usual
if (!in_array($oCurrentLink->GetKey(), $oBlock->aRemoved)) {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */);
// If successful, it means that we can edit its link
if ($oLinkedObj !== null) {
$bReadOnly = false;
} // Else we retrieve it without restrictions (silos) and will display its link as readonly
else {
$bReadOnly = true;
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */, true);
}
if ($oCurrentLink->IsNew()) {
$key = $iAddedId--;
} else {
$key = $oCurrentLink->GetKey();
}
$iMaxAddedId = max($iMaxAddedId, $key);
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
}
}
$oBlock->iMaxAddedId = (int)$iMaxAddedId;
$oDataTable = DataTableUIBlockFactory::MakeForForm("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aForm);
$oDataTable->SetOptions(['select_mode' => 'custom', 'disable_hyperlinks' => true]);
$oBlock->AddSubBlock($oDataTable);
$oBlock->AddControls();
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
}
/**
* @param string $sClass
* @param string $sAttCode
*
* @return string
* @throws \Exception
*/
protected static function GetTargetClass($sClass, $sAttCode)
{
/** @var AttributeLinkedSet $oAttDef */
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
$sLinkedClass = $oAttDef->GetLinkedClass();
$sTargetClass = '';
switch(get_class($oAttDef))
{
case 'AttributeLinkedSetIndirect':
/** @var AttributeExternalKey $oLinkingAttDef */
/** @var AttributeLinkedSetIndirect $oAttDef */
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
$sTargetClass = $oLinkingAttDef->GetTargetClass();
break;
case 'AttributeLinkedSet':
$sTargetClass = $sLinkedClass;
break;
}
return $sTargetClass;
}
/**
* @param WebPage $oPage
* @param DBObject $oCurrentObj
@@ -173,11 +473,11 @@ class UILinksWidget
$sLinkedSetId = "{$this->m_sAttCode}{$this->m_sNameSuffix}";
$oBlock = new BlockObjectPickerDialog($this);
$oBlock = new BlockObjectPickerDialog();
$oPage->AddUiBlock($oBlock);
$oBlock->sLinkedSetId = $sLinkedSetId;
$oBlock->iInputId = $this->m_sInputId;
$oBlock->iInputId = $this->m_iInputId;
$oBlock->sLinkedClassName = MetaModel::GetName($this->m_sLinkedClass);
$oBlock->sClassName = MetaModel::GetName($this->m_sClass);
@@ -248,8 +548,7 @@ class UILinksWidget
foreach ($aLinkedObjectIds as $iObjectId) {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
if (is_object($oLinkedObj)) {
$oBlock = new BlockIndirectLinksEditTable($this);
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
$oRow = new FormTableRow("{$this->m_sAttCode}{$this->m_sNameSuffix}", $this->m_aTableConfig, $aRow, -$iAdditionId);
$oP->AddUiBlock($oRow);
$iAdditionId++;
@@ -276,8 +575,7 @@ class UILinksWidget
foreach ($aLinkedObjectIds as $iObjectId) {
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
if (is_object($oLinkedObj)) {
$oBlock = new BlockIndirectLinksEditTable($this);
$aRow = $oBlock->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
$aData = [];
foreach ($aRow as $item) {
$aData[] = $item;
@@ -338,77 +636,24 @@ class UILinksWidget
/** @var AttributeExternalKey $oAttDef */
$sTargetClass = $oAttDef->GetTargetClass();
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sTargetClass);
if ($sHierarchicalKeyCode !== false) {
if ($sHierarchicalKeyCode !== false)
{
$oFilter = new DBObjectSearch($sTargetClass);
$oFilter->AddCondition('id', $defaultValue);
$oHKFilter = new DBObjectSearch($sTargetClass);
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
}
} catch (Exception $e)
{
}
catch (Exception $e) {
}
} else {
}
else
{
$oSearch->AddCondition($sAttCode, $defaultValue);
}
}
}
}
}
public function GetLinkedSetId(): string
{
return "{$this->m_sAttCode}{$this->m_sNameSuffix}";
}
public function GetClass(): string
{
return $this->m_sClass;
}
public function GetLinkedClass(): string
{
return $this->m_sLinkedClass;
}
public function GetAttCode(): string
{
return $this->m_sAttCode;
}
public function GetInputId(): string
{
return $this->m_sInputId;
}
public function GetNameSuffix(): string
{
return $this->m_sNameSuffix;
}
public function IsDuplicatesAllowed(): bool
{
return $this->m_bDuplicatesAllowed;
}
public function GetExternalKeyToRemote(): string
{
return $this->m_sExtKeyToRemote;
}
public function GetExternalKeyToMe(): string
{
return $this->m_sExtKeyToMe;
}
public function GetRemoteClass(): string
{
return $this->m_sRemoteClass;
}
public function GetEditableFields(): array
{
return $this->m_aEditableFields;
}
}

View File

@@ -69,16 +69,6 @@ class utils
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_CONTEXT_PARAM = 'context_param';
/**
* @var string To filter routes passed to back-end router before being redirected to corresponding controller / method
* @since 3.1.0
*/
public const ENUM_SANITIZATION_FILTER_ROUTE = 'route';
/**
* @var string To filter operation codes passed to back-end router before being redirected to corresponding controller (/ business logic in case of legacy operations)
* @since 3.1.0
*/
public const ENUM_SANITIZATION_FILTER_OPERATION = 'operation';
/**
* @var string
* @since 3.0.0
@@ -416,8 +406,6 @@ class utils
break;
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
case static::ENUM_SANITIZATION_FILTER_ROUTE:
case static::ENUM_SANITIZATION_FILTER_OPERATION:
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
@@ -439,31 +427,27 @@ class utils
switch ($sSanitizationFilter)
{
case static::ENUM_SANITIZATION_FILTER_TRANSACTION_ID:
// Same as parameter type but keep the dot character
// transaction_id, the dot is mostly for Windows servers when using file storage as the tokens are named *.tmp
// - See N°1835
// - Note: It must be included at the regexp beginning otherwise you'll get an invalid character error
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_ROUTE:
case static::ENUM_SANITIZATION_FILTER_OPERATION:
// - Routes should be of the "controller_namespace_code.controller_method_name" form
// - Operations should be allowed to be namespaced as well even though then don't have dedicated controller yet
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[\.A-Za-z0-9_-]*$/')));
// same as parameter type but keep the dot character
// see N°1835 : when using file transaction_id on Windows you get *.tmp tokens
// it must be included at the regexp beginning otherwise you'll get an invalid character error
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
break;
case static::ENUM_SANITIZATION_FILTER_PARAMETER:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
// Characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
// characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
break;
case static::ENUM_SANITIZATION_FILTER_FIELD_NAME:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
break;
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
break;
}
@@ -2714,7 +2698,7 @@ HTML;
* @return array
* @since 3.0.0
*/
public static function GetClassesForInterface(string $sInterface, string $sClassNameFilter = '', $aExcludedPath = ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]']): array
public static function GetClassesForInterface(string $sInterface, string $sClassNameFilter = '', $aExcludedPath = []): array
{
$aMatchingClasses = [];
@@ -3159,55 +3143,15 @@ HTML;
*/
public static function AddParameterToUrl(string $sUrl, string $sParamName, string $sParamValue): string
{
if (strpos($sUrl, '?') === false) {
if (strpos($sUrl, '?') === false)
{
$sUrl = $sUrl.'?'.urlencode($sParamName).'='.urlencode($sParamValue);
} else {
}
else
{
$sUrl = $sUrl.'&'.urlencode($sParamName).'='.urlencode($sParamValue);
}
return $sUrl;
}
/**
* Return traits array used by a class and by parent classes hierarchy.
*
* @see https://www.php.net/manual/en/function.class-uses.php#110752
*
* @param string $sClass Class to scan
* @param bool $bAutoload Autoload flag
*
* @return array traits used
* @since 3.1.0
*/
public static function TraitsUsedByClass(string $sClass, bool $bAutoload = true): array
{
$aTraits = [];
do {
$aTraits = array_merge(class_uses($sClass, $bAutoload), $aTraits);
} while ($sClass = get_parent_class($sClass));
foreach ($aTraits as $sTrait => $same) {
$aTraits = array_merge(class_uses($sTrait, $bAutoload), $aTraits);
}
return array_unique($aTraits);
}
/**
* Test trait usage by a class or by parent classes hierarchy.
*
* @param string $sTrait Trait to search for
* @param string $sClass Class to check
*
* @return bool
* @since 3.1.0
*/
public static function IsTraitUsedByClass(string $sTrait, string $sClass): bool
{
return in_array($sTrait, self::TraitsUsedByClass($sClass, true));
}
public static function GetUniqId()
{
return hash('sha256', uniqid(sprintf('%x', rand()), true).sprintf('%x', rand()));
}
}

View File

@@ -12,7 +12,7 @@
"ext-json": "*",
"ext-mysqli": "*",
"ext-soap": "*",
"apereo/phpcas" : "~1.6.0",
"apereo/phpcas" : "~1.3",
"combodo/tcpdf": "~6.4.4",
"guzzlehttp/guzzle": "^7.4.5",
"laminas/laminas-mail": "^2.11",

14
composer.lock generated
View File

@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1fee7c7fd7649286a09641ae53e216de",
"content-hash": "276d2024de344c0d4105b15850560696",
"packages": [
{
"name": "apereo/phpcas",
"version": "1.6.0",
"version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/apereo/phpCAS.git",
"reference": "f817c72a961484afef95ac64a9257c8e31f063b9"
"reference": "d6f5797fb568726f34c8e48741776d81e4a2646b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/apereo/phpCAS/zipball/f817c72a961484afef95ac64a9257c8e31f063b9",
"reference": "f817c72a961484afef95ac64a9257c8e31f063b9",
"url": "https://api.github.com/repos/apereo/phpCAS/zipball/d6f5797fb568726f34c8e48741776d81e4a2646b",
"reference": "d6f5797fb568726f34c8e48741776d81e4a2646b",
"shasum": ""
},
"require": {
@@ -70,9 +70,9 @@
],
"support": {
"issues": "https://github.com/apereo/phpCAS/issues",
"source": "https://github.com/apereo/phpCAS/tree/1.6.0"
"source": "https://github.com/apereo/phpCAS/tree/1.5.0"
},
"time": "2022-10-31T20:39:27+00:00"
"time": "2022-05-03T21:12:54+00:00"
},
{
"name": "combodo/tcpdf",

View File

@@ -89,12 +89,8 @@ 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');
/**
* Attributes implementing this interface won't be accepted as `group by` field
*
* @since 2.7.4 N°3473
*/
interface iAttributeNoGroupBy
@@ -1514,31 +1510,9 @@ class AttributeLinkedSet extends AttributeDefinition
return $this->GetOptional('tracking_level', MetaModel::GetConfig()->Get('tracking_level_linked_set_default'));
}
/**
* @deprecated 3.1.0 N°5563 this attribute is no longer used
* @return string see LINKSET_EDITMODE_* constants
*/
public function GetEditMode()
{
return $this->GetOptional('legacy_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 boolean
* @since 3.1.0 N°5563
*/
public function GetReadOnly()
{
return $this->GetOptional('read_only', false);
return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS);
}
public function GetLinkedClass()
@@ -2315,15 +2289,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',
@@ -6057,9 +6022,7 @@ class AttributeDateTime extends AttributeDBField
public function GetDefaultValue(DBObject $oHostObject = null)
{
if (!$this->IsNullAllowed()) {
return date($this->GetInternalFormat());
}
// null value will be replaced by the current date, if not already set, in DoComputeValues
return $this->GetNullValue();
}
@@ -7849,7 +7812,7 @@ class AttributeBlob extends AttributeDefinition
public function GetDefaultValue(DBObject $oHostObject = null)
{
return new ormDocument('', '', '');
return "";
}
public function IsNullAllowed(DBObject $oHostObject = null)
@@ -8198,11 +8161,6 @@ class AttributeImage extends AttributeBlob
return $oDoc;
}
public function GetDefaultValue(DBObject $oHostObject = null)
{
return new ormDocument('', '', '');
}
/**
* Check that the supplied ormDocument actually contains an image
* {@inheritDoc}
@@ -11394,13 +11352,6 @@ class AttributeTagSet extends AttributeSet
return new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
}
public function GetDefaultValue(DBObject $oHostObject = null)
{
$oTagSet = new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
$oTagSet->SetValues([]);
return $oTagSet;
}
public function IsNull($proposedValue)
{
if (is_null($proposedValue))
@@ -13132,7 +13083,7 @@ class AttributeObsolescenceFlag extends AttributeBoolean
public function GetDefaultValue(DBObject $oHostObject = null)
{
return $this->MakeRealValue(false, $oHostObject);
return $this->MakeRealValue("", $oHostObject);
}
public function IsNullAllowed()

View File

@@ -11,7 +11,7 @@ define('UTF8_BOM', chr(239).chr(187).chr(191)); // 0xEF, 0xBB, 0xBF
/**
* CellChangeSpec
* A series of classes, keeping the information about a given cell: could it be changed or not (and why)?
* A series of classes, keeping the information about a given cell: could it be changed or not (and why)?
*
* @package iTopORM
*/
@@ -42,17 +42,6 @@ abstract class CellChangeSpec
return $this->m_sOql;
}
/**
* @since 3.1.0 N°5305
*/
public function GetDisplayableValueAndDescription(): string
{
return sprintf("%s%s",
$this->GetDisplayableValue(),
$this->GetDescription()
);
}
abstract public function GetDescription();
}
@@ -97,90 +86,26 @@ class CellStatus_Issue extends CellStatus_Modify
parent::__construct($proposedValue, $previousValue);
}
public function GetDisplayableValue()
public function GetDescription()
{
if (is_null($this->m_proposedValue))
{
return Dict::Format('UI:CSVReport-Value-SetIssue');
return Dict::Format('UI:CSVReport-Value-SetIssue', $this->m_sReason);
}
return Dict::Format('UI:CSVReport-Value-ChangeIssue', \utils::EscapeHtml($this->m_proposedValue));
}
public function GetDescription()
{
return $this->m_sReason;
}
/*
* @since 3.1.0 N°5305
*/
public function GetDisplayableValueAndDescription(): string
{
return sprintf("%s. %s",
$this->GetDisplayableValue(),
$this->GetDescription()
);
return Dict::Format('UI:CSVReport-Value-ChangeIssue', $this->m_proposedValue, $this->m_sReason);
}
}
class CellStatus_SearchIssue extends CellStatus_Issue
{
/** @var string|null $m_sAllowedValues */
private $m_sAllowedValues;
/**
* @since 3.1.0 N°5305
* @var string $sSerializedSearch
*/
private $sSerializedSearch;
/** @var string|null $m_sTargetClass */
private $m_sTargetClass;
/**
* CellStatus_SearchIssue constructor.
* @since 3.1.0 N°5305
*
* @param string $sOql : main message
* @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
*/
public function __construct($sSerializedSearch, $sReason, $sClass=null, $sAllowedValues=null)
public function __construct()
{
parent::__construct(null, null, $sReason);
$this->sSerializedSearch = $sSerializedSearch;
$this->m_sAllowedValues = $sAllowedValues;
$this->m_sTargetClass = $sClass;
}
public function GetDisplayableValue()
{
if (null === $this->m_sReason) {
return Dict::Format('UI:CSVReport-Value-NoMatch', '');
}
return $this->m_sReason;
parent::__construct(null, null, null);
}
public function GetDescription()
{
if (\utils::IsNullOrEmptyString($this->m_sAllowedValues) ||
\utils::IsNullOrEmptyString($this->m_sTargetClass)) {
return '';
}
return Dict::Format('UI:CSVReport-Value-NoMatch-PossibleValues', $this->m_sTargetClass, $this->m_sAllowedValues);
}
/**
* @since 3.1.0 N°5305
* @return string
*/
public function GetSearchLinkUrl()
{
return sprintf("UI.php?operation=search&filter=%s",
rawurlencode($this->sSerializedSearch)
);
return Dict::S('UI:CSVReport-Value-NoMatch');
}
}
@@ -201,24 +126,11 @@ class CellStatus_NullIssue extends CellStatus_Issue
class CellStatus_Ambiguous extends CellStatus_Issue
{
protected $m_iCount;
/**
* @since 3.1.0 N°5305
* @var string
*/
protected $sSerializedSearch;
/**
* @since 3.1.0 N°5305
*
* @param $previousValue
* @param int $iCount
* @param string $sSerializedSearch
*
*/
public function __construct($previousValue, $iCount, $sSerializedSearch)
public function __construct($previousValue, $iCount, $sOql)
{
$this->m_iCount = $iCount;
$this->sSerializedSearch = $sSerializedSearch;
$this->m_sQuery = $sOql;
parent::__construct(null, $previousValue, '');
}
@@ -227,23 +139,12 @@ class CellStatus_Ambiguous extends CellStatus_Issue
$sCount = $this->m_iCount;
return Dict::Format('UI:CSVReport-Value-Ambiguous', $sCount);
}
/**
* @since 3.1.0 N°5305
* @return string
*/
public function GetSearchLinkUrl()
{
return sprintf("UI.php?operation=search&filter=%s",
rawurlencode($this->sSerializedSearch)
);
}
}
/**
* RowStatus
* A series of classes, keeping the information about a given row: could it be changed or not (and why)?
* A series of classes, keeping the information about a given row: could it be changed or not (and why)?
*
* @package iTopORM
*/
@@ -310,26 +211,6 @@ class RowStatus_Issue extends RowStatus
}
}
/**
* class dedicated to testability
* not used/ignored in csv imports UI/CLI
* @since 3.1.0 N°5305
*/
class RowStatus_Error extends RowStatus
{
/** @var string */
protected $m_sError;
public function __construct($sError)
{
$this->m_sError = $sError;
}
public function GetDescription()
{
return $this->m_sError;
}
}
/**
* BulkChange
@@ -339,35 +220,17 @@ class RowStatus_Error extends RowStatus
*/
class BulkChange
{
/** @var string */
protected $m_sClass;
protected $m_sClass;
protected $m_aData; // Note: hereafter, iCol maybe actually be any acceptable key (string)
// #@# todo: rename the variables to sColIndex
/** @var array<string, string> attcode as key, iCol as value */
protected $m_aAttList;
/** @var array<string, array<string, string>> sExtKeyAttCode as key, array of sExtReconcKeyAttCode/iCol as value */
protected $m_aExtKeys;
/** @var string[] list of attcode (attcode = 'id' for the pkey) */
protected $m_aReconcilKeys;
/** @var string OQL - if specified, then the missing items will be reported */
protected $m_sSynchroScope;
/**
* @var array<string, mixed> attcode as key, attvalue as value. Values to be set when an object gets out of scope
* (ignored if no scope has been defined)
*/
protected $m_aOnDisappear;
/**
* @see DateTime::createFromFormat
* @var string Date format specification
*/
protected $m_sDateFormat;
/**
* @see AttributeEnum
* @var boolean true if Values in the data set are localized
*/
protected $m_bLocalizedValues;
/** @var array Cache for resolving external keys based on the given search criterias */
protected $m_aExtKeysMappingCache;
protected $m_aAttList; // attcode => iCol
protected $m_aExtKeys; // aExtKeys[sExtKeyAttCode][sExtReconcKeyAttCode] = iCol;
protected $m_aReconcilKeys; // attcode (attcode = 'id' for the pkey)
protected $m_sSynchroScope; // OQL - if specified, then the missing items will be reported
protected $m_aOnDisappear; // array of attcode => value, values to be set when an object gets out of scope (ignored if no scope has been defined)
protected $m_sDateFormat; // Date format specification, see DateTime::createFromFormat
protected $m_bLocalizedValues; // Values in the data set are localized (see AttributeEnum)
protected $m_aExtKeysMappingCache; // Cache for resolving external keys based on the given search criterias
public function __construct($sClass, $aData, $aAttList, $aExtKeys, $aReconcilKeys, $sSynchroScope = null, $aOnDisappear = null, $sDateFormat = null, $bLocalize = false)
{
@@ -398,30 +261,30 @@ class BulkChange
$this->m_sReportCsvSep = $sSeparator;
$this->m_sReportCsvDelimiter = $sDelimiter;
}
protected function ResolveExternalKey($aRowData, $sAttCode, &$aResults)
{
$oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
foreach ($this->m_aExtKeys[$sAttCode] as $sReconKeyAttCode => $iCol)
foreach ($this->m_aExtKeys[$sAttCode] as $sForeignAttCode => $iCol)
{
if ($sReconKeyAttCode == 'id')
if ($sForeignAttCode == 'id')
{
$value = (int) $aRowData[$iCol];
}
else
{
// The foreign attribute is one of our reconciliation key
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sReconKeyAttCode);
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sForeignAttCode);
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
}
$oReconFilter->AddCondition($sReconKeyAttCode, $value, '=');
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
}
$oExtObjects = new CMDBObjectSet($oReconFilter);
$aKeys = $oExtObjects->ToArray();
return array($oReconFilter, $aKeys);
return array($oReconFilter->ToOql(), $aKeys);
}
// Returns true if the CSV data specifies that the external key must be left undefined
@@ -455,10 +318,10 @@ class BulkChange
{
$aResults = array();
$aErrors = array();
// External keys reconciliation
//
foreach($this->m_aExtKeys as $sAttCode => $aReconKeys)
foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
{
// Skip external keys used for the reconciliation process
// if (!array_key_exists($sAttCode, $this->m_aAttList)) continue;
@@ -467,7 +330,7 @@ class BulkChange
if ($this->IsNullExternalKeySpec($aRowData, $sAttCode))
{
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
{
// Default reporting
// $aRowData[$iCol] is always null
@@ -489,24 +352,25 @@ class BulkChange
$oReconFilter = new DBObjectSearch($oExtKey->GetTargetClass());
$aCacheKeys = array();
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
{
// The foreign attribute is one of our reconciliation key
if ($sReconKeyAttCode == 'id')
if ($sForeignAttCode == 'id')
{
$value = $aRowData[$iCol];
}
else
{
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sReconKeyAttCode);
$oForeignAtt = MetaModel::GetAttributeDef($oExtKey->GetTargetClass(), $sForeignAttCode);
$value = $oForeignAtt->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
}
$aCacheKeys[] = $value;
$oReconFilter->AddCondition($sReconKeyAttCode, $value, '=');
$oReconFilter->AddCondition($sForeignAttCode, $value, '=');
$aResults[$iCol] = new CellStatus_Void(utils::HtmlEntities($aRowData[$iCol]));
}
$sCacheKey = implode('_|_', $aCacheKeys); // Unique key for this query...
$iForeignKey = null;
$sOQL = '';
// TODO: check if *too long* keys can lead to collisions... and skip the cache in such a case...
if (!array_key_exists($sAttCode, $this->m_aExtKeysMappingCache))
{
@@ -515,8 +379,9 @@ class BulkChange
if (array_key_exists($sCacheKey, $this->m_aExtKeysMappingCache[$sAttCode]))
{
// Cache hit
$iObjectFoundCount = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['c'];
$iCount = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['c'];
$iForeignKey = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['k'];
$sOQL = $this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['oql'];
// Record the hit
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey]['h']++;
}
@@ -524,35 +389,34 @@ class BulkChange
{
// Cache miss, let's initialize it
$oExtObjects = new CMDBObjectSet($oReconFilter);
$iObjectFoundCount = $oExtObjects->Count();
if ($iObjectFoundCount == 1)
$iCount = $oExtObjects->Count();
if ($iCount == 1)
{
$oForeignObj = $oExtObjects->Fetch();
$iForeignKey = $oForeignObj->GetKey();
}
$this->m_aExtKeysMappingCache[$sAttCode][$sCacheKey] = array(
'c' => $iObjectFoundCount,
'c' => $iCount,
'k' => $iForeignKey,
'oql' => $oReconFilter->ToOql(),
'h' => 0, // number of hits on this cache entry
);
}
switch($iObjectFoundCount)
switch($iCount)
{
case 0:
$oCellStatus_SearchIssue = $this->GetCellSearchIssue($oReconFilter);
$aResults[$sAttCode] = $oCellStatus_SearchIssue;
$aErrors[$sAttCode] = Dict::S('UI:CSVReport-Value-Issue-NotFound');
break;
$aErrors[$sAttCode] = Dict::S('UI:CSVReport-Value-Issue-NotFound');
$aResults[$sAttCode]= new CellStatus_SearchIssue();
break;
case 1:
// Do change the external key attribute
$oTargetObj->Set($sAttCode, $iForeignKey);
break;
// Do change the external key attribute
$oTargetObj->Set($sAttCode, $iForeignKey);
break;
default:
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-FoundMany', $iObjectFoundCount);
$aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $iObjectFoundCount, $oReconFilter->serialize());
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-FoundMany', $iCount);
$aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $iCount, $sOQL);
}
}
@@ -569,7 +433,7 @@ class BulkChange
else
{
$aResults[$sAttCode]= new CellStatus_Modify($iForeignObj, $oTargetObj->GetOriginal($sAttCode));
foreach ($aReconKeys as $sReconKeyAttCode => $iCol)
foreach ($aKeyConfig as $sForeignAttCode => $iCol)
{
// Report the change on reconciliation values as well
$aResults[$iCol] = new CellStatus_Modify(utils::HtmlEntities($aRowData[$iCol]));
@@ -582,7 +446,7 @@ class BulkChange
}
}
}
// Set the object attributes
//
foreach ($this->m_aAttList as $sAttCode => $iCol)
@@ -623,13 +487,7 @@ class BulkChange
$value = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
if (is_null($value) && (strlen($aRowData[$iCol]) > 0))
{
if ($oAttDef instanceof AttributeEnum || $oAttDef instanceof AttributeTagSet){
/** @var AttributeDefinition $oAttributeDefinition */
$oAttributeDefinition = $oAttDef;
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-AllowedValues', $sAttCode, implode(',', $oAttributeDefinition->GetAllowedValues()));
} else {
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-NoMatch', $sAttCode);
}
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-NoMatch', $sAttCode);
}
else
{
@@ -646,7 +504,7 @@ class BulkChange
}
}
}
// Reporting on fields
//
$aChangedFields = $oTargetObj->ListChanges();
@@ -698,7 +556,7 @@ class BulkChange
}
}
}
// Checks
//
$res = $oTargetObj->CheckConsistency();
@@ -709,101 +567,12 @@ class BulkChange
}
return $aResults;
}
/**
* search with current permissions did not match
* let's search why and give some more feedbacks to the user through proper labels
*
* @param DBObjectSearch $oDbSearchWithConditions search used to find external key
*
* @return \CellStatus_SearchIssue
* @throws \CoreException
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
*
* @since 3.1.0 N°5305
*/
protected function GetCellSearchIssue($oDbSearchWithConditions) : CellStatus_SearchIssue {
//current search with current permissions did not match
//let's search why and give some more feedback to the user
$sSerializedSearch = $oDbSearchWithConditions->serialize();
// Count all objects with all permissions without any condition
$oDbSearchWithoutAnyCondition = new DBObjectSearch($oDbSearchWithConditions->GetClass());
$oDbSearchWithoutAnyCondition->AllowAllData(true);
$oExtObjectSet = new CMDBObjectSet($oDbSearchWithoutAnyCondition);
$iAllowAllDataObjectCount = $oExtObjectSet->Count();
if ($iAllowAllDataObjectCount === 0) {
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-NoObject', $oDbSearchWithConditions->GetClass());
return new CellStatus_SearchIssue($sSerializedSearch, $sReason);
}
// Count all objects with current user permissions
$oDbSearchWithoutAnyCondition->AllowAllData(false);
$oExtObjectSetWithCurrentUserPermissions = new CMDBObjectSet($oDbSearchWithoutAnyCondition);
$iCurrentUserRightsObjectCount = $oExtObjectSetWithCurrentUserPermissions->Count();
if ($iCurrentUserRightsObjectCount === 0){
// No objects visible by current user
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser', $oDbSearchWithConditions->GetClass());
return new CellStatus_SearchIssue($sSerializedSearch, $sReason);
}
try{
$aDisplayedAllowedValues = [];
// Possibles values are displayed to UI user. we have to limit the amount of displayed values
$oExtObjectSetWithCurrentUserPermissions->SetLimit(4);
for($i = 0; $i < 3; $i++){
/** @var \DBObject $oVisibleObject */
$oVisibleObject = $oExtObjectSetWithCurrentUserPermissions->Fetch();
if (is_null($oVisibleObject)){
break;
}
$aCurrentAllowedValueFields = [];
foreach ($oDbSearchWithConditions->GetInternalParams() as $sForeignAttCode => $sValue){
$aCurrentAllowedValueFields[] = $oVisibleObject->Get($sForeignAttCode);
}
$aDisplayedAllowedValues[] = implode(" ", $aCurrentAllowedValueFields);
}
$allowedValues = implode(", ", $aDisplayedAllowedValues);
if ($oExtObjectSetWithCurrentUserPermissions->Count() > 3){
$allowedValues .= "...";
}
} catch(Exception $e) {
IssueLog::Error("failure during CSV import when fetching few visible objects: ", null,
[ 'target_class' => $oDbSearchWithConditions->GetClass(), 'criteria' => $oDbSearchWithConditions->GetCriteria(), 'message' => $e->getMessage()]
);
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch-NoObject-ForCurrentUser', $oDbSearchWithConditions->GetClass());
return new CellStatus_SearchIssue($sSerializedSearch, $sReason);
}
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);
}
// No match. This is not linked to any right issue
// Possible values: DD,DD
$aCurrentValueFields = [];
foreach ($oDbSearchWithConditions->GetInternalParams() as $sValue){
$aCurrentValueFields[] = $sValue;
}
$value =implode(" ", $aCurrentValueFields);
$sReason = Dict::Format('UI:CSVReport-Value-NoMatch', $value);
return new CellStatus_SearchIssue($sSerializedSearch, $sReason, $oDbSearchWithConditions->GetClass(), $allowedValues);
}
protected function PrepareMissingObject(&$oTargetObj, &$aErrors)
{
$aResults = array();
$aErrors = array();
// External keys
//
foreach($this->m_aExtKeys as $sAttCode => $aKeyConfig)
@@ -816,7 +585,7 @@ class BulkChange
$aResults[$iCol] = new CellStatus_Void('?');
}
}
// Update attributes
//
foreach($this->m_aOnDisappear as $sAttCode => $value)
@@ -827,7 +596,7 @@ class BulkChange
}
$oTargetObj->Set($sAttCode, $value);
}
// Reporting on fields
//
$aChangedFields = $oTargetObj->ListChanges();
@@ -847,7 +616,7 @@ class BulkChange
$aResults[$iCol]= new CellStatus_Void($oTargetObj->Get($sAttCode));
}
}
// Checks
//
$res = $oTargetObj->CheckConsistency();
@@ -905,16 +674,14 @@ class BulkChange
}
$aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors);
if (count($aErrors) > 0)
{
$sErrors = implode(', ', $aErrors);
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
//__ERRORS__ used by tests only
$aResult[$iRow]["__ERRORS__"] = new RowStatus_Error($sErrors);
return $oTargetObj;
}
// Check that any external key will have a value proposed
$aMissingKeys = array();
foreach (MetaModel::GetExternalKeys($this->m_sClass) as $sExtKeyAttCode => $oExtKey)
@@ -922,7 +689,7 @@ class BulkChange
if (!$oExtKey->IsNullAllowed())
{
if (!array_key_exists($sExtKeyAttCode, $this->m_aExtKeys) && !array_key_exists($sExtKeyAttCode, $this->m_aAttList))
{
{
$aMissingKeys[] = $oExtKey->GetLabel();
}
}
@@ -978,16 +745,14 @@ class BulkChange
{
$sErrors = implode(', ', $aErrors);
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
//__ERRORS__ used by tests only
$aResult[$iRow]["__ERRORS__"] = new RowStatus_Error($sErrors);
return;
}
$aChangedFields = $oTargetObj->ListChanges();
if (count($aChangedFields) > 0)
{
$aResult[$iRow]["__STATUS__"] = new RowStatus_Modify(count($aChangedFields));
// Optionaly record the results
//
if ($oChange)
@@ -1029,11 +794,9 @@ class BulkChange
{
$sErrors = implode(', ', $aErrors);
$aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Attribute'));
//__ERRORS__ used by tests only
$aResult[$iRow]["__ERRORS__"] = new RowStatus_Error($sErrors);
return;
}
$aChangedFields = $oTargetObj->ListChanges();
if (count($aChangedFields) > 0)
{
@@ -1058,7 +821,7 @@ class BulkChange
$aResult[$iRow]["__STATUS__"] = new RowStatus_Disappeared(0);
}
}
public function Process(CMDBChange $oChange = null)
{
if ($oChange)
@@ -1103,7 +866,7 @@ class BulkChange
foreach ($this->m_aAttList as $sAttCode => $iCol)
{
if ($sAttCode == 'id') continue;
$oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
{
@@ -1118,18 +881,14 @@ class BulkChange
$sFormat = $sDateFormat;
}
$oFormat = new DateTimeFormat($sFormat);
$sDateExample = $oFormat->Format(new DateTime('2022-10-23 16:25:33'));
$sRegExp = $oFormat->ToRegExpr('/');
$sErrorMsg = Dict::Format('UI:CSVReport-Row-Issue-ExpectedDateFormat', $sDateExample);
if (!preg_match($sRegExp, $sValue))
if (!preg_match($sRegExp, $this->m_aData[$iRow][$iCol]))
{
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
$aResult[$iRow][$iCol] = new CellStatus_Issue(utils::HtmlEntities($sValue), null, $sErrorMsg);
}
else
{
$oDate = DateTime::createFromFormat($sFormat, $sValue);
$oDate = DateTime::createFromFormat($sFormat, $this->m_aData[$iRow][$iCol]);
if ($oDate !== false)
{
$sNewDate = $oDate->format($oAttDef->GetInternalFormat());
@@ -1139,7 +898,7 @@ class BulkChange
{
// Leave the cell unchanged
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
$aResult[$iRow][$iCol] = new CellStatus_Issue($sValue, null, $sErrorMsg);
$aResult[$iRow][$sAttCode] = new CellStatus_Issue(null, utils::HtmlEntities($this->m_aData[$iRow][$iCol]), Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
}
}
}
@@ -1193,26 +952,23 @@ class BulkChange
else
{
// The value has to be found or verified
/** var DBObjectSearch $oReconFilter */
list($oReconFilter, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]);
list($sQuery, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]);
if (count($aMatches) == 1)
{
$oRemoteObj = reset($aMatches); // first item
$valuecondition = $oRemoteObj->GetKey();
$aResult[$iRow][$sAttCode] = new CellStatus_Void($oRemoteObj->GetKey());
}
}
elseif (count($aMatches) == 0)
{
$oCellStatus_SearchIssue = $this->GetCellSearchIssue($oReconFilter);
$aResult[$iRow][$sAttCode] = $oCellStatus_SearchIssue;
}
$aResult[$iRow][$sAttCode] = new CellStatus_SearchIssue();
}
else
{
$aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $oReconFilter->serialize());
$aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $sQuery);
}
}
}
}
else
{
@@ -1263,7 +1019,7 @@ class BulkChange
default:
// Found several matches, ambiguous
$aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Ambiguous'));
$aResult[$iRow]["id"]= new CellStatus_Ambiguous(0, $oReconciliationSet->Count(), $oReconciliationFilter->serialize());
$aResult[$iRow]["id"]= new CellStatus_Ambiguous(0, $oReconciliationSet->Count(), $oReconciliationFilter->ToOql());
$aResult[$iRow]["finalclass"]= 'n/a';
}
}
@@ -1354,7 +1110,7 @@ class BulkChange
}
}
$oBulkChanges->Seek(0);
$aDetails = array();
while ($oChange = $oBulkChanges->Fetch())
{
@@ -1518,7 +1274,7 @@ EOF
$oOldTarget = MetaModel::GetObject($oAttDef->GetTargetClass(), $oOperation->Get('oldvalue'));
$sOldValue = $oOldTarget->GetHyperlink();
}
$sNewValue = Dict::S('UI:UndefinedObject');
if ($oOperation->Get('newvalue') != 0)
{
@@ -1544,11 +1300,11 @@ EOF
}
else
{
$aAttributes[$sAttCode] = 1;
$aAttributes[$sAttCode] = 1;
}
}
}
$aDetails = array();
foreach($aObjects as $iUId => $aObjData)
{
@@ -1600,6 +1356,6 @@ EOF
$aConfig[$sAttCode] = array('label' => MetaModel::GetLabel($sClass, $sAttCode), 'description' => MetaModel::GetDescription($sClass, $sAttCode));
}
$oPage->table($aConfig, $aDetails);
}
}
}

View File

@@ -472,7 +472,7 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
$sDisplayUrl = $oPrevDoc->GetDisplayURL(get_class($this), $this->GetKey(), 'prevdata');
$sDownloadLabel = Dict::S('UI:DownloadDocument_');
$sDownloadLabel = Dict::Format('UI:DownloadDocument_');
$sDownloadUrl = $oPrevDoc->GetDownloadURL(get_class($this), $this->GetKey(), 'prevdata');
$sDocView = <<<HTML

View File

@@ -499,7 +499,7 @@ abstract class CMDBObject extends DBObject
$oMyChangeOp->Set("objkey", $this->GetKey());
$oMyChangeOp->Set("attcode", $sAttCode);
$oMyChangeOp->Set("oldvalue", $original);
$oMyChangeOp->Set("newvalue", $value);
$oMyChangeOp->Set("newvalue", $value[$sAttCode]);
$iId = $oMyChangeOp->DBInsertNoReload();
}
elseif ($oAttDef instanceOf AttributeCustomFields)
@@ -640,6 +640,20 @@ abstract class CMDBObject extends DBObject
return $newKey;
}
public function DBUpdate()
{
// Copy the changes list before the update (the list should be reset afterwards)
$aChanges = $this->ListChanges();
if (count($aChanges) == 0)
{
return;
}
$ret = parent::DBUpdate();
return $ret;
}
/**
* @param null $oDeletionPlan
*

View File

@@ -129,22 +129,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'event_service.debug.filter_events' => [
'type' => 'array',
'description' => 'Filter Event Service debug by events',
'default' => '',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'event_service.debug.filter_sources' => [
'type' => 'array',
'description' => 'Filter Event Service debug by event sources',
'default' => '',
'value' => '',
'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")',
@@ -1254,14 +1238,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'navigation_menu.show_organization_filter' => [
'type' => 'bool',
'description' => 'Display organization filter in menu',
'default' => true,
'value' => true,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'quick_create.enabled' => [
'type' => 'bool',
'description' => 'Whether or not the quick create is enabled',
@@ -1893,7 +1869,7 @@ class Config
}
if (strlen($sNoise) > 0)
{
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
throw new ConfigException('Syntax error in configuration file',
array('file' => $sConfigFile, 'error' => '<tt>'.utils::EscapeHtml($sNoise, ENT_QUOTES).'</tt>'));
}
@@ -2278,7 +2254,7 @@ class Config
$oHandle = null;
$sConfig = null;
if ($this->m_sFile !== null && is_file($this->m_sFile))
if (is_file($this->m_sFile))
{
$oHandle = fopen($this->m_sFile, 'r');
$index = 0;
@@ -2703,7 +2679,7 @@ class ConfigPlaceholdersResolver
}
$sPattern = '/\%(env|server)\((\w+)\)(?:\?:(\w*))?\%/'; //3 capturing groups, ie `%env(HTTP_PORT)?:8080%` produce: `env` `HTTP_PORT` and `8080`.
if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER))
{
return $rawValue;

View File

@@ -270,4 +270,4 @@
</class>
</classes>
</meta>
</itop_design>
</itop_design>

File diff suppressed because it is too large Load Diff

View File

@@ -141,7 +141,7 @@ class DBObjectSet implements iDBObjectSetIterator
{
$sRet = '';
$this->Rewind();
$sRet .= "Set (".$this->m_oFilter->ToOQL(true).")<br/>\n";
$sRet .= "Set (".$this->m_oFilter->ToOQL().")<br/>\n";
$sRet .= "Query: <pre style=\"font-size: smaller; display:inline;\">".$this->m_oFilter->MakeSelectQuery().")</pre>\n";
$sRet .= $this->Count()." records<br/>\n";
@@ -154,7 +154,6 @@ class DBObjectSet implements iDBObjectSetIterator
}
$sRet .= "</ul>\n";
}
$this->Rewind();
return $sRet;
}

View File

@@ -1717,6 +1717,6 @@ abstract class DBSearch
*/
public function __toString()
{
return $this->ToOQL(true);
return $this->ToOQL();
}
}

View File

@@ -182,26 +182,6 @@ class DesignElement extends \DOMElement
return $this->ownerDocument->GetNodes($sXPath, $this);
}
public static function ToArray(DesignElement $oNode)
{
$aRes = [];
if ($oNode->GetNodes('./*')->length == 0) {
return $oNode->GetText('');
}
foreach ($oNode->GetNodes('./*') as $oSubNode) {
/** @var \Combodo\iTop\DesignElement $oSubNode */
$aSubArray = DesignElement::ToArray($oSubNode);
if ($oSubNode->hasAttribute('id')) {
$aRes[$oSubNode->getAttribute('id')] = $aSubArray;
} else {
$aRes[$oSubNode->tagName] = $aSubArray;
}
}
return $aRes;
}
/**
* Create an HTML representation of the DOM, for debugging purposes
*

View File

@@ -77,7 +77,7 @@ class EMail implements iEMail
* @return void
* @throws \ConfigException
* @throws \CoreException
* @since 2.7.8 3.0.3 3.1.0 N°4947 Method creation, to factorize same code in children classes
* @since 2.7.>8 3.0.3 3.1.0 N°4947 Method creation, to factorize same code in children classes
*/
protected function InitRecipientFrom()
{

View File

@@ -299,7 +299,7 @@ class ExecutionKPI
*/
private static function Push(ExecutionKPI $oExecutionKPI)
{
self::$m_aExecutionStack[] = $oExecutionKPI;
array_push(self::$m_aExecutionStack, $oExecutionKPI);
}
/**
@@ -449,3 +449,4 @@ class ExecutionKPI
return 0;
}
}

View File

@@ -551,9 +551,6 @@ class LogChannels
*/
public const NOTIFICATIONS = 'notifications';
/**
* @since 3.0.0
*/
public const CLI = 'CLI';
/**
@@ -563,26 +560,15 @@ class LogChannels
*/
public const CMDB_SOURCE = 'cmdbsource';
/**
* @since 3.0.0
*/
public const CONSOLE = 'console';
public const CONSOLE = 'console';
public const CORE = 'core';
public const CORE = 'core';
public const DEADLOCK = 'DeadLock';
public const DEADLOCK = 'DeadLock';
public const INLINE_IMAGE = 'InlineImage';
public const PORTAL = 'portal';
/**
* @var string
* @since 3.1.0 specific channel for event service
*/
public const EVENT_SERVICE = 'EventService';
public const DM_CRUD = 'DMCRUD';
}

View File

@@ -128,10 +128,6 @@ abstract class MetaModel
/** @var string */
protected static $m_sEnvironment = 'production';
public const REENTRANCE_TYPE_UPDATE = 'update';
protected static $m_aReentranceProtection = [];
/**
* MetaModel constructor.
*/
@@ -6789,19 +6785,6 @@ abstract class MetaModel
}
$sClass = $aRow[$sClassAlias."finalclass"];
}
// if an object is already being updated, then this method will return this object instead of recreating a new one.
// At this point the method DBUpdate of a new object with the same class and id won't do anything due to reentrance protection,
// so to ensure that the potential modifications are correctly saved, the object currently being updated is returned.
// DBUpdate() method then will take care that all the modifications will be saved.
if (array_key_exists($sClassAlias.'id', $aRow)) {
$iKey = $aRow[$sClassAlias."id"];
$oObject = self::GetReentranceObject(Metamodel::REENTRANCE_TYPE_UPDATE, $sClass, $iKey);
if ($oObject !== false) {
return $oObject;
}
}
return new $sClass($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
}
@@ -7560,36 +7543,6 @@ abstract class MetaModel
/** @var AttributeEnum $oAttDef */
return $oAttDef->GetStyle($sValue);
}
protected static function GetReentranceObject($sType, $sClass, $sKey)
{
if (isset(self::$m_aReentranceProtection[$sType][$sClass][$sKey])) {
return self::$m_aReentranceProtection[$sType][$sClass][$sKey];
}
return false;
}
/**
* @param $sType
* @param \DBObject $oObject
*
* @return bool true if reentry possible
*/
public static function StartReentranceProtection($sType, DBObject $oObject)
{
if (isset(self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()])) {
return false;
}
self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()] = $oObject;
return true;
}
public static function StopReentranceProtection($sType, DBObject $oObject)
{
if (isset(self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()])) {
unset(self::$m_aReentranceProtection[$sType][get_class($oObject)][$oObject->GetKey()]);
}
}
}

View File

@@ -25,9 +25,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Service\EventData;
use Combodo\iTop\Service\EventService;
/**
* ormDocument
@@ -196,6 +193,7 @@ class ormDocument
* @param string $sContentDisposition Either 'inline' or 'attachment'
* @param string $sSecretField The attcode of the field containing a "secret" to be provided in order to retrieve the file
* @param string $sSecretValue The value of the secret to be compared with the value of the attribute $sSecretField
* @return none
*/
public static function DownloadDocument(WebPage $oPage, $sClass, $id, $sAttCode, $sContentDisposition = 'attachment', $sSecretField = null, $sSecretValue = null)
{
@@ -214,12 +212,6 @@ class ormDocument
$oDocument = $oObj->Get($sAttCode);
if (is_object($oDocument))
{
$aEventData = array(
'debug_info' => $oDocument->GetFileName(),
'object' => $oObj,
'document' => $oDocument,
);
EventService::FireEvent(new EventData(EVENT_SERVICE_DOWNLOAD_DOCUMENT, $sClass, $aEventData));
$oPage->TrashUnexpectedOutput();
$oPage->SetContentType($oDocument->GetMimeType());
$oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName());

View File

@@ -383,8 +383,9 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$iPreservedCount = count($this->aPreserved);
if ($this->iCursor < $iPreservedCount)
{
$sId = key($this->aPreserved);
$oRet = MetaModel::GetObject($this->sClass, $sId);
$iRet = current($this->aPreserved);
$this->oOriginalSet->Seek($iRet);
$oRet = $this->oOriginalSet->Fetch();
}
else
{
@@ -735,7 +736,6 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$oLink->DBClone();
}
}
$oLink->SetLinkHostObject($oHostObject);
$oLink->DBWrite();
$this->aPreserved[$oLink->GetKey()] = $oLink;

View File

@@ -575,7 +575,7 @@ class CoreServices implements iRestServiceProvider
$oObject = $oElement->GetProperty('object');
if ($oObject)
{
if ($bEnableRedundancy && $sDirection == 'down')
if ($bEnableRedundancy)
{
// Add only the "reached" objects
if ($oElement->GetProperty('is_reached'))

View File

@@ -348,7 +348,7 @@ abstract class User extends cmdbAbstractObject
$aChanges = $this->ListChanges();
if (array_key_exists('login', $aChanges)) {
// Check login uniqueness
if ( $this->GetOriginal('login') === null || strcasecmp($this->Get('login'), $this->GetOriginal('login')) !== 0) {
if (strcasecmp($this->Get('login'), $this->GetOriginal('login')) !== 0) {
$sNewLogin = $aChanges['login'];
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT User WHERE login = :newlogin");
if (!$this->IsNew()) {
@@ -1936,7 +1936,7 @@ class UserRights
// The bug has been fixed in PHP 7.2, but in case session_regenerate_id()
// fails we just silently ignore the error and keep the same session id...
$old_error_handler = set_error_handler(array(__CLASS__, 'VoidErrorHandler'));
Session::RegenerateId(true);
session_regenerate_id(true);
if ($old_error_handler !== null) {
set_error_handler($old_error_handler);
}

View File

@@ -43,9 +43,3 @@
.ibo-svg-illustration--container > svg *[fill="#6c63ff"]{
fill: $ibo-svg-illustration--fill;
}
// Workaround for a Safari (unsupported browser) issue: https://sourceforge.net/p/itop/discussion/itop-hub/thread/fc97ec4a10/?limit=25#1cc0/9930
// Fix found here: https://stackoverflow.com/questions/40895387/z-index-not-working-on-safari-fine-on-firefox-and-chrome
.ibo-navigation-menu.ibo-is-active .ibo-navigation-menu--drawer{
transform: translate3d(0,0,0);
}

View File

@@ -119,10 +119,6 @@ $ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
&.selected {
background-color: $ibo-datatable--row--background-color--is-selected;
}
.ibo-datatable--row-actions-toolbar{
justify-content: end;
}
}
}
@@ -148,20 +144,4 @@ $ibo-fieldsorter--selected--background-color: $ibo-color-blue-200 !default;
@extend %ibo-font-ral-sembol-100;
border-bottom: $ibo-vendors-datatables--columns-header--border-bottom;
}
}
#table-row-action-confirmation-dialog{
.ibo-row-action--confirmation--explanation{
margin-bottom: 16px;
}
.ibo-row-action--confirmation--do-not-show-again--checkbox{
height: auto;
display: inline-block;
width: auto;
}
}

View File

@@ -27,6 +27,11 @@ tr.ibo-csv-import--row-unchanged td {
border-bottom: 1px $ibo-color-grey-400 solid;
}
.wizContainer table tr.ibo-csv-import--row-error td {
border-bottom: 1px $ibo-color-grey-400 solid;
background-color: $ibo-color-red-200;
}
tr.ibo-csv-import--row-modified td {
border-bottom: 1px $ibo-color-grey-400 solid;
}
@@ -39,4 +44,4 @@ tr.ibo-csv-import--row-added td {
font-size: 4em;
color: $ibo-color-primary-400;
margin: 20px;
}
}

View File

@@ -7,16 +7,6 @@
*
* Other modification done : replaced the `Alpha(` by `alpha(` to avoid warnings generated by SCSSPHP
*/
/********************************************************************************/
/* */
/* @deprecated 3.0.0 N°3558 now we are using /css/backoffice/vendors/_jquery* */
/* */
/********************************************************************************/
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;

View File

@@ -1,10 +0,0 @@
{
"config" : {
"classmap-authoritative" : true
},
"autoload" : {
"psr-4" : {
"Combodo\\iTop\\Cas\\" : "src"
}
}
}

View File

@@ -1,18 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d751713988987e9331980363e24189ce",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
}

View File

@@ -0,0 +1,3 @@
<?php
require_once __DIR__.'/src/Config.php';
require_once __DIR__.'/src/CASLoginExtension.php';

View File

@@ -24,8 +24,7 @@ SetupWebPage::AddModule(
//
'datamodel' => array(
'model.authent-cas.php',
'vendor/autoload.php',
'src/CASLoginExtension.php',
'main.php'
),
'webservice' => array(
@@ -51,7 +50,6 @@ SetupWebPage::AddModule(
'cas_port' => '',
'cas_context' => '',
'cas_version' => '',
'service_base_url' => '',
),
)
);

View File

@@ -1,17 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Cas;
use LogAPI;
class CASLog extends LogAPI
{
const CHANNEL_DEFAULT = 'CASLog';
protected static $m_oFileLog = null;
}

View File

@@ -1,81 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2022 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\Cas;
use IssueLog;
use LogAPI;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
class CASLogger implements LoggerInterface
{
public function __construct($sDebugFile)
{
CASLog::Enable($sDebugFile);
}
const LEVEL_COMPAT = [
LogLevel::EMERGENCY => LogAPI::LEVEL_ERROR,
LogLevel::ALERT => LogAPI::LEVEL_ERROR,
LogLevel::CRITICAL => LogAPI::LEVEL_ERROR,
LogLevel::ERROR => LogAPI::LEVEL_ERROR,
LogLevel::WARNING => LogAPI::LEVEL_WARNING,
LogLevel::NOTICE => LogAPI::LEVEL_INFO,
LogLevel::INFO => LogAPI::LEVEL_INFO,
LogLevel::DEBUG => LogAPI::LEVEL_DEBUG,
];
public function emergency($message, array $context = array())
{
CASLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context);
IssueLog::Error('EMERGENCY: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function alert($message, array $context = array())
{
CASLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context);
IssueLog::Error('ALERT: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function critical($message, array $context = array())
{
CASLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context);
IssueLog::Error('CRITICAL: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function error($message, array $context = array())
{
CASLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context);
IssueLog::Error('ERROR: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function warning($message, array $context = array())
{
CASLog::Warning('WARNING: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function notice($message, array $context = array())
{
CASLog::Info('NOTICE: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function info($message, array $context = array())
{
CASLog::Info('INFO: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function debug($message, array $context = array())
{
CASLog::Debug('DEBUG: '.$message, CASLog::CHANNEL_DEFAULT, $context);
}
public function log($level, $message, array $context = array())
{
$sLevel = self::LEVEL_COMPAT[$level] ?? LogAPI::LEVEL_ERROR;
CASLog::Log($sLevel, strtoupper($level).": $message", CASLog::CHANNEL_DEFAULT, $context);
}
}

View File

@@ -153,7 +153,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
$bCASDebug = Config::Get('cas_debug');
if ($bCASDebug)
{
phpCAS::setLogger(new CASLogger(APPROOT.'log/cas.log'));
phpCAS::setDebug(APPROOT.'log/cas.log');
}
// Initialize phpCAS
@@ -161,8 +161,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
$sCASHost = Config::Get('cas_host');
$iCASPort = Config::Get('cas_port');
$sCASContext = Config::Get('cas_context');
$sServiceBaseURL = Config::Get('service_base_url', self::GetServiceBaseURL());
phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, $sServiceBaseURL, false /* session already started */);
phpCAS::client($sCASVersion, $sCASHost, $iCASPort, $sCASContext, false /* session already started */);
$sCASCACertPath = Config::Get('cas_server_ca_cert_path');
if (empty($sCASCACertPath))
{
@@ -178,38 +177,6 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
}
}
private static function GetServiceBaseURL()
{
$protocol = $_SERVER['REQUEST_SCHEME'];
$protocol .= '://';
if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
// explode the host list separated by comma and use the first host
$hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
// see rfc7239#5.3 and rfc7230#2.7.1: port is in HTTP_X_FORWARDED_HOST if non default
return $protocol . $hosts[0];
} else if (!empty($_SERVER['HTTP_X_FORWARDED_SERVER'])) {
$server_url = $_SERVER['HTTP_X_FORWARDED_SERVER'];
} else {
if (empty($_SERVER['SERVER_NAME'])) {
$server_url = $_SERVER['HTTP_HOST'];
} else {
$server_url = $_SERVER['SERVER_NAME'];
}
}
if (!strpos($server_url, ':')) {
if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) {
$server_port = $_SERVER['SERVER_PORT'];
} else {
$ports = explode(',', $_SERVER['HTTP_X_FORWARDED_PORT']);
$server_port = $ports[0];
}
$server_url .= ':';
$server_url .= $server_port;
}
return $protocol . $server_url;
}
private function DoUserProvisioning($sLogin)
{
$bCASUserSynchro = Config::Get('cas_user_synchro');

View File

@@ -1,7 +0,0 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0::getLoader();

View File

@@ -1,572 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-var array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
* @private
*/
function includeFile($file)
{
include $file;
}

View File

@@ -1,337 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*/
class InstalledVersions
{
private static $installed;
private static $canGetVendors;
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
$installed[] = self::$installed;
return $installed;
}
}

View File

@@ -1,21 +0,0 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,14 +0,0 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Combodo\\iTop\\Cas\\CASLog' => $baseDir . '/src/CASLog.php',
'Combodo\\iTop\\Cas\\CASLogger' => $baseDir . '/src/CASLogger.php',
'Combodo\\iTop\\Cas\\CASLoginExtension' => $baseDir . '/src/CASLoginExtension.php',
'Combodo\\iTop\\Cas\\Config' => $baseDir . '/src/Config.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
);

View File

@@ -1,9 +0,0 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@@ -1,10 +0,0 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Combodo\\iTop\\Cas\\' => array($baseDir . '/src'),
);

View File

@@ -1,46 +0,0 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInit1878ad96115c3aa0fa5e9fd9807f5db0', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->setClassMapAuthoritative(true);
$loader->register(true);
return $loader;
}
}

View File

@@ -1,40 +0,0 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0
{
public static $prefixLengthsPsr4 = array (
'C' =>
array (
'Combodo\\iTop\\Cas\\' => 17,
),
);
public static $prefixDirsPsr4 = array (
'Combodo\\iTop\\Cas\\' =>
array (
0 => __DIR__ . '/../..' . '/src',
),
);
public static $classMap = array (
'Combodo\\iTop\\Cas\\CASLog' => __DIR__ . '/../..' . '/src/CASLog.php',
'Combodo\\iTop\\Cas\\CASLogger' => __DIR__ . '/../..' . '/src/CASLogger.php',
'Combodo\\iTop\\Cas\\CASLoginExtension' => __DIR__ . '/../..' . '/src/CASLoginExtension.php',
'Combodo\\iTop\\Cas\\Config' => __DIR__ . '/../..' . '/src/Config.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1878ad96115c3aa0fa5e9fd9807f5db0::$classMap;
}, null, ClassLoader::class);
}
}

View File

@@ -1,5 +0,0 @@
{
"packages": [],
"dev": true,
"dev-package-names": []
}

View File

@@ -1,23 +0,0 @@
<?php return array(
'root' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '5a1627632aa2e605996c1c556c60c2a2cddc0a05',
'name' => '__root__',
'dev' => true,
),
'versions' => array(
'__root__' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '5a1627632aa2e605996c1c556c60c2a2cddc0a05',
'dev_requirement' => false,
),
),
);

View File

@@ -1,51 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<classes>
<class id="UserLDAP" _delta="define">
<parent>cmdbAbstractObject</parent>
<php_parent>
<name>UserInternal</name>
</php_parent>
<properties>
<comment>/**
<classes>
<class id="UserLDAP" _delta="define">
<parent>cmdbAbstractObject</parent>
<php_parent>
<name>UserInternal</name>
</php_parent>
<properties>
<comment>/**
* LDAP Authentication
* User authentication Module, no password at all!
*
* @copyright Copyright (C) 2010-2020 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/</comment>
<category>addon/authentication,grant_by_profile,silo</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_user_ldap</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<format>%1$s</format>
<attributes>
<attribute id="login"/>
</attributes>
</naming>
<display_template/>
<style>
<icon/>
</style>
<reconciliation>
<attributes>
<attribute id="login"/>
</attributes>
</reconciliation>
</properties>
<fields>
<field id="ldap_server" xsi:type="AttributeString">
<sql>ldap_server</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
</fields>
<methods>
<method id="CheckCredentials">
<comment><![CDATA[/**
<category>addon/authentication,grant_by_profile,silo</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_user_ldap</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<format>%1$s</format>
<attributes>
<attribute id="login"/>
</attributes>
</naming>
<display_template/>
<style>
<icon/>
</style>
<reconciliation>
<attributes>
<attribute id="login"/>
</attributes>
</reconciliation>
</properties>
<fields>
<field id="ldap_server" xsi:type="AttributeString">
<sql>ldap_server</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
</fields>
<methods>
<method id="CheckCredentials">
<comment><![CDATA[/**
* Check the user's password against the LDAP server
* Algorithm:
* 1) Connect to the LDAP server, using a predefined account (or anonymously)
@@ -60,10 +60,10 @@
* @throws \ArchivedObjectException
* @throws \CoreException
*/]]></comment>
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code><![CDATA[ public function CheckCredentials($sPassword)
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code><![CDATA[ public function CheckCredentials($sPassword)
{
$sServer = $this->Get('ldap_server');
if (empty($sServer))
@@ -190,39 +190,39 @@
return false;
}
}]]></code>
</method>
<method id="TrustWebServerContext">
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code> public function TrustWebServerContext()
</method>
<method id="TrustWebServerContext">
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code> public function TrustWebServerContext()
{
return false;
}</code>
</method>
<method id="CanChangePassword">
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code> public function CanChangePassword()
</method>
<method id="CanChangePassword">
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code> public function CanChangePassword()
{
return false;
}</code>
</method>
<method id="ChangePassword">
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code> public function ChangePassword($sOldPassword, $sNewPassword)
</method>
<method id="ChangePassword">
<static>false</static>
<access>public</access>
<type>OQLMenuNode</type>
<code> public function ChangePassword($sOldPassword, $sNewPassword)
{
return false;
}</code>
</method>
<method id="LogIssue">
<static>false</static>
<access>protected</access>
<type>OQLMenuNode</type>
<code><![CDATA[ protected function LogIssue($bDebug, $sMessage, $aData = array())
</method>
<method id="LogIssue">
<static>false</static>
<access>protected</access>
<type>OQLMenuNode</type>
<code><![CDATA[ protected function LogIssue($bDebug, $sMessage, $aData = array())
{
if ($bDebug)
{
@@ -240,91 +240,91 @@
}
IssueLog::Error($sMessage);
}]]></code>
</method>
<method id="LogInfo">
<static>false</static>
<access>protected</access>
<type>OQLMenuNode</type>
<code><![CDATA[ protected function LogInfo($bDebug, $sMessage)
</method>
<method id="LogInfo">
<static>false</static>
<access>protected</access>
<type>OQLMenuNode</type>
<code><![CDATA[ protected function LogInfo($bDebug, $sMessage)
{
if ($bDebug)
{
IssueLog::Info($sMessage);
}
}]]></code>
</method>
</methods>
<presentation>
<details>
<items>
<item id="contactid">
<rank>10</rank>
</item>
<item id="org_id">
<rank>20</rank>
</item>
<item id="email">
<rank>30</rank>
</item>
<item id="login">
<rank>40</rank>
</item>
<item id="language">
<rank>50</rank>
</item>
<item id="status">
<rank>60</rank>
</item>
<item id="profile_list">
<rank>70</rank>
</item>
<item id="allowed_org_list">
<rank>80</rank>
</item>
<item id="ldap_server">
<rank>90</rank>
</item>
</items>
</details>
<search>
<items>
<item id="login">
<rank>10</rank>
</item>
<item id="contactid">
<rank>20</rank>
</item>
<item id="status">
<rank>30</rank>
</item>
<item id="org_id">
<rank>40</rank>
</item>
<item id="ldap_server">
<rank>50</rank>
</item>
</items>
</search>
<list>
<items>
<item id="first_name">
<rank>10</rank>
</item>
<item id="last_name">
<rank>20</rank>
</item>
<item id="status">
<rank>30</rank>
</item>
<item id="org_id">
<rank>40</rank>
</item>
<item id="ldap_server">
<rank>50</rank>
</item>
</items>
</list>
</presentation>
</class>
</classes>
</method>
</methods>
<presentation>
<details>
<items>
<item id="contactid">
<rank>10</rank>
</item>
<item id="org_id">
<rank>20</rank>
</item>
<item id="email">
<rank>30</rank>
</item>
<item id="login">
<rank>40</rank>
</item>
<item id="language">
<rank>50</rank>
</item>
<item id="status">
<rank>60</rank>
</item>
<item id="profile_list">
<rank>70</rank>
</item>
<item id="allowed_org_list">
<rank>80</rank>
</item>
<item id="ldap_server">
<rank>90</rank>
</item>
</items>
</details>
<search>
<items>
<item id="login">
<rank>10</rank>
</item>
<item id="contactid">
<rank>20</rank>
</item>
<item id="status">
<rank>30</rank>
</item>
<item id="org_id">
<rank>40</rank>
</item>
<item id="ldap_server">
<rank>50</rank>
</item>
</items>
</search>
<list>
<items>
<item id="first_name">
<rank>10</rank>
</item>
<item id="last_name">
<rank>20</rank>
</item>
<item id="status">
<rank>30</rank>
</item>
<item id="org_id">
<rank>40</rank>
</item>
<item id="ldap_server">
<rank>50</rank>
</item>
</items>
</list>
</presentation>
</class>
</classes>
</itop_design>

View File

@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<module_parameters>
<parameters id="authent-local" _delta="define">
<password_validation.pattern>^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,}$</password_validation.pattern>
<password_validation.message type="hash"/>
</parameters>
</module_parameters>
<module_parameters>
<parameters id="authent-local" _delta="define">
<password_validation.pattern>^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,}$</password_validation.pattern>
<password_validation.message type="hash"></password_validation.message>
</parameters>
</module_parameters>
</itop_design>

View File

@@ -46,13 +46,13 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'Class:UserLocal/Attribute:expiration/Value:never_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:force_expire' => 'Wygasło',
'Class:UserLocal/Attribute:expiration/Value:force_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:otp_expire' => 'Jednorazowe hasło',
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => 'Hasło nie może być zmienione przez użytkownika.',
'Class:UserLocal/Attribute:expiration/Value:otp_expire' => 'One-time Password~~',
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => 'Password cannot be changed by the user.~~',
'Class:UserLocal/Attribute:password_renewed_date' => 'Odnowienie hasła',
'Class:UserLocal/Attribute:password_renewed_date+' => 'Kiedy ostatnio zmieniano hasło',
'Error:UserLocalPasswordValidator:UserPasswordPolicyRegex:ValidationFailed' => 'Hasło musi mieć co najmniej 8 znaków i zawierać duże, małe litery, cyfry i znaki specjalne.',
'UserLocal:password:expiration' => 'Poniższe pola wymagają rozszerzenia',
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => 'Ustawienie wygaśnięcia hasła "Hasło jednorazowe" nie jest dozwolone dla własnego użytkownika',
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => 'Setting password expiration to "One-time password" is not allowed for your own User~~',
));

File diff suppressed because one or more lines are too long

View File

@@ -27,8 +27,8 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'DBTools:Class' => 'Klasa',
'DBTools:Title' => 'Narzędzia do konserwacji bazy danych',
'DBTools:ErrorsFound' => 'Znalezione błędy',
'DBTools:Indication' => 'Ważne: po naprawieniu błędów w bazie danych będziesz musiał ponownie uruchomić analizę, ponieważ będą generowane nowe niespójności',
'DBTools:Disclaimer' => 'OŚWIADCZENIE: PRZED URUCHOMIENIEM POPRAWEK NALEŻY WYKONAĆ KOPIĘ ZAPASOWĄ BAZY DANYCH',
'DBTools:Indication' => 'Important: after fixing errors in the database you\'ll have to run the analysis again as new inconsistencies will be generated~~',
'DBTools:Disclaimer' => 'DISCLAIMER: BACKUP YOUR DATABASE BEFORE RUNNING THE FIXES~~',
'DBTools:Error' => 'Błąd',
'DBTools:Count' => 'Liczba',
'DBTools:SQLquery' => 'Zapytanie SQL',
@@ -40,21 +40,21 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'DBTools:ShowReport' => 'Raport',
'DBTools:IntegrityCheck' => 'Sprawdzanie integralności',
'DBTools:FetchCheck' => 'Sprawdzenie przestrzeni (długie)',
'DBTools:SelectAnalysisType' => 'Wybierz typ analizy',
'DBTools:SelectAnalysisType' => 'Select analysis type~~',
'DBTools:Analyze' => 'Analiza',
'DBTools:Details' => 'Pokaż szczegóły',
'DBTools:ShowAll' => 'Pokaż wszystkie błędy',
'DBTools:Inconsistencies' => 'Niespójności bazy danych',
'DBTools:DetailedErrorTitle' => '%2$s błąd(y) w klasie %1$s: %3$s',
'DBTools:DetailedErrorTitle' => '%2$s error(s) in class %1$s: %3$s~~',
'DBAnalyzer-Integrity-OrphanRecord' => 'Osierocony rekord w `%1$s`, powinien mieć swój odpowiednik w tabeli `%2$s`',
'DBAnalyzer-Integrity-InvalidExtKey' => 'Nieprawidłowy klucz zewnętrzny %1$s (kolumna: `%2$s.%3$s`)',
'DBAnalyzer-Integrity-MissingExtKey' => 'Brak klucza zewnętrznego %1$s (kolumna: `%2$s.%3$s`)',
'DBAnalyzer-Integrity-InvalidValue' => 'Nieprawidłowa wartość dla %1$s (kolumna: `%2$s.%3$s`)',
'DBAnalyzer-Integrity-UsersWithoutProfile' => 'Niektóre konta użytkowników w ogóle nie mają profilu',
'DBAnalyzer-Integrity-HKInvalid' => 'Nieprawidłowy klucz hierarchiczny `%1$s`',
'DBAnalyzer-Integrity-HKInvalid' => 'Broken hierarchical key `%1$s`~~',
'DBAnalyzer-Fetch-Count-Error' => 'Błąd liczby wpisów w `%1$s`, %2$d pobrane wpisy / %3$d obliczone',
'DBAnalyzer-Integrity-FinalClass' => 'Pole `%2$s`.`%1$s` musi mieć taką samą wartość jak `%3$s`.`%1$s`',
'DBAnalyzer-Integrity-RootFinalClass' => 'Pole `%2$s`.`%1$s` musi zawierać prawidłową klasę',

View File

@@ -14,22 +14,6 @@ use DBObjectSet;
class DBToolsUtils
{
private static bool $bAnalyzed = false;
private static function AnalyzeTables()
{
if (self::$bAnalyzed) {
return;
}
$oResult = CMDBSource::Query('SHOW TABLES;');
while ($aRow = $oResult->fetch_array()) {
$sTable = $aRow['0'];
CMDBSource::Query("ANALYZE TABLE `$sTable`; ");
}
self::$bAnalyzed = true;
}
/**
* @return int
* @throws \CoreException
@@ -38,7 +22,6 @@ class DBToolsUtils
*/
public final static function GetDatabaseSize()
{
self::AnalyzeTables();
$sSchema = CMDBSource::DBName();
$sReq = <<<EOF
@@ -65,7 +48,6 @@ EOF;
*/
public final static function GetDBDataSize()
{
self::AnalyzeTables();
$sSchema = CMDBSource::DBName();
$sReq = <<<EOF
@@ -92,7 +74,6 @@ EOF;
*/
public final static function GetDBIndexSize()
{
self::AnalyzeTables();
$sSchema = CMDBSource::DBName();
$sReq = <<<EOF
@@ -146,7 +127,6 @@ EOF;
public static function GetDBTablesInfo()
{
self::AnalyzeTables();
$sSchema = CMDBSource::DBName();
$sReq = <<<EOF

View File

@@ -55,51 +55,51 @@
</indexes>
</properties>
<fields>
<field id="expire" xsi:type="AttributeDateTime">
<sql>expire</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="temp_id" xsi:type="AttributeString">
<sql>temp_id</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="item_class" xsi:type="AttributeString">
<sql>item_class</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="item_id" xsi:type="AttributeObjectKey">
<sql>item_id</sql>
<is_null_allowed>true</is_null_allowed>
<class_attcode>item_class</class_attcode>
</field>
<field id="item_org_id" xsi:type="AttributeInteger">
<sql>item_org_id</sql>
<default_value>0</default_value>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="contents" xsi:type="AttributeBlob"/>
<field id="creation_date" xsi:type="AttributeDateTime">
<sql>creation_date</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="user_id" xsi:type="AttributeExternalKey">
<sql>user_id</sql>
<is_null_allowed>true</is_null_allowed>
<on_target_delete>DEL_MANUAL</on_target_delete>
<target_class>User</target_class>
<allow_target_creation>false</allow_target_creation>
</field>
<field id="contact_id" xsi:type="AttributeExternalField">
<extkey_attcode>user_id</extkey_attcode>
<target_attcode>contactid</target_attcode>
<dependencies>
<attribute id="user_id"/>
</dependencies>
</field>
<field id="expire" xsi:type="AttributeDateTime">
<sql>expire</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="temp_id" xsi:type="AttributeString">
<sql>temp_id</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="item_class" xsi:type="AttributeString">
<sql>item_class</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="item_id" xsi:type="AttributeObjectKey">
<sql>item_id</sql>
<is_null_allowed>true</is_null_allowed>
<class_attcode>item_class</class_attcode>
</field>
<field id="item_org_id" xsi:type="AttributeInteger">
<sql>item_org_id</sql>
<default_value>0</default_value>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="contents" xsi:type="AttributeBlob"/>
<field id="creation_date" xsi:type="AttributeDateTime">
<sql>creation_date</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="user_id" xsi:type="AttributeExternalKey">
<sql>user_id</sql>
<is_null_allowed>true</is_null_allowed>
<on_target_delete>DEL_MANUAL</on_target_delete>
<target_class>User</target_class>
<allow_target_creation>false</allow_target_creation>
</field>
<field id="contact_id" xsi:type="AttributeExternalField">
<extkey_attcode>user_id</extkey_attcode>
<target_attcode>contactid</target_attcode>
<dependencies>
<attribute id="user_id"></attribute>
</dependencies>
</field>
</fields>
<methods>
<method id="MapContextParam">
@@ -236,69 +236,23 @@
</item>
</items>
</search>
<list>
<items>
<item id="temp_id">
<rank>10</rank>
</item>
<item id="item_class">
<rank>20</rank>
</item>
<item id="item_id">
<rank>30</rank>
</item>
<item id="creation_date">
<rank>40</rank>
</item>
</items>
</list>
<list>
<items>
<item id="temp_id">
<rank>10</rank>
</item>
<item id="item_class">
<rank>20</rank>
</item>
<item id="item_id">
<rank>30</rank>
</item>
<item id="creation_date">
<rank>40</rank>
</item>
</items>
</list>
</presentation>
</class>
</classes>
<events>
<event id="EVENT_SERVICE_ADD_ATTACHMENT_TO_OBJECT" _delta="define">
<description>An attachment has been added to an object</description>
<replaces>Attachment::AfterUpdate</replaces>
<sources>
<source id="Attachment">Attachment</source>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The attachment updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="target_object">
<description>The object to which the attachment is linked</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_REMOVE_ATTACHMENT_FROM_OBJECT" _delta="define">
<description>An attachment has been removed from an object</description>
<replaces>Attachment::AfterUpdate</replaces>
<sources>
<source id="Attachment">Attachment</source>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The attachment updated</description>
<type>DBObject</type>
</event_datum>
<event_datum id="target_object">
<description>The object to which the attachment is linked</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
</events>
</itop_design>

View File

@@ -304,8 +304,6 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
// Remove attachments that are no longer attached to the current object
if (in_array($oAttachment->GetKey(), $aRemovedAttachmentIds))
{
$aData = ['target_object' => $oObject];
$oAttachment->FireEvent(EVENT_SERVICE_REMOVE_ATTACHMENT_FROM_OBJECT, $aData);
$oAttachment->DBDelete();
$aActions[] = self::GetActionChangeOp($oAttachment, false /* false => deletion */);
}
@@ -334,8 +332,6 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
$oAttachment->DBUpdate();
// temporary attachment confirmed, list it in the history
$aActions[] = self::GetActionChangeOp($oAttachment, true /* true => creation */);
$aData = ['target_object' => $oObject];
$oAttachment->FireEvent(EVENT_SERVICE_ADD_ATTACHMENT_TO_OBJECT, $aData);
}
}
}

View File

@@ -20,7 +20,6 @@ auth_user = admin
auth_pwd = admin
# Target file - path and filename (optional)
# Full path or relative to current directory
#
# Formatting rules:
# %Y-%m-%d => 2011-01-25... see PHP documentation of strftime()
@@ -41,7 +40,8 @@ check_size_reduction_max = 10 # percentage
# If the backup has failed, a ticket will be created
# This process relies on the SOAP service "CreateIncident"
#
itop_backup_incident = http://destination-itop.demo.com # Root URL of an instance of iTop into which the ticket will be created
# Root URL of an instance of iTop, into which the ticket will be created : config file param 'itop_backup_incident'
# Any of the above paramaters are mandatory
check_ticket_login = admin # must have the right to create an Incident Ticket
check_ticket_pwd = admin
check_ticket_title = Backup check failed
@@ -49,4 +49,4 @@ check_ticket_customer = Demo
check_ticket_service = Computers and peripherals
check_ticket_service_subcategory = Repair
check_ticket_workgroup = Hardware support
check_ticket_impacted_server = source-itop.demo.com # identifier for the iTop instance we tried to backup
check_ticket_impacted_server = dbserver1.demo.com

View File

@@ -49,7 +49,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'bkp-status-backups-manual' => 'Ręczne kopie zapasowe',
'bkp-status-backups-none' => 'Nie ma jeszcze kopii zapasowej',
'bkp-next-backup' => 'Następna kopia zapasowa zostanie utworzona <b>%1$s</b> (%2$s) w %3$s',
'bkp-next-backup-unknown' => 'Następna kopia zapasowa <b>nie jest zaplanowana</b>.',
'bkp-next-backup-unknown' => 'The next backup is <b>not scheduled</b> yet.~~',
'bkp-button-backup-now' => 'Utwórz kopię teraz!',
'bkp-button-restore-now' => 'Przywróć!',
'bkp-confirm-backup' => 'Potwierdź, że chcesz teraz wykonać kopię zapasową.',

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<constants/>
<constants></constants>
<classes>
<class id="lnkFunctionalCIToTicket" _delta="define">
<parent>cmdbAbstractObject</parent>
@@ -292,7 +292,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>
@@ -301,7 +300,6 @@
<count_max>0</count_max>
<ext_key_to_remote>service_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
<field id="tickets_list" xsi:type="AttributeLinkedSetIndirect" _delta="define">
<linked_class>lnkFunctionalCIToTicket</linked_class>
@@ -310,7 +308,6 @@
<count_max>0</count_max>
<ext_key_to_remote>ticket_id</ext_key_to_remote>
<duplicates/>
<read_only>false</read_only>
</field>
</fields>
<presentation>

View File

@@ -31,24 +31,24 @@
// Class: lnkFunctionalCIToTicket
//
Dict::Add('PL PL', 'Polish', 'Polski', array(
'Class:lnkFunctionalCIToTicket' => 'Połączenie Konfiguracja / Zgłoszenie',
'Class:lnkFunctionalCIToTicket+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Zgłoszenie',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Adnotacja',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_title' => 'Tytuł zgłoszenia',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_title+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id' => 'Konfiguracja',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name' => 'Nazwa konfiguracji',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:impact' => 'Dotyczy (tekst)',
'Class:lnkFunctionalCIToTicket/Attribute:impact+' => '',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code' => 'Dotyczy',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:manual' => 'Dodane ręcznie',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:computed' => 'Obliczone',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:not_impacted' => 'Nie dotyczy',
'Class:lnkFunctionalCIToTicket' => 'Link FunctionalCI / Ticket~~',
'Class:lnkFunctionalCIToTicket+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id' => 'Ticket~~',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_id+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref' => 'Ref~~',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_ref+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_title' => 'Ticket title~~',
'Class:lnkFunctionalCIToTicket/Attribute:ticket_title+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id' => 'CI~~',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_id+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name' => 'CI Name~~',
'Class:lnkFunctionalCIToTicket/Attribute:functionalci_name+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:impact' => 'Impact (text)~~',
'Class:lnkFunctionalCIToTicket/Attribute:impact+' => '~~',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code' => 'Impact~~',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:manual' => 'Added manually~~',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:computed' => 'Computed~~',
'Class:lnkFunctionalCIToTicket/Attribute:impact_code/Value:not_impacted' => 'Not impacted~~',
));
//
@@ -73,16 +73,16 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
//
Dict::Add('PL PL', 'Polish', 'Polski', array(
'Class:lnkFunctionalCIToService' => 'Połączenie Konfiguracja / Usługa',
'Class:lnkFunctionalCIToService+' => '',
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Usługa',
'Class:lnkFunctionalCIToService/Attribute:service_id+' => '',
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Nazwa usługi',
'Class:lnkFunctionalCIToService/Attribute:service_name+' => '',
'Class:lnkFunctionalCIToService/Attribute:functionalci_id' => 'Konfiguracja',
'Class:lnkFunctionalCIToService/Attribute:functionalci_id+' => '',
'Class:lnkFunctionalCIToService/Attribute:functionalci_name' => 'Nazwa konfiguracji',
'Class:lnkFunctionalCIToService/Attribute:functionalci_name+' => '',
'Class:lnkFunctionalCIToService' => 'Link FunctionalCI / Service~~',
'Class:lnkFunctionalCIToService+' => '~~',
'Class:lnkFunctionalCIToService/Attribute:service_id' => 'Service~~',
'Class:lnkFunctionalCIToService/Attribute:service_id+' => '~~',
'Class:lnkFunctionalCIToService/Attribute:service_name' => 'Service Name~~',
'Class:lnkFunctionalCIToService/Attribute:service_name+' => '~~',
'Class:lnkFunctionalCIToService/Attribute:functionalci_id' => 'CI~~',
'Class:lnkFunctionalCIToService/Attribute:functionalci_id+' => '~~',
'Class:lnkFunctionalCIToService/Attribute:functionalci_name' => 'CI Name~~',
'Class:lnkFunctionalCIToService/Attribute:functionalci_name+' => '~~',
));
//
@@ -90,10 +90,10 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
//
Dict::Add('PL PL', 'Polish', 'Polski', array(
'Class:FunctionalCI/Attribute:providercontracts_list' => 'Umowy z dostawcami',
'Class:FunctionalCI/Attribute:providercontracts_list+' => 'Wszystkie umowy dostawcy dla tej konfiguracji',
'Class:FunctionalCI/Attribute:services_list' => 'Usługi',
'Class:FunctionalCI/Attribute:services_list+' => 'Wszystkie usługi, na które ma wpływ tą konfigurację',
'Class:FunctionalCI/Attribute:tickets_list' => 'Zgłoszenia',
'Class:FunctionalCI/Attribute:tickets_list+' => 'Wszystkie zgłoszenia dla tej konfiguracji',
'Class:FunctionalCI/Attribute:providercontracts_list' => 'Provider contracts~~',
'Class:FunctionalCI/Attribute:providercontracts_list+' => 'All the provider contracts for this configuration item~~',
'Class:FunctionalCI/Attribute:services_list' => 'Services~~',
'Class:FunctionalCI/Attribute:services_list+' => 'All the services impacted by this configuration item~~',
'Class:FunctionalCI/Attribute:tickets_list' => 'Tickets~~',
'Class:FunctionalCI/Attribute:tickets_list+' => 'All the tickets for this configuration item~~',
));

View File

@@ -44,11 +44,19 @@
<values>
<value id="approved">approved
<code>approved</code>
<style><main_color>$ibo-lifecycle-success-state-primary-color</main_color><complementary_color>$ibo-lifecycle-success-state-secondary-color</complementary_color><decoration_classes>fas fa-user-check</decoration_classes></style>
<style>
<main_color>$ibo-lifecycle-success-state-primary-color</main_color>
<complementary_color>$ibo-lifecycle-success-state-secondary-color</complementary_color>
<decoration_classes>fas fa-user-check</decoration_classes>
</style>
</value>
<value id="assigned">assigned
<code>assigned</code>
<style><main_color>$ibo-lifecycle-neutral-state-primary-color</main_color><complementary_color>$ibo-lifecycle-neutral-state-secondary-color</complementary_color><decoration_classes/></style>
<style>
<main_color>$ibo-lifecycle-neutral-state-primary-color</main_color>
<complementary_color>$ibo-lifecycle-neutral-state-secondary-color</complementary_color>
<decoration_classes/>
</style>
</value>
<value id="closed">
<code>closed</code>
@@ -239,39 +247,31 @@
<field id="related_request_list" xsi:type="AttributeLinkedSet">
<linked_class>UserRequest</linked_class>
<ext_key_to_me>parent_change_id</ext_key_to_me>
<legacy_edit_mode>add_remove</legacy_edit_mode>
<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>
<ext_key_to_me>parent_change_id</ext_key_to_me>
<legacy_edit_mode>add_remove</legacy_edit_mode>
<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>
<ext_key_to_me>related_change_id</ext_key_to_me>
<legacy_edit_mode>add_remove</legacy_edit_mode>
<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>
<ext_key_to_me>parent_id</ext_key_to_me>
<legacy_edit_mode>add_remove</legacy_edit_mode>
<edit_mode>add_remove</edit_mode>
<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>
@@ -279,17 +279,17 @@
<item id="approved">
<rank>1</rank>
<color>HIGHLIGHT_CLASS_NONE</color>
<icon>images/change-approved.svg</icon>
<icon>images/change-approved.svg</icon>
</item>
<item id="rejected">
<rank>2</rank>
<color>HIGHLIGHT_CLASS_NONE</color>
<icon>images/change-rejected.svg</icon>
<icon>images/change-rejected.svg</icon>
</item>
<item id="closed">
<rank>3</rank>
<color>HIGHLIGHT_CLASS_NONE</color>
<icon>images/change-closed.svg</icon>
<icon>images/change-closed.svg</icon>
</item>
</highlight_scale>
<stimuli>
@@ -976,17 +976,17 @@
</states>
</lifecycle>
<methods>
<method id="GetTicketRefFormat">
<static>true</static>
<access>public</access>
<type>Overload-DBObject</type>
<code><![CDATA[
<method id="GetTicketRefFormat">
<static>true</static>
<access>public</access>
<type>Overload-DBObject</type>
<code><![CDATA[
public static function GetTicketRefFormat()
{
return 'C-%06d';
}
]]></code>
</method>
</method>
<method id="SetClosureDate">
<comment><![CDATA[/**
* To be deprecated: use SetCurrentDate() instead
@@ -1026,7 +1026,8 @@
$this->UpdateImpactedItems();
$this->SetIfNull('creation_date', time());
$this->SetIfNull('last_update', time());
}]]></code>
}]]>
</code>
</method>
<method id="OnUpdate">
<static>false</static>
@@ -1042,7 +1043,8 @@
$this->UpdateImpactedItems();
}
$this->Set('last_update', time());
}]]></code>
}]]>
</code>
</method>
</methods>
<presentation>
@@ -4532,9 +4534,9 @@
<menus>
<menu id="ChangeManagement" xsi:type="MenuGroup" _delta="define">
<rank>50</rank>
<style>
<decoration_classes>fas fa-exchange-alt</decoration_classes>
</style>
<style>
<decoration_classes>fas fa-exchange-alt</decoration_classes>
</style>
</menu>
<menu id="Change:Overview" xsi:type="DashboardMenuNode" _delta="define">
<rank>0</rank>
@@ -4657,7 +4659,7 @@
AND (C.id != :this->id)
]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[
@@ -4672,7 +4674,7 @@
AND (C.end_date < NOW() AND C.end_date > DATE_SUB(NOW(), INTERVAL 3 DAY ))
]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
</item>
</items>
</down>
@@ -4694,7 +4696,7 @@
AND (C.id != :this->id)
]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[
@@ -4709,7 +4711,7 @@
AND (C.end_date < NOW() AND C.end_date > DATE_SUB(NOW(), INTERVAL 3 DAY ))
]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
</item>
</items>
</down>
@@ -4731,7 +4733,7 @@
AND (C.id != :this->id)
]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[
@@ -4746,7 +4748,7 @@
AND (C.end_date < NOW() AND C.end_date > DATE_SUB(NOW(), INTERVAL 3 DAY ))
]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
</item>
</items>
</down>
@@ -4771,7 +4773,7 @@
AND (L.impact_code != 'not_impacted')
]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[
@@ -4785,7 +4787,7 @@
AND (C.end_date < NOW() AND C.end_date > DATE_SUB(NOW(), INTERVAL 3 DAY ))
]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
</item>
</items>
</down>
@@ -4802,7 +4804,7 @@
AND (L.impact_code != 'not_impacted')
]]></oql>
<dict>Tickets:Related:OpenChanges</dict>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
<icon>itop-change-mgmt-itil/images/change-ongoing.png</icon>
</item>
<item id="recent_changes" _delta="define">
<oql><![CDATA[
@@ -4816,7 +4818,7 @@
AND (C.end_date < NOW() AND C.end_date > DATE_SUB(NOW(), INTERVAL 3 DAY ))
]]></oql>
<dict>Tickets:Related:RecentChanges</dict>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
<icon>itop-change-mgmt-itil/images/change-done.png</icon>
</item>
</items>
</up>

View File

@@ -95,7 +95,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'Class:Change/Attribute:requestor_email+' => '',
'Class:Change/Attribute:creation_date' => 'Data utworzenia',
'Class:Change/Attribute:creation_date+' => '',
'Class:Change/Attribute:impact' => 'Dotyczy',
'Class:Change/Attribute:impact' => 'Wpływ',
'Class:Change/Attribute:impact+' => '',
'Class:Change/Attribute:supervisor_group_id' => 'Zespół nadzorujący',
'Class:Change/Attribute:supervisor_group_id+' => '',

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -528,7 +528,7 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:SoftwareInstance' => 'Software Instance',
'Class:SoftwareInstance+' => '',
'Class:SoftwareInstance/Attribute:system_id' => 'System',
'Class:SoftwareInstance/Attribute:system_id+' => 'The system can be a Server, a Virtual Machine, a PC, ...',
'Class:SoftwareInstance/Attribute:system_id+' => '',
'Class:SoftwareInstance/Attribute:system_name' => 'System name',
'Class:SoftwareInstance/Attribute:system_name+' => '',
'Class:SoftwareInstance/Attribute:software_id' => 'Software',

View File

@@ -34,8 +34,8 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'Relation:depends on/Description' => 'Elementy wpływające',
'Relation:depends on/DownStream' => 'Zależy od...',
'Relation:depends on/UpStream' => 'Wpływa na...',
'Relation:impacts/LoadData' => 'Załaduj dane',
'Relation:impacts/NoFilteredData' => 'proszę wybrać obiekty w widoku graficznym',
'Relation:impacts/LoadData' => 'Load data~~',
'Relation:impacts/NoFilteredData' => 'please select objects in Graphical view tag~~',
));

View File

@@ -1,4 +1,4 @@
<?php
+<?php
// Copyright (C) 2010-2021 Combodo SARL
//
// This file is part of iTop.

View File

@@ -13,7 +13,9 @@ use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
use Combodo\iTop\Config\Validator\iTopConfigAstValidator;
use Combodo\iTop\Config\Validator\iTopConfigSyntaxValidator;
require_once(APPROOT.'application/application.inc.php');
require_once(APPROOT.'application/startup.inc.php');
require_once(APPROOT.'application/loginwebpage.class.inc.php');
/**

View File

@@ -75,9 +75,9 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'iTopUpdate:UI:CanCoreUpdate:Yes' => 'Aplikacja może być zaktualizowana',
'iTopUpdate:UI:CanCoreUpdate:No' => 'Nie można zaktualizować aplikacji: %1$s',
'iTopUpdate:UI:CanCoreUpdate:Warning' => 'Ostrzeżenie: aktualizacja aplikacji może się nie powieść: %1$s',
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Wykryto kilka zmodyfikowanych plików</b>, nie można wykonać częściowej aktualizacji.</br>Postępuj zgodnie z <a target="_blank" href="%2$s"> procedurą</a> w celu ręcznej aktualizacji iTop. Musisz użyć <a href="%1$s">setup</a> aby zaktualizować aplikację.',
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Wykryto kilka nowych modułów</b>, nie można wykonać częściowej aktualizacji.</br>Postępuj zgodnie z <a target="_blank" href="%2$s"> procedurą</a> w celu ręcznej aktualizacji iTop. Musisz użyć <a href="%1$s">setup</a> aby zaktualizować aplikację.',
'iTopUpdate:UI:CheckInProgress' => 'Proszę czekać trwa sprawdzanie integralności',
'iTopUpdate:UI:CannotUpdateUseSetup' => '<b>Some modified files were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
'iTopUpdate:UI:CannotUpdateNewModules' => '<b>Some new modules were detected</b>, a partial update cannot be executed.</br>Follow the <a target="_blank" href="%2$s"> procedure</a> in order to manually upgrade your iTop. You must use the <a href="%1$s">setup</a> to update the application.~~',
'iTopUpdate:UI:CheckInProgress' => 'Please wait during integrity check~~',
// Setup Messages
'iTopUpdate:UI:SetupMessage:Ready' => 'Gotowy do startu',

View File

@@ -37,20 +37,16 @@
<field id="device_list" xsi:type="AttributeLinkedSet">
<linked_class>DatacenterDevice</linked_class>
<ext_key_to_me>rack_id</ext_key_to_me>
<legacy_edit_mode>add_only</legacy_edit_mode>
<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>
<ext_key_to_me>rack_id</ext_key_to_me>
<legacy_edit_mode>add_only</legacy_edit_mode>
<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/>
@@ -233,11 +229,9 @@
<field id="device_list" xsi:type="AttributeLinkedSet">
<linked_class>DatacenterDevice</linked_class>
<ext_key_to_me>enclosure_id</ext_key_to_me>
<legacy_edit_mode>add_only</legacy_edit_mode>
<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/>
@@ -579,11 +573,9 @@
<field id="pdus_list" xsi:type="AttributeLinkedSet">
<linked_class>PDU</linked_class>
<ext_key_to_me>powerstart_id</ext_key_to_me>
<legacy_edit_mode>add_only</legacy_edit_mode>
<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

@@ -1390,7 +1390,7 @@
<dashlet id="25" xsi:type="DashletHeaderStatic">
<rank>0</rank>
<title>Menu:ConfigManagement:EndUsers</title>
<icon>../images/icons/icons8-team.svg</icon>
<icon>../images/icons/icons8-team.svg</icon>
</dashlet>
<dashlet id="26" xsi:type="DashletBadge">
<rank>1</rank>

View File

@@ -173,11 +173,9 @@
<field id="faq_list" xsi:type="AttributeLinkedSet">
<linked_class>FAQ</linked_class>
<ext_key_to_me>category_id</ext_key_to_me>
<legacy_edit_mode>add_only</legacy_edit_mode>
<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/>
@@ -307,15 +305,15 @@
<twig>
<div class="row">
<div class="col-sm-4">
<div class="form_field" data-field-id="category_name"/>
<div class="form_field" data-field-id="title"/>
<div class="form_field" data-field-id="error_code"/>
<div class="form_field" data-field-id="key_words"/>
<div class="form_field" data-field-id="domains"/>
<div class="form_field" data-field-id="summary"/>
<div class="form_field" data-field-id="category_name"></div>
<div class="form_field" data-field-id="title"></div>
<div class="form_field" data-field-id="error_code"></div>
<div class="form_field" data-field-id="key_words"></div>
<div class="form_field" data-field-id="domains"></div>
<div class="form_field" data-field-id="summary"></div>
</div>
<div class="col-sm-8">
<div class="form_field" data-field-id="description"/>
<div class="form_field" data-field-id="description"></div>
</div>
</div>
</twig>

View File

@@ -25,7 +25,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
// Errors
'FilesInformation:Error:MissingFile' => 'Brakujący plik: %1$s',
'FilesInformation:Error:CorruptedFile' => 'Plik %1$s jest uszkodzony',
'FilesInformation:Error:ListCorruptedFile' => 'Uszkodzone pliki: %1$s',
'FilesInformation:Error:ListCorruptedFile' => 'Fichier(s) corrompu(s): %1$s~~',
'FilesInformation:Error:CantWriteToFile' => 'Nie można zapisać do pliku %1$s',
));

View File

@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<classes>
<class id="Ticket">
<methods>
<method id="CreateFromServiceSubcategory" _delta="define">
<comment>/**
<classes>
<class id="Ticket">
<methods>
<method id="CreateFromServiceSubcategory" _delta="define">
<comment>/**
* Instanciate an object of the relevant class, depending on the request type
* @return DBObject
*/</comment>
<static>true</static>
<access>public</access>
<type>Factory</type>
<code><![CDATA[ static public function CreateFromServiceSubcategory($oServiceSubcategory)
<static>true</static>
<access>public</access>
<type>Factory</type>
<code><![CDATA[ static public function CreateFromServiceSubcategory($oServiceSubcategory)
{
$sType = $oServiceSubcategory->Get('request_type');
if ($sType == 'incident')
@@ -32,43 +32,43 @@
}
return $oRet;
}]]></code>
</method>
</methods>
</class>
</classes>
<module_designs>
<module_design id="itop-portal">
<bricks>
<brick id="services">
<levels>
<level id="1">
<levels>
<level id="1">
<levels>
<level id="1">
<actions>
<action id="create_from_this">
<class _delta="delete"/>
<factory_method _delta="define"><![CDATA[\Ticket::CreateFromServiceSubcategory]]></factory_method>
</action>
</actions>
</level>
</levels>
</level>
</levels>
</level>
</levels>
</brick>
</bricks>
<classes>
<class id="ServiceSubcategory">
<scopes>
<scope id="all">
<oql_view _delta="redefine"><![CDATA[SELECT ServiceSubcategory WHERE status != 'obsolete']]></oql_view>
</scope>
</scopes>
</class>
</classes>
</module_design>
</module_designs>
</method>
</methods>
</class>
</classes>
<module_designs>
<module_design id="itop-portal">
<bricks>
<brick id="services">
<levels>
<level id="1">
<levels>
<level id="1">
<levels>
<level id="1">
<actions>
<action id="create_from_this">
<class _delta="delete" />
<factory_method _delta="define"><![CDATA[\Ticket::CreateFromServiceSubcategory]]></factory_method>
</action>
</actions>
</level>
</levels>
</level>
</levels>
</level>
</levels>
</brick>
</bricks>
<classes>
<class id="ServiceSubcategory">
<scopes>
<scope id="all">
<oql_view _delta="redefine"><![CDATA[SELECT ServiceSubcategory WHERE status != 'obsolete']]></oql_view>
</scope>
</scopes>
</class>
</classes>
</module_design>
</module_designs>
</itop_design>

View File

@@ -13,15 +13,15 @@
</profiles>
</user_rights>
<module_parameters>
<parameters id="itop-hub-connector" _delta="define">
<url>https://www.itophub.io</url>
<parameters id="itop-hub-connector" _delta="define">
<url>https://www.itophub.io</url>
<route_landing>/my-instances/landing-from-remote</route_landing>
<route_landing_stateless>/stateless-remote-itop/landing-from-remote-stateless</route_landing_stateless>
<route_fetch_unread_messages>/api/messages</route_fetch_unread_messages>
<route_mark_all_messages_as_read>/api/messages/mark-all-as-read</route_mark_all_messages_as_read>
<route_view_all_messages>/messages</route_view_all_messages>
<setup_url>../pages/exec.php?exec_module=itop-hub-connector&amp;exec_page=launch.php&amp;target=inform_after_setup</setup_url>
<route_landing_stateless>/stateless-remote-itop/landing-from-remote-stateless</route_landing_stateless>
<route_fetch_unread_messages>/api/messages</route_fetch_unread_messages>
<route_mark_all_messages_as_read>/api/messages/mark-all-as-read</route_mark_all_messages_as_read>
<route_view_all_messages>/messages</route_view_all_messages>
<setup_url>../pages/exec.php?exec_module=itop-hub-connector&amp;exec_page=launch.php&amp;target=inform_after_setup</setup_url>
<rgpd_url>https://www.itophub.io/page/data-privacy</rgpd_url>
</parameters>
</parameters>
</module_parameters>
</itop_design>

View File

@@ -55,7 +55,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', array(
'iTopHub:ExtensionCategory:Remote' => 'Rozszerzenia wdrożone z iTop Hub',
'iTopHub:ExtensionCategory:Remote+' => 'Następujące rozszerzenia zostały wdrożone z iTop Hub:',
'iTopHub:NoExtensionInThisCategory' => 'W tej kategorii nie ma rozszerzenia.<br/><br/>Przeglądaj iTop Hub, aby znaleźć rozszerzenia, które pomogą Ci dostosować i dostosować '.ITOP_APPLICATION_SHORT.' do Twoich procesów.',
'iTopHub:NoExtensionInThisCategory+' => '',
'iTopHub:NoExtensionInThisCategory+' => '~~',
'iTopHub:ExtensionNotInstalled' => 'Nie zainstalowane',
'iTopHub:GetMoreExtensions' => 'Pobierz rozszerzenia z iTop Hub...',

View File

@@ -111,10 +111,6 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:Incident/Attribute:urgency/Value:4+' => 'low',
'Class:Incident/Attribute:origin' => 'Origin',
'Class:Incident/Attribute:origin+' => '',
'Class:Incident/Attribute:origin/Value:in_person' => 'in-person',
'Class:Incident/Attribute:origin/Value:in_person+' => '',
'Class:Incident/Attribute:origin/Value:chat' => 'chat',
'Class:Incident/Attribute:origin/Value:chat+' => '',
'Class:Incident/Attribute:origin/Value:mail' => 'email',
'Class:Incident/Attribute:origin/Value:mail+' => 'email',
'Class:Incident/Attribute:origin/Value:monitoring' => 'monitoring',

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