mirror of
https://github.com/Combodo/iTop.git
synced 2026-03-12 04:24:12 +01:00
Compare commits
8 Commits
feature/92
...
feature/79
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff97be963 | ||
|
|
add7743b6f | ||
|
|
2415d3d5d3 | ||
|
|
77989b6bd8 | ||
|
|
f26ed0ea71 | ||
|
|
309b6bd900 | ||
|
|
83f1476de4 | ||
|
|
c2d0c310a9 |
99
.doc/README.md
Normal file
99
.doc/README.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Phpdoc dokuwiki template
|
||||||
|
This directory contains a template for rendering iTop phpdoc as dokuwiki pages.
|
||||||
|
|
||||||
|
|
||||||
|
Conventional tags that you should use:
|
||||||
|
* `@internal` : exclude from the documentation.
|
||||||
|
* `@api` : it means that a method is an api, thus it may be interacted with.
|
||||||
|
* `@see` : it points to another documented method
|
||||||
|
* `@link` : external url
|
||||||
|
* if you point to another page of the wiki, please use relative links.
|
||||||
|
* `@example` : let you provide example of code
|
||||||
|
* `@param`, `@return`, `@throws`, ...
|
||||||
|
|
||||||
|
|
||||||
|
## Special instructions
|
||||||
|
|
||||||
|
Some iTop specific tags were added :
|
||||||
|
* `@api-advanced`: it means that a method is an `@api` but mark it also as "complex" to use
|
||||||
|
* `@overwritable-hook`: used to mark a method as "designed to be extended"
|
||||||
|
* `@extension-hook`: not used for now
|
||||||
|
* `@phpdoc-tuning-exclude-inherited`: once this tag is present on a class, it's inherited methods won't be showed.
|
||||||
|
|
||||||
|
|
||||||
|
### known limitations:
|
||||||
|
#### `@see` tags must be very specific:
|
||||||
|
* always prefix class members (attributes or methods) with `ClassName::` (do not use self)
|
||||||
|
* for methods always suffix them with `()`,
|
||||||
|
* do not reference variables since they are not documented. If you have to, always prefix them with `$`
|
||||||
|
|
||||||
|
examples:
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* @see DBObject
|
||||||
|
* @see DBObject::Get()
|
||||||
|
* @see DBObject::$foo
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Do not use inline tags, they do not work properly, example:
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* This is a texts with an inline tag {@see [FQSEN] [<description>]} it must never be used
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### The `@example` tag must respect this very precise syntax
|
||||||
|
* the sentence in the first line (next to the tag) is the title, it must be enclosed by double quotes
|
||||||
|
* the following lines are the sample code.
|
||||||
|
* 💔 since we simply hack the official tag, this syntax must be respected carefully 💔
|
||||||
|
example:
|
||||||
|
```
|
||||||
|
/**
|
||||||
|
* @example "This is the title of the multiline example"
|
||||||
|
* $foo = DBObject::Get('foo');
|
||||||
|
* DBObject::Set('foo', ++$foo);
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
## How content is included into the documentation
|
||||||
|
|
||||||
|
**For a class** those requirements have to be respected:
|
||||||
|
- the file containing the class must be listed in `/phpdoc/files/file[]` of `.doc/phpdoc-objects-manipulation.dist.xml`
|
||||||
|
- the class **must not** have the tag `@internal`
|
||||||
|
- the class **must** have at least one of: `@api`, `@api-advanced`, `@overwritable-hook`, `@extension-hook`
|
||||||
|
|
||||||
|
Then, **for a method** of an eligible class:
|
||||||
|
- **public** methods **must** have at least one of: `@api`, `@api-advanced`, `@overwritable-hook`, `@extension-hook`
|
||||||
|
- **protected** methods **must** have at least one of: `@overwritable-hook`, `@extension-hook`
|
||||||
|
- **private** methods are **always excluded**
|
||||||
|
|
||||||
|
**Class properties** and **constants** are never documented (this is subject to change).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## A note about the rendering engine
|
||||||
|
|
||||||
|
:notebook: as spaces are used to mark code, the templates (`.doc/phpdoc-templates/combodo-wiki/*`) have very few indentation, thus they are awful to read (sorry).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
cd .doc
|
||||||
|
composer require phpdocumentor/phpdocumentor:~2 --dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generation
|
||||||
|
|
||||||
|
1. Switch to this directory : `cd /path/to/itop/.doc`
|
||||||
|
2. `composer install`
|
||||||
|
3. `./bin/build-doc-object-manipulation`
|
||||||
|
3. `./bin/build-doc-extensions`
|
||||||
|
4. Get the generated files from `/path/to/itop/data/phpdocumentor/output`
|
||||||
|
|
||||||
|
## Dokuwiki requirements
|
||||||
|
* the template uses the [wrap plugin](https://www.dokuwiki.org/plugin:wrap).
|
||||||
|
* the generated files have to be placed under an arbitrary directory of `[/path/to/dokuwiki]/data/pages`.
|
||||||
|
* the html has to be activated [config:htmlok](https://www.dokuwiki.org/config:htmlok)
|
||||||
|
* the generated files have to be in lowercase
|
||||||
6
.doc/bin/build-doc-extensions
Executable file
6
.doc/bin/build-doc-extensions
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
|
||||||
|
rm -rf /tmp/phpdoc-twig-cache/ && rm -rf data/phpdocumentor/output/extensions/ && rm -rf data/phpdocumentor/temp/extensions/ && ./vendor/bin/phpdoc -c ./phpdoc-extensions.dist.xml -vvv
|
||||||
|
|
||||||
|
# now wee need to lowercase every generated file because dokuwiki can't handle uppercase
|
||||||
|
cd ../data/phpdocumentor/output/extensions/ && for i in $(ls | grep [A-Z]); do mv -i $i $(echo $i | tr 'A-Z' 'a-z'); done
|
||||||
7
.doc/bin/build-doc-object-manipulation
Executable file
7
.doc/bin/build-doc-object-manipulation
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
|
||||||
|
rm -rf /tmp/phpdoc-twig-cache/ && rm -rf ../data/phpdocumentor/output/objects-manipulation/ && rm -rf ../data/phpdocumentor/temp/objects-manipulation/ && ./vendor/bin/phpdoc -c ./phpdoc-objects-manipulation.dist.xml -vvv
|
||||||
|
|
||||||
|
|
||||||
|
# now wee need to lowercase every generated file because dokuwiki can't handle uppercase
|
||||||
|
cd ../data/phpdocumentor/output/objects-manipulation/ && for i in $( ls | grep [A-Z] ); do mv -i $i `echo $i | tr 'A-Z' 'a-z'`; done
|
||||||
6
.doc/composer.json
Normal file
6
.doc/composer.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"require-dev": {
|
||||||
|
"phpdocumentor/phpdocumentor": "~2",
|
||||||
|
"jms/serializer": "1.7.*"
|
||||||
|
}
|
||||||
|
}
|
||||||
3015
.doc/composer.lock
generated
Normal file
3015
.doc/composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 983 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.8 MiB |
98
.doc/itop-version-history.md
Normal file
98
.doc/itop-version-history.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# iTop version history
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'themeVariables': {
|
||||||
|
'git0': 'lawngreen',
|
||||||
|
'git3': 'dodgerblue',
|
||||||
|
'git4': 'grey',
|
||||||
|
'git5': 'grey',
|
||||||
|
'git6': 'grey',
|
||||||
|
'git7': 'grey'
|
||||||
|
}, 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
|
||||||
|
gitGraph
|
||||||
|
commit id: "2016-07-06" tag: "2.3.0" type: HIGHLIGHT
|
||||||
|
branch support/2.3 order: 900
|
||||||
|
commit id: "2016-07-08" tag: "2.3.1"
|
||||||
|
commit id: "2016-12-22" tag: "2.3.3"
|
||||||
|
commit id: "2017-04-14" tag: "2.3.4"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2017-07-12" tag: "2.4.0-beta" type: REVERSE
|
||||||
|
commit id: "2017-11-16" tag: "2.4.0" type: HIGHLIGHT
|
||||||
|
branch support/2.4 order: 890
|
||||||
|
commit id: "2018-02-14" tag: "2.4.1"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2018-04-25" tag: "2.5.0-beta" type: REVERSE
|
||||||
|
checkout support/2.4
|
||||||
|
commit id: "2018-06-14" tag: "2.4.2"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2018-06-27" tag: "2.5.0" type: HIGHLIGHT
|
||||||
|
branch support/2.5 order: 880
|
||||||
|
checkout develop
|
||||||
|
commit id: "2019-01-09" tag: "2.6.0" type: HIGHLIGHT
|
||||||
|
branch support/2.6 order: 870
|
||||||
|
commit id: "2019-03-28" tag: "2.6.1"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2019-12-18" tag: "2.7.0-beta" type: REVERSE
|
||||||
|
checkout support/2.5
|
||||||
|
commit id: "2020-01-22" tag: "2.5.4"
|
||||||
|
checkout support/2.6
|
||||||
|
commit id: "2020-01-23" tag: "2.6.3"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2020-01-29" tag: "2.7.0-beta2" type: REVERSE
|
||||||
|
commit id: "2020-04-01" tag: "2.7.0-1" type: HIGHLIGHT
|
||||||
|
checkout support/2.6
|
||||||
|
commit id: "2020-04-22" tag: "2.6.4"
|
||||||
|
checkout develop
|
||||||
|
branch support/2.7 order: 860
|
||||||
|
commit id: "2020-06-26" tag: "2.7.1"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2020-12-09" tag: "2.7.3"
|
||||||
|
commit id: "2021-03-31" tag: "2.7.4"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2021-04-06" tag: "3.0.0-beta" type: REVERSE
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2021-07-05" tag: "2.7.5"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2021-07-05." tag: "3.0.0-beta2" type: REVERSE
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2021-12-17" tag: "2.7.6"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2022-01-04" tag: "3.0.0" type: HIGHLIGHT
|
||||||
|
branch support/3.0 order: 850
|
||||||
|
commit id: "2022-04-08" tag: "3.0.1"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2022-07-11" tag: "2.7.7"
|
||||||
|
checkout support/3.0
|
||||||
|
commit id: "2022-09-12" tag: "3.0.2-1"
|
||||||
|
checkout develop
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2022-12-28" tag: "2.7.8"
|
||||||
|
checkout support/3.0
|
||||||
|
commit id: "2023-04-12" tag: "3.0.3"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2023-06-19" tag: "3.1.0-beta" type: REVERSE
|
||||||
|
commit id: "2023-07-26" tag: "3.1.0-1" type: HIGHLIGHT
|
||||||
|
branch support/3.1 order: 840
|
||||||
|
checkout support/3.1
|
||||||
|
commit id: "2023-08-09" tag: "3.1.0-2"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2023-08-10" tag: "2.7.9"
|
||||||
|
checkout support/3.1
|
||||||
|
commit id: "2023-12-20" tag: "3.1.1"
|
||||||
|
checkout develop
|
||||||
|
commit id: "2024-01-15" tag: "Start 3.2" type: HIGHLIGHT
|
||||||
|
branch support/3.2 order: 830
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2024-01-17a" tag: "2.7.10"
|
||||||
|
checkout support/3.0
|
||||||
|
commit id: "2024-01-17b" tag: "3.0.4"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2024-09-28" tag: "2.7.11"
|
||||||
|
checkout support/3.1
|
||||||
|
commit id: "2024-09-27" tag: "3.1.2"
|
||||||
|
checkout support/3.2
|
||||||
|
commit id: "2024-06-25" tag: "3.2.0-beta1" type: REVERSE
|
||||||
|
commit id: "2024-08-07" tag: "3.2.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
||||||
20
.doc/phpdoc-extensions.dist.xml
Executable file
20
.doc/phpdoc-extensions.dist.xml
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<phpdoc>
|
||||||
|
<title><![CDATA[iTop extensions]]></title>
|
||||||
|
|
||||||
|
<parser>
|
||||||
|
<target>../data/phpdocumentor/temp/extensions</target>
|
||||||
|
</parser>
|
||||||
|
|
||||||
|
<transformer>
|
||||||
|
<target>../data/phpdocumentor/output/extensions</target>
|
||||||
|
</transformer>
|
||||||
|
|
||||||
|
<transformations>
|
||||||
|
<template name="phpdoc-templates/combodo-wiki"/>
|
||||||
|
</transformations>
|
||||||
|
|
||||||
|
<files>
|
||||||
|
<file>../application/applicationextension.inc.php</file>
|
||||||
|
</files>
|
||||||
|
</phpdoc>
|
||||||
58
.doc/phpdoc-objects-manipulation.dist.xml
Executable file
58
.doc/phpdoc-objects-manipulation.dist.xml
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<phpdoc>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/**
|
||||||
|
The documentation of this file can be found here : https://docs.phpdoc.org/references/configuration.html
|
||||||
|
it has to be completed by the CLI parameters documentation which is more comprehensive: https://docs.phpdoc.org/references/commands/project_run.html#usage
|
||||||
|
|
||||||
|
usage:
|
||||||
|
vendor/bin/phpdoc -c phpdoc-objects-manipulation.dist.xml
|
||||||
|
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
<title><![CDATA[iTop's objects manipulation API]]></title>
|
||||||
|
|
||||||
|
<parser>
|
||||||
|
<default-package-name>iTopORM</default-package-name>
|
||||||
|
<target>../data/phpdocumentor/temp/objects-manipulation</target>
|
||||||
|
<visibility>public,protected</visibility>
|
||||||
|
<markers>
|
||||||
|
<!--<item>TODO</item>-->
|
||||||
|
<!--<item>FIXME</item>-->
|
||||||
|
</markers>
|
||||||
|
<extensions>
|
||||||
|
<extension>php</extension>
|
||||||
|
</extensions>
|
||||||
|
</parser>
|
||||||
|
|
||||||
|
<transformer>
|
||||||
|
<target>../data/phpdocumentor/output/objects-manipulation</target>
|
||||||
|
</transformer>
|
||||||
|
|
||||||
|
<transformations>
|
||||||
|
<template name="phpdoc-templates/combodo-wiki"/>
|
||||||
|
</transformations>
|
||||||
|
|
||||||
|
<!--<logging>-->
|
||||||
|
<!--<level>warn</level>-->
|
||||||
|
<!--<paths>-->
|
||||||
|
<!--<!–<default>data/phpdocumentor/log/objects-manipulation/{DATE}.log</default>–>-->
|
||||||
|
<!--<!–<errors>data/phpdocumentor/log/objects-manipulation/{DATE}.errors.log</errors>–>-->
|
||||||
|
|
||||||
|
<!--<default>{APP_ROOT}/data/log/{DATE}.log</default>-->
|
||||||
|
<!--<errors>{APP_ROOT}/data/log/{DATE}.errors.log</errors>-->
|
||||||
|
<!--</paths>-->
|
||||||
|
<!--</logging>-->
|
||||||
|
|
||||||
|
<files>
|
||||||
|
<file>../core/dbobject.class.php</file>
|
||||||
|
<file>../core/dbobjectsearch.class.php</file>
|
||||||
|
<file>../core/metamodel.class.php</file>
|
||||||
|
<file>../core/dbobjectset.class.php</file>
|
||||||
|
<file>../core/dbsearch.class.php</file>
|
||||||
|
<file>../core/dbunionsearch.class.php</file>
|
||||||
|
</files>
|
||||||
|
|
||||||
|
</phpdoc>
|
||||||
0
.doc/phpdoc-templates/.placeholder
Normal file
0
.doc/phpdoc-templates/.placeholder
Normal file
136
.doc/phpdoc-templates/combodo-wiki/class.txt.twig
Normal file
136
.doc/phpdoc-templates/combodo-wiki/class.txt.twig
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
{% extends 'layout.txt.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<wrap button>[[start|🔙 Back]]</wrap>
|
||||||
|
|
||||||
|
{% if node.tags['internal'] is defined %}
|
||||||
|
====== {{ node.name }} ======
|
||||||
|
<WRAP alert>This class is "internal", and thus is not documented!</WRAP>
|
||||||
|
{% elseif node.tags['api'] is not defined and node.tags['api-advanced'] is not defined and node.tags['overwritable-hook'] is not defined and node.tags['extension-hook'] is not defined %}
|
||||||
|
====== {{ node.name }} ======
|
||||||
|
<WRAP alert>This class is neither "api", "api-advanced", "overwritable-hook" or "extension-hook", and thus is not documented!</WRAP>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
====== {{ node.name }} ======
|
||||||
|
|
||||||
|
{% if node.deprecated %}<wrap danger>deprecated</wrap>{% endif %}
|
||||||
|
{% if node.abstract %}<wrap warning>abstract</wrap>{% endif %}
|
||||||
|
{% if node.final %}<wrap notice>final</wrap>{% endif %}
|
||||||
|
{% include 'includes/wrap-tags.txt.twig' with {structure:node, wrap: 'safety', wrapTags: ['api', 'api-advanced', 'overwritable-hook', 'extension-hook']} %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% if node.deprecated %}
|
||||||
|
=== **<del>Deprecated</del>**===
|
||||||
|
//{{ node.tags.deprecated[0].description }}//
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
== {{ node.summary|replace({"\n":""})|raw }} ==
|
||||||
|
<html>{{ node.description|markdown|raw }}</html>
|
||||||
|
|
||||||
|
|
||||||
|
{% include 'includes/code-examples.txt.twig' with {structure:node, title_level: '====='} %}
|
||||||
|
|
||||||
|
|
||||||
|
{% set class = node.parent %}
|
||||||
|
{% block hierarchy_element %}
|
||||||
|
|
||||||
|
{% if class and class.name is defined and class.name|trim != '' %}
|
||||||
|
==== parent ====
|
||||||
|
{% set child = class %}
|
||||||
|
{% set class = class.parent %}
|
||||||
|
{{ block('hierarchy_element') }}
|
||||||
|
[[{{ child.name }}|{{ child.name }}]]
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% for interface in node.interfaces|sort_asc %}
|
||||||
|
{% if loop.first %}
|
||||||
|
==== Implements ====
|
||||||
|
{% endif %}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{{ interface.fullyQualifiedStructuralElementName ?: interface }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
{% for trait in node.usedTraits|sort_asc %}
|
||||||
|
{% if loop.first %}
|
||||||
|
==== Uses traits ====
|
||||||
|
{% endif %}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{{ trait.fullyQualifiedStructuralElementName ?: trait }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include 'includes/see-also.txt.twig' with {structure:node, title_level: '==='} %}
|
||||||
|
|
||||||
|
{% include 'includes/tags.txt.twig' with {structure:node, title_level: '=====', blacklist: ['link', 'see', 'abstract', 'example', 'method', 'property', 'property-read', 'property-write', 'package', 'subpackage', 'phpdoc-tuning-exclude-inherited', 'api', 'api-advanced', 'overwritable-hook', 'extension-hook', 'copyright', 'license', 'code-example']} %}
|
||||||
|
|
||||||
|
{% set methods = node.inheritedMethods.merge(node.methods.merge(node.magicMethods)) %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'api'} %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'api-advanced'} %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'overwritable-hook'} %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'extension-hook'} %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include 'includes/code-examples.txt.twig' with {structure:node, title_level: '=====', sub_title_level: '=='} %}
|
||||||
|
|
||||||
|
<WRAP clear />
|
||||||
|
|
||||||
|
{% for method in methods|sort_asc
|
||||||
|
if method.visibility == 'public'
|
||||||
|
and (
|
||||||
|
method.tags['api'] is defined
|
||||||
|
or method.tags['api-advanced'] is defined
|
||||||
|
or method.tags['overwritable-hook'] is defined
|
||||||
|
or method.tags['extension-hook'] is defined
|
||||||
|
)
|
||||||
|
and (
|
||||||
|
node.tags['phpdoc-tuning-exclude-inherited'] is not defined
|
||||||
|
or method.parent.name == node.name
|
||||||
|
)
|
||||||
|
%}
|
||||||
|
{%- if loop.first %}
|
||||||
|
===== Public methods =====
|
||||||
|
{% endif %}
|
||||||
|
{{ block('method') }}
|
||||||
|
{% endfor %}
|
||||||
|
{% for method in methods|sort_asc if method.visibility == 'protected' and (method.tags['overwritable-hook'] is defined or method.tags['extension-hook'] is defined) %}
|
||||||
|
{%- if loop.first %}
|
||||||
|
===== Protected methods =====
|
||||||
|
{% endif %}
|
||||||
|
{{ block('method') }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% set constants = node.inheritedConstants.merge(node.constants) %}
|
||||||
|
{% if constants|length > 0 %}
|
||||||
|
===== Constants =====
|
||||||
|
{% for constant in constants|sort_asc %}
|
||||||
|
{{ block('constant') }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{#{% set properties = node.inheritedProperties.merge(node.properties.merge(node.magicProperties)) %}#}
|
||||||
|
{#{% for property in properties|sort_asc if property.visibility == 'public' %}#}
|
||||||
|
{#{%- if loop.first %}#}
|
||||||
|
{#===== Public properties =====#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{{ block('property') }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% for property in properties|sort_asc if property.visibility == 'protected' %}#}
|
||||||
|
{#{%- if loop.first %}#}
|
||||||
|
{#===== Protected properties =====#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{{ block('property') }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
|
||||||
|
|
||||||
|
{%- endif %} {#{% elseif node.tags['xxx'] is not defined and ... #}
|
||||||
|
|
||||||
|
<wrap button>[[start|🔙 Back]]</wrap>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{% block constant %}
|
||||||
|
|
||||||
|
<WRAP group box >
|
||||||
|
<WRAP twothirds column >
|
||||||
|
==== {{ constant.name }} ====
|
||||||
|
</WRAP>{# twothirds column#}
|
||||||
|
|
||||||
|
<WRAP third column>
|
||||||
|
{% if constant.deprecated %}<wrap danger>deprecated</wrap> {% endif %}
|
||||||
|
{% if (node.parent is not null and constant.parent.fullyQualifiedStructuralElementName != node.fullyQualifiedStructuralElementName) %}<wrap notice>inherited</wrap> {% endif %}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
== {{ constant.summary|replace({"\n":""})|raw }} ==
|
||||||
|
<html>{{ constant.description|markdown|raw }}</html>
|
||||||
|
|
||||||
|
{% if constant.deprecated %}
|
||||||
|
=== Deprecated ===
|
||||||
|
{{ constant.tags.deprecated[0].description|raw }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include 'includes/inherited-from.txt.twig' with {structure:constant} %}
|
||||||
|
|
||||||
|
{% include 'includes/see-also.txt.twig' with {structure:constant, title_level: '=='} %}
|
||||||
|
|
||||||
|
{% include 'includes/uses.txt.twig' with {structure:constant, title_level: '=='} %}
|
||||||
|
|
||||||
|
{% include 'includes/tags.txt.twig' with {structure:constant, title_level: '==', blacklist: ['link', 'see', 'var', 'deprecated', 'uses', 'package', 'subpackage', 'todo', 'code-example']} %}
|
||||||
|
|
||||||
|
</WRAP>{# group #}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
95
.doc/phpdoc-templates/combodo-wiki/elements/method.txt.twig
Normal file
95
.doc/phpdoc-templates/combodo-wiki/elements/method.txt.twig
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
{% block method %}
|
||||||
|
|
||||||
|
|
||||||
|
<WRAP group box >
|
||||||
|
<WRAP twothirds column >
|
||||||
|
==== {{ method.name }} ====
|
||||||
|
</WRAP>{# twothirds column#}
|
||||||
|
<WRAP third column >
|
||||||
|
{% include 'includes/wrap-tags.txt.twig' with {structure:method, wrap: 'safety', wrapTags: ['api', 'api-advanced', 'overwritable-hook', 'extension-hook']} %}
|
||||||
|
{% if method.deprecated %}<wrap danger>deprecated</wrap> {% endif %}
|
||||||
|
{% if (node.parent is not null and method.parent.fullyQualifiedStructuralElementName != node.fullyQualifiedStructuralElementName) %}<wrap notice>inherited</wrap> {% endif %}
|
||||||
|
{% if method.abstract %}<wrap warning>abstract</wrap> {% endif %}
|
||||||
|
{% if method.final %}<wrap notice>final</wrap> {% endif %}
|
||||||
|
<wrap notice>{{ method.visibility }}</wrap>
|
||||||
|
{% if method.static %}<wrap warning>static</wrap> {% endif %}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
|
||||||
|
== {{ method.summary|replace({"\n":""})|raw }} ==
|
||||||
|
<html>{{ method.description|markdown|raw }}</html>
|
||||||
|
|
||||||
|
<code php>{% if method.abstract %}abstract {% endif %}{% if method.final %}final {% endif %}{{ method.visibility }} {% if method.static %}static {% endif %}{{ method.name }}({% for argument in method.arguments %}{{ argument.isVariadic ? '...' }}{{ argument.name }}{{ argument.default ? (' = '~argument.default)|raw }}{% if not loop.last %}, {% endif %}{% endfor %})</code>
|
||||||
|
|
||||||
|
<WRAP twothirds column >
|
||||||
|
|
||||||
|
|
||||||
|
=== Parameters ===
|
||||||
|
{% if method.arguments|length > 0 -%}
|
||||||
|
^ types ^ name ^ default ^ description ^
|
||||||
|
{% for argument in method.arguments -%}
|
||||||
|
| **<nowiki>{{ argument.types|join('|')|raw }}</nowiki>** | {{ argument.name }} {{ argument.isVariadic ? '<small style="color: gray">variadic</small>' }} | <nowiki>{{ argument.default|raw }}</nowiki> | {{ argument.description|trim|replace("\n", ' ')|raw }} |{{ "\r\n" }}
|
||||||
|
{%- endfor %}
|
||||||
|
{% else %}
|
||||||
|
//none//
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{#=== Parameters ===#}
|
||||||
|
{#{% if method.arguments|length > 0 -%}#}
|
||||||
|
{#{% for argument in method.arguments -%}#}
|
||||||
|
{#== {{ argument.name }} ==#}
|
||||||
|
|
||||||
|
|
||||||
|
{#{% set varDesc %}#}
|
||||||
|
{#<span style="margin:0 10px; 0 20px; font-weight: bold;">{{ argument.types|join('|') }}</span>#}
|
||||||
|
{#{{ argument.isVariadic ? '<small style="color: gray">variadic</small>' }}#}
|
||||||
|
{#{{ argument.description|raw }}#}
|
||||||
|
{#{% endset %}#}
|
||||||
|
{#<html>{{ varDesc|markdown|raw }}</html>#}
|
||||||
|
{#{%- endfor %}#}
|
||||||
|
{#{% else %}#}
|
||||||
|
{#<wrap tip>This method has no parameter</wrap>#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
|
||||||
|
|
||||||
|
{% if method.response and method.response.types|join() != 'void' %}
|
||||||
|
=== Returns ===
|
||||||
|
<html>{{ ('**' ~ method.response.types|join('|')|trim ~ '** ' ~ method.response.description)|markdown|raw }}</html>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</WRAP>{# twothirds column#}
|
||||||
|
|
||||||
|
<WRAP third column >
|
||||||
|
|
||||||
|
{% if method.tags.throws|length > 0 or method.tags.throw|length > 0 %}
|
||||||
|
=== Throws ===
|
||||||
|
{% for exception in method.tags.throws -%}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}''{{ exception.types|join('|')|raw }}'' <nowiki>{{ exception.description|raw }}</nowiki>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include 'includes/inherited-from.txt.twig' with {structure:method} %}
|
||||||
|
|
||||||
|
{% include 'includes/see-also.txt.twig' with {structure:method, title_level: '==='} %}
|
||||||
|
|
||||||
|
{% include 'includes/uses.txt.twig' with {structure:method, title_level: '==='} %}
|
||||||
|
|
||||||
|
{% include 'includes/used-by.txt.twig' with {structure:method, title_level: '==='} %}
|
||||||
|
|
||||||
|
{% include 'includes/tags-with-description.txt.twig' with {structure:method, title_level: '===', WRAP: 'info', tagsWithDescription: ['api', 'api-advanced', 'overwritable-hook', 'extension-hook']} %}
|
||||||
|
|
||||||
|
{% include 'includes/tags.txt.twig' with {structure:method, title_level: '===', blacklist: ['todo', 'link', 'see', 'abstract', 'example', 'param', 'return', 'access', 'deprecated', 'throws', 'throw', 'uses', 'api', 'api-advanced', 'overwritable-hook', 'extension-hook', 'used-by', 'inheritdoc', 'code-example']} %}
|
||||||
|
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% include 'includes/code-examples.txt.twig' with {structure:method, title_level: '==='} %}
|
||||||
|
|
||||||
|
</WRAP>{# group #}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
{% block property %}
|
||||||
|
|
||||||
|
<WRAP group box>
|
||||||
|
<WRAP twothirds column >
|
||||||
|
==== ${{ property.name }} ====
|
||||||
|
</WRAP>{# twothirds column#}
|
||||||
|
|
||||||
|
<WRAP third column>
|
||||||
|
{% if property.deprecated %}<wrap danger>deprecated</wrap> {% endif %}
|
||||||
|
{% if (node.parent is not null and property.parent.fullyQualifiedStructuralElementName != node.fullyQualifiedStructuralElementName) %}<wrap notice>inherited</wrap> {% endif %}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
== {{ property.summary|replace({"\n":""})|raw }} ==
|
||||||
|
<html>{{ property.description|markdown|raw }}</html>
|
||||||
|
{% if property.var.0.description %}<html>{{ property.var.0.description|markdown|raw }}</html>{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{#{% if property.types %}#}
|
||||||
|
{#== Type ==#}
|
||||||
|
{#{% for type in property.types %}#}
|
||||||
|
{#{% if loop.length > 1 %} * {% endif %}{{ type|raw }} : {{ type.description|raw }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{{ property.types|join('|')|raw }}#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
|
||||||
|
|
||||||
|
{% if property.deprecated %}
|
||||||
|
== Deprecated ==
|
||||||
|
{{ property.tags.deprecated[0].description }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include 'includes/inherited-from.txt.twig' with {structure:property} %}
|
||||||
|
|
||||||
|
{% include 'includes/see-also.txt.twig' with {structure:property, title_level: '=='} %}
|
||||||
|
|
||||||
|
{% include 'includes/uses.txt.twig' with {structure:property, title_level: ''} %}
|
||||||
|
|
||||||
|
{% include 'includes/tags.txt.twig' with {structure:property, title_level: '==', blacklist: ['link', 'see', 'access', 'var', 'deprecated', 'uses', 'todo', 'code-example']} %}
|
||||||
|
|
||||||
|
|
||||||
|
<code php>{{ property.visibility }} ${{ property.name }}{% if property.types %} : {{ property.types|join('|')|raw }}{% endif %}</code>
|
||||||
|
|
||||||
|
</WRAP>{# group #}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
1
.doc/phpdoc-templates/combodo-wiki/file.source.txt.twig
Normal file
1
.doc/phpdoc-templates/combodo-wiki/file.source.txt.twig
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{{ node.source|raw }}
|
||||||
122
.doc/phpdoc-templates/combodo-wiki/file.txt.twig
Normal file
122
.doc/phpdoc-templates/combodo-wiki/file.txt.twig
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
{% extends 'layout.txt.twig' %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{#<section class="row-fluid">#}
|
||||||
|
{#<div class="span2 sidebar">#}
|
||||||
|
{#{% set namespace = project.namespace %}#}
|
||||||
|
{#{{ block('sidebarNamespaces') }}#}
|
||||||
|
{#</div>#}
|
||||||
|
{#</section>#}
|
||||||
|
{#<section class="row-fluid">#}
|
||||||
|
====== {{ node.path|split('/')|slice(0,-1)|join('/') }}{{ node.name }} ======
|
||||||
|
{{ node.summary }}
|
||||||
|
<html>{{ node.description|markdown|raw }}</html>
|
||||||
|
|
||||||
|
{% if node.traits|length > 0 %}
|
||||||
|
|
||||||
|
===== Traits =====
|
||||||
|
{% for trait in node.traits %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ trait|raw }}</td>
|
||||||
|
<td><em>{{ trait.summary }}</em></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if node.interfaces|length > 0 %}
|
||||||
|
===== Interfaces =====
|
||||||
|
{% for interface in node.interfaces %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ interface|raw }}</td>
|
||||||
|
<td><em>{{ interface.summary }}</em></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if node.classes|length > 0 %}
|
||||||
|
===== Classes =====
|
||||||
|
{% for class in node.classes %}
|
||||||
|
{{ class|raw }}
|
||||||
|
<em>{{ class.summary }}</em>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if node.package is not empty and node.package != '\\' %}
|
||||||
|
===== Package =====
|
||||||
|
{{ node.subpackage ? (node.package ~ '\\' ~ node.subpackage) : node.package }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for tagName,tags in node.tags if tagName in ['link', 'see'] %}
|
||||||
|
{% if loop.first %}
|
||||||
|
===== See also =====
|
||||||
|
{% endif %}
|
||||||
|
{% for tag in tags %}
|
||||||
|
<dd><a href="{{ tag.reference ?: tag.link }}"><div class="namespace-wrapper">{{ tag.description ?: tag.reference }}</div></a></dd>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<h2>Tags</h2>
|
||||||
|
<table class="table table-condensed">
|
||||||
|
{% for tagName,tags in node.tags if tagName not in ['link', 'see', 'package', 'subpackage'] %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ tagName }}
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
{% for tag in tags %}
|
||||||
|
{{ tag.description|markdown|raw }}
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr><td colspan="2"><em>None found</em></td></tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if node.constants|length > 0 %}
|
||||||
|
<div class="row-fluid">
|
||||||
|
<section class="span8 content file">
|
||||||
|
<h2>Constants</h2>
|
||||||
|
</section>
|
||||||
|
<aside class="span4 detailsbar"></aside>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% for constant in node.constants %}
|
||||||
|
{{ block('constant') }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if node.functions|length > 0 %}
|
||||||
|
<div class="row-fluid">
|
||||||
|
<section class="span8 content file">
|
||||||
|
<h2>Functions</h2>
|
||||||
|
</section>
|
||||||
|
<aside class="span4 detailsbar"></aside>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% for method in node.functions %}
|
||||||
|
{{ block('method') }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div id="source-view" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="source-view-label" aria-hidden="true">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3 id="source-view-label">{{ node.file.name }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<pre data-src="{{ path('files/' ~ node.path ~ '.txt')|raw }}" class="language-php line-numbers"></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
42
.doc/phpdoc-templates/combodo-wiki/graphs/class.html.twig
Normal file
42
.doc/phpdoc-templates/combodo-wiki/graphs/class.html.twig
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{% extends 'layout.html.twig' %}
|
||||||
|
|
||||||
|
{% block stylesheets %}
|
||||||
|
<link href="{{ path('css/jquery.iviewer.css') }}" rel="stylesheet" media="all"/>
|
||||||
|
<style>
|
||||||
|
#viewer {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
<script src="{{ path('js/jquery.mousewheel.js') }}" type="text/javascript"></script>
|
||||||
|
<script src="{{ path('js/jquery.iviewer.js') }}" type="text/javascript"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(window).resize(function(){
|
||||||
|
$("#viewer").height($(window).height() - 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#viewer").iviewer({src: '{{ path('graphs/classes.svg') }}', zoom_animation: false});
|
||||||
|
$('#viewer img').bind('dragstart', function(event){
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
$(window).resize();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div id="viewer" class="viewer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
5
.doc/phpdoc-templates/combodo-wiki/htaccess.dist
Normal file
5
.doc/phpdoc-templates/combodo-wiki/htaccess.dist
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Fixes a vulnerability in CentOS: http://stackoverflow.com/questions/20533279/prevent-php-from-parsing-non-php-files-such-as-somefile-php-txt
|
||||||
|
<FilesMatch \.php\.txt$>
|
||||||
|
RemoveHandler .php
|
||||||
|
ForceType text/plain
|
||||||
|
</FilesMatch>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{%- set title_level = '==' -%}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if sub_title_level is not defined %}
|
||||||
|
{%- set sub_title_level = title_level|slice(1) -%}
|
||||||
|
{% endif %}
|
||||||
|
{% if sub_title_level == '=' %}
|
||||||
|
{%- set sub_title_level = '' -%}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{#{% for tagName,tags in structure.tags if tagName in ['code-example'] %}#}
|
||||||
|
{#{% if loop.first %}#}
|
||||||
|
{#{{title_level}} Examples {{title_level}}#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{% for tag in tags %}#}
|
||||||
|
{#{%- set descToken = tag.description|split("\n", 2) -%}#}
|
||||||
|
{#{%- set title = descToken[0] -%}#}
|
||||||
|
{#{%- set code = descToken[1] -%}#}
|
||||||
|
{#{{sub_title_level}} {{ title }} {{sub_title_level}}#}
|
||||||
|
{#<code php>{{ code|raw }}</code>#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
|
||||||
|
|
||||||
|
{% for tagName,tags in structure.tags if tagName in ['example'] %}
|
||||||
|
{% if loop.first %}
|
||||||
|
{{title_level}} Examples {{title_level}}
|
||||||
|
{% endif %}
|
||||||
|
{% for tag in tags %}
|
||||||
|
{{ sub_title_level }} {{ tag.filePath|escape }}{{ sub_title_level }}
|
||||||
|
<code php>{{ tag.description|raw }}</code>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{% set title_level='' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if (node.parent is null) %}
|
||||||
|
{{title_level}} File {{ structure.path }} {{title_level}}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if (node.parent is not null and structure.parent.fullyQualifiedStructuralElementName != node.fullyQualifiedStructuralElementName) %}
|
||||||
|
{{title_level}} Inherited from {{title_level}}
|
||||||
|
[[{{structure.parent}}|{{structure.parent}}]]
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{% for structure in structures|sort_asc if structure.tags['internal'] is not defined and (structure.tags['api'] is defined or structure.tags['api-advanced'] is defined or structure.tags['overwritable-hook'] is defined or structure.tags['extension-hook'] is defined ) %}
|
||||||
|
{#{{ structure|raw }}#}
|
||||||
|
|
||||||
|
{% set structureName = structure|trim('\\', 'left') %}
|
||||||
|
|
||||||
|
<WRAP group box>
|
||||||
|
<WRAP twothirds column >
|
||||||
|
==== {{ structureName }} ====
|
||||||
|
</WRAP>{# twothirds column#}
|
||||||
|
|
||||||
|
<WRAP third column>
|
||||||
|
{% if structure.deprecated %}<wrap danger>deprecated</wrap>{% endif %}
|
||||||
|
{% if structure.abstract %}<wrap warning>abstract</wrap>{% endif %}
|
||||||
|
{% if structure.final %}<wrap notice>final</wrap>{% endif %}
|
||||||
|
{% if (node.parent is not null and structure.parent.fullyQualifiedStructuralElementName != node.fullyQualifiedStructuralElementName) %}<wrap notice>inherited</wrap> {% endif %}
|
||||||
|
{% include 'includes/wrap-tags.txt.twig' with {structure:structure, wrap: 'safety', wrapTags: ['api', 'api-advanced', 'overwritable-hook', 'extension-hook']} %}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
|
||||||
|
{{ structure.summary|raw }}
|
||||||
|
[[{{structureName}}|More information]]
|
||||||
|
|
||||||
|
</WRAP>{# group #}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{%- set title_level='==' -%}
|
||||||
|
{% endif %}
|
||||||
|
{% for tagName,tags in structure.tags if tagName in ['link', 'see'] %}
|
||||||
|
{% if loop.first %}
|
||||||
|
{{title_level}} See also {{title_level}}
|
||||||
|
{% endif %}
|
||||||
|
{% for tag in tags %}
|
||||||
|
{%- set linkTag = tag.reference|trim('\\', 'left') -%}
|
||||||
|
{% if not('()' in linkTag or '$' in linkTag or node.name in linkTag or '::' in linkTag ) %}
|
||||||
|
{%- set linkTag = linkTag|lower -%}
|
||||||
|
{% elseif node.name~'::' in linkTag %}
|
||||||
|
{%- set linkTag = linkTag|replace({(node.name~'::'): '#'})|lower -%}
|
||||||
|
{% elseif '::' in linkTag -%}
|
||||||
|
{%- set linkTag = linkTag|replace({'::': '#'})|lower -%}
|
||||||
|
{% else %}
|
||||||
|
{%- set linkTag = '#' ~ linkTag|lower -%}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{% if tag.reference is not empty -%}
|
||||||
|
[[{{linkTag}}|{{ (tag.reference)|trim('\\', 'left') }}]] {% if tag.description|trim is not empty %}: {{ tag.description|trim('\\', 'left') }} {% endif %}
|
||||||
|
{%- else -%}
|
||||||
|
{#{{ tag.description|trim('\\', 'left') }}#}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
{% if tag is not defined -%}
|
||||||
|
{# Do not display @api if @api-advanced is also present #}
|
||||||
|
{%- set tag = "api" -%}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{% if hidden_by is not defined -%}
|
||||||
|
{# Do not display @api if @api-advanced is also present #}
|
||||||
|
{%- set hidden_by = {"api" : "api-advanced"} -%}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% for method in methods|sort_asc
|
||||||
|
if (method.visibility == 'public')
|
||||||
|
and (
|
||||||
|
method.tags[tag] is defined
|
||||||
|
and (
|
||||||
|
hidden_by[tag] is not defined or method.tags[hidden_by[tag]] is not defined
|
||||||
|
)
|
||||||
|
)
|
||||||
|
%}
|
||||||
|
{%- if loop.first %}
|
||||||
|
{% if tag == 'api' %}
|
||||||
|
===== API synthesis =====
|
||||||
|
<WRAP>
|
||||||
|
List of the public API methods.
|
||||||
|
When manipulating {{ node.name }}, You can call those methods:
|
||||||
|
</WRAP>
|
||||||
|
{% elseif tag == 'api-advanced' %}
|
||||||
|
===== Advanced API synthesis =====
|
||||||
|
<WRAP>
|
||||||
|
List of advanced API methods
|
||||||
|
Beware they usage is recommended to advanced users only.
|
||||||
|
</WRAP>
|
||||||
|
{% elseif tag == 'overwritable-hook' %}
|
||||||
|
===== overwritable-hook synthesis =====
|
||||||
|
<WRAP >When inheriting from {{ node.name }},
|
||||||
|
you can overwrite those methods in order to add custom logic:
|
||||||
|
</WRAP>
|
||||||
|
{% elseif tag == 'extension-hook' %}
|
||||||
|
===== extension-hook synthesis =====
|
||||||
|
<WRAP >
|
||||||
|
When inheriting from {{ node.name }},
|
||||||
|
you can extend the behaviour of iTop by implementing:
|
||||||
|
</WRAP>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% set sanitizedMethod = method|trim('\\', 'left')|replace({(node.name~'::'): ''}) %}
|
||||||
|
{% if '::' in sanitizedMethod -%}
|
||||||
|
{%- if node.tags['phpdoc-tuning-exclude-inherited'] is not defined %}
|
||||||
|
* [[{{sanitizedMethod|replace({'::': '#'})|lower}}|↪{{sanitizedMethod}}]] — {{ method.summary|replace({"\n":""})|raw }}
|
||||||
|
{% endif %}
|
||||||
|
{%- else %}
|
||||||
|
* [[#{{sanitizedMethod}}|{{sanitizedMethod}}]] — {{ method.summary|replace({"\n":""})|raw }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{% set title_level = '==' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{%- for tagName,tags in structure.tags if tagName in tagsWithDescription -%}
|
||||||
|
{%- for tag in tags -%}
|
||||||
|
{%- if tag.description is not empty -%}
|
||||||
|
{%- if WRAP is defined -%}
|
||||||
|
<WRAP {{WRAP}}>
|
||||||
|
{%- endif -%}
|
||||||
|
{{title_level}} {{ tagName }} {{title_level}}
|
||||||
|
{{ tag.description|escape }}
|
||||||
|
{%- if WRAP is defined -%}
|
||||||
|
</WRAP>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
|
||||||
22
.doc/phpdoc-templates/combodo-wiki/includes/tags.txt.twig
Normal file
22
.doc/phpdoc-templates/combodo-wiki/includes/tags.txt.twig
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{% set title_level='=====' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if blacklist is not defined %}
|
||||||
|
{% set blacklist =['link', 'see', 'abstract', 'example', 'method', 'property', 'property-read', 'property-write', 'package', 'subpackage', 'api', 'api-advanced', 'todo', 'code-example'] %}
|
||||||
|
{% endif %}
|
||||||
|
{% if hidden_by is not defined -%}
|
||||||
|
{# Do not display @api if @api-advanced is also present #}
|
||||||
|
{%- set hidden_by = {"api" : "api-advanced"} -%}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{#^ {% for tagName,tags in structure.tags if tagName not in blacklist -%}#}
|
||||||
|
{#{{ tagName }} ^#}
|
||||||
|
{#{%- endfor %}#}
|
||||||
|
|
||||||
|
{% for tagName,tags in structure.tags if tagName not in blacklist and (hidden_by[tagName] is not defined or structure.tags[hidden_by[tagName]] is not defined) %}
|
||||||
|
{%- if loop.first %}
|
||||||
|
{{title_level}} Tags {{title_level}}
|
||||||
|
{% endif %}
|
||||||
|
^ {{ tagName }} | {% for tag in tags %}{{ tag.version ? tag.version ~ ' ' : '' }}{{ tag.description}}{% endfor %} |
|
||||||
|
{% endfor %}
|
||||||
24
.doc/phpdoc-templates/combodo-wiki/includes/used-by.txt.twig
Normal file
24
.doc/phpdoc-templates/combodo-wiki/includes/used-by.txt.twig
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{% set title_level='' %}
|
||||||
|
{% endif %}
|
||||||
|
{% for tagName,tags in structure.tags if tagName in ['used-by'] %}
|
||||||
|
{% if loop.first %}
|
||||||
|
{{title_level}} Used by {{title_level}}
|
||||||
|
{% endif %}
|
||||||
|
{% for tag in tags %}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{{ tag.reference ?: tag.link }} : {{ tag.description ?: tag.reference }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{#{% for tagName,tags in method.tags if tagName in ['uses'] %}#}
|
||||||
|
{#{% if loop.first %}#}
|
||||||
|
{#<dt>Uses</dt>#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{% for tag in tags %}#}
|
||||||
|
{#<dd>{{ tag.reference|raw }}</dd>#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
24
.doc/phpdoc-templates/combodo-wiki/includes/uses.txt.twig
Normal file
24
.doc/phpdoc-templates/combodo-wiki/includes/uses.txt.twig
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% if title_level is not defined %}
|
||||||
|
{% set title_level='' %}
|
||||||
|
{% endif %}
|
||||||
|
{% for tagName,tags in structure.tags if tagName in ['uses'] %}
|
||||||
|
{% if loop.first %}
|
||||||
|
{{title_level}} Uses {{title_level}}
|
||||||
|
{% endif %}
|
||||||
|
{% for tag in tags %}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{{ tag.reference ?: tag.link }} : {{ tag.description ?: tag.reference }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{#{% for tagName,tags in method.tags if tagName in ['uses'] %}#}
|
||||||
|
{#{% if loop.first %}#}
|
||||||
|
{#<dt>Uses</dt>#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{% for tag in tags %}#}
|
||||||
|
{#<dd>{{ tag.reference|raw }}</dd>#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{% if wrap is not defined -%}
|
||||||
|
{% set wrap = 'notice' %}
|
||||||
|
{%- endif -%}
|
||||||
|
{% if hidden_by is not defined -%}
|
||||||
|
{# Do not display @api if @api-advanced is also present #}
|
||||||
|
{%- set hidden_by = {"api" : "api-advanced"} -%}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{%- for tagName,tags in structure.tags if tagName in wrapTags and (hidden_by[tagName] is not defined or structure.tags[hidden_by[tagName]] is not defined) %}
|
||||||
|
<wrap {{wrap}}>{{tagName}}</wrap>
|
||||||
|
{% endfor %}
|
||||||
121
.doc/phpdoc-templates/combodo-wiki/interface.txt.twig
Normal file
121
.doc/phpdoc-templates/combodo-wiki/interface.txt.twig
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
{% extends 'layout.txt.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<wrap button>[[start|🔙 Back]]</wrap>
|
||||||
|
|
||||||
|
{% if node.tags['internal'] is defined %}
|
||||||
|
====== {{ node.name }} ======
|
||||||
|
<WRAP alert>This interface is "internal", and thus is not documented!</WRAP>
|
||||||
|
{% elseif node.tags['api'] is not defined and node.tags['api-advanced'] is not defined and node.tags['overwritable-hook'] is not defined and node.tags['extension-hook'] is not defined %}
|
||||||
|
====== {{ node.name }} ======
|
||||||
|
<WRAP alert>This interface is neither "api", "overwritable-hook" or "extension-hook", and thus is not documented!</WRAP>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
====== {{ node.name }} ======
|
||||||
|
|
||||||
|
{% if node.deprecated %}<wrap danger>deprecated</wrap>{% endif %}
|
||||||
|
{% if node.abstract %}<wrap warning>abstract</wrap>{% endif %}
|
||||||
|
{% if node.final %}<wrap notice>final</wrap>{% endif %}
|
||||||
|
{% include 'includes/wrap-tags.txt.twig' with {structure:node, wrap: 'safety', wrapTags: ['api', 'api-advanced', 'overwritable-hook', 'extension-hook']} %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% if node.deprecated %}
|
||||||
|
=== **<del>Deprecated</del>**===
|
||||||
|
//{{ node.tags.deprecated[0].description }}//
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
== {{ node.summary|replace({"\n":""})|raw }} ==
|
||||||
|
<html>{{ node.description|markdown|raw }}</html>
|
||||||
|
|
||||||
|
|
||||||
|
{% include 'includes/code-examples.txt.twig' with {structure:node, title_level: '====='} %}
|
||||||
|
|
||||||
|
|
||||||
|
{% set class = node.parent %}
|
||||||
|
{% block hierarchy_element %}
|
||||||
|
|
||||||
|
{% if class and class.name is defined and class.name|trim != '' %}
|
||||||
|
==== parent ====
|
||||||
|
{% set child = class %}
|
||||||
|
{% set class = class.parent %}
|
||||||
|
{{ block('hierarchy_element') }}
|
||||||
|
[[{{ child.name }}|{{ child.name }}]]
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% for interface in node.interfaces|sort_asc %}
|
||||||
|
{% if loop.first %}
|
||||||
|
==== Implements ====
|
||||||
|
{% endif %}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{{ interface.fullyQualifiedStructuralElementName ?: interface }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
{% for trait in node.usedTraits|sort_asc %}
|
||||||
|
{% if loop.first %}
|
||||||
|
==== Uses traits ====
|
||||||
|
{% endif %}
|
||||||
|
{% if loop.length > 1 %} * {% endif %}{{ trait.fullyQualifiedStructuralElementName ?: trait }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
{% include 'includes/see-also.txt.twig' with {structure:node, title_level: '==='} %}
|
||||||
|
|
||||||
|
{% include 'includes/tags.txt.twig' with {structure:node, title_level: '=====', blacklist: ['link', 'see', 'abstract', 'example', 'method', 'property', 'property-read', 'property-write', 'package', 'subpackage', 'phpdoc-tuning-exclude-inherited', 'api', 'api-advanced', 'overwritable-hook', 'extension-hook', 'copyright', 'license', 'code-example']} %}
|
||||||
|
|
||||||
|
|
||||||
|
{% set methods = node.inheritedMethods.merge(node.methods) %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'api'} %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'api-advanced'} %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'overwritable-hook'} %}
|
||||||
|
{% include 'includes/tag-synthesys.txt.twig' with {methods:methods, tag:'extension-hook'} %}
|
||||||
|
|
||||||
|
<WRAP clear />
|
||||||
|
|
||||||
|
|
||||||
|
{% for method in methods|sort_asc if method.visibility == 'public' %}
|
||||||
|
{%- if loop.first %}
|
||||||
|
===== Public methods =====
|
||||||
|
{% endif %}
|
||||||
|
{{ block('method') }}
|
||||||
|
{% endfor %}
|
||||||
|
{% for method in methods|sort_asc if method.visibility == 'protected' %}
|
||||||
|
{%- if loop.first %}
|
||||||
|
===== Protected methods =====
|
||||||
|
{% endif %}
|
||||||
|
{{ block('method') }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% set constants = node.inheritedConstants.merge(node.constants) %}
|
||||||
|
{% if constants|length > 0 %}
|
||||||
|
===== Constants =====
|
||||||
|
{% for constant in constants|sort_asc %}
|
||||||
|
{{ block('constant') }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{#{% set properties = node.inheritedProperties.merge(node.properties) %}#}
|
||||||
|
{#{% for property in properties|sort_asc if property.visibility == 'public' %}#}
|
||||||
|
{#{%- if loop.first %}#}
|
||||||
|
{#===== Public properties =====#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{{ block('property') }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% for property in properties|sort_asc if property.visibility == 'protected' %}#}
|
||||||
|
{#{%- if loop.first %}#}
|
||||||
|
{#===== Protected properties =====#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{{ block('property') }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
|
||||||
|
|
||||||
|
{%- endif %} {#{% elseif node.tags['xxx'] is not defined and ... #}
|
||||||
|
|
||||||
|
<wrap button>[[start|🔙 Back]]</wrap>
|
||||||
|
{% endblock %}
|
||||||
5
.doc/phpdoc-templates/combodo-wiki/layout.txt.twig
Normal file
5
.doc/phpdoc-templates/combodo-wiki/layout.txt.twig
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{% use 'elements/constant.txt.twig' %}
|
||||||
|
{% use 'elements/property.txt.twig' %}
|
||||||
|
{% use 'elements/method.txt.twig' %}
|
||||||
|
|
||||||
|
{% block content %}{% endblock %}
|
||||||
51
.doc/phpdoc-templates/combodo-wiki/namespace.txt.twig
Normal file
51
.doc/phpdoc-templates/combodo-wiki/namespace.txt.twig
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{% extends 'layout.txt.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% set namespace = project.namespace %}
|
||||||
|
{{ block('sidebarNamespaces') }}
|
||||||
|
|
||||||
|
{#{{ node.parent|raw }}#}
|
||||||
|
{#====== {{ node.parent.fullyQualifiedStructuralElementName }}{{ node.name }} ======#}
|
||||||
|
|
||||||
|
{% if node.children|length > 0 %}
|
||||||
|
=====Namespaces=====
|
||||||
|
{% include 'includes/namespace-structure-toc.html.twig' with {structures: node.children} %}
|
||||||
|
----
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if node.traits|length > 0 %}
|
||||||
|
===== Traits =====
|
||||||
|
{% include 'includes/namespace-structure-toc.html.twig' with {structures: node.traits} %}
|
||||||
|
----
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
{% if node.interfaces|length > 0 %}
|
||||||
|
===== Interfaces =====
|
||||||
|
{% include 'includes/namespace-structure-toc.html.twig' with {structures: node.interfaces} %}
|
||||||
|
----
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if node.classes|length > 0 %}
|
||||||
|
===== Classes =====
|
||||||
|
{% include 'includes/namespace-structure-toc.html.twig' with {structures: node.classes} %}
|
||||||
|
----
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{#{% if node.constants|length > 0 %}#}
|
||||||
|
{#===== Constants =====#}
|
||||||
|
{#{% for constant in node.constants|sort_asc %}#}
|
||||||
|
{# {{ block('constant') }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
|
||||||
|
{#{% if node.functions|length > 0 %}#}
|
||||||
|
{#===== Functions =====#}
|
||||||
|
|
||||||
|
{#{% for method in node.functions|sort_asc %}#}
|
||||||
|
{# {{ block('method') }}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
====== Deprecated elements ======
|
||||||
|
|
||||||
|
{#{% for element in project.indexes.elements if element.deprecated %}#}
|
||||||
|
{#{% if element.file.path != previousPath %}#}
|
||||||
|
{#<li><a href="#{{ element.file.path }}"><i class="icon-file"></i> {{ element.file.path }}</a></li>#}
|
||||||
|
{#{% endif %}#}
|
||||||
|
{#{% set previousPath = element.file.path %}#}
|
||||||
|
{#{% endfor %}#}
|
||||||
|
|
||||||
|
{% for element in project.indexes.elements if element.deprecated %}
|
||||||
|
{% if element.file.path != previousPath %}
|
||||||
|
{% if previousPath %}
|
||||||
|
</WRAP>{# group #}
|
||||||
|
{% endif %}
|
||||||
|
{#<a name="{{ element.file.path }}" id="{{ element.file.path }}"></a>#}
|
||||||
|
===== {{ element.file.path }} ({{ element.tags.deprecated.count }} found)=====
|
||||||
|
|
||||||
|
<WRAP group >
|
||||||
|
<WRAP third column >
|
||||||
|
Element
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
<WRAP third column >
|
||||||
|
Line
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
<WRAP third column >
|
||||||
|
Description
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% for tag in element.tags.deprecated %}
|
||||||
|
<WRAP group >
|
||||||
|
<WRAP third column >
|
||||||
|
{{ element.fullyQualifiedStructuralElementName }}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
<WRAP third column >
|
||||||
|
{{ element.line }}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
<WRAP third column >
|
||||||
|
{{ tag.description }}
|
||||||
|
</WRAP>{# third column#}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</WRAP>{# group #}
|
||||||
|
{% set previousPath = element.file.path %}
|
||||||
|
{% else %}
|
||||||
|
<WRAP info>No deprecated elements have been found in this project.</WRAP>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
27
.doc/phpdoc-templates/combodo-wiki/template.xml
Normal file
27
.doc/phpdoc-templates/combodo-wiki/template.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<template>
|
||||||
|
<author>Bruno DA SILVA</author>
|
||||||
|
<email>contact [at] combodo.com</email>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<copyright>Combodo 2018</copyright>
|
||||||
|
<description><![CDATA[
|
||||||
|
|
||||||
|
Forked from the clean theme of https://github.com/phpDocumentor/phpDocumentor2 provided under the MIT licence.
|
||||||
|
The original work is copyright "Mike van Riel".
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
To improve performance you can add the following to your .htaccess:
|
||||||
|
|
||||||
|
<ifModule mod_deflate.c>
|
||||||
|
<filesMatch "\.(js|css|html)$">
|
||||||
|
SetOutputFilter DEFLATE
|
||||||
|
</filesMatch>
|
||||||
|
</ifModule>
|
||||||
|
]]></description>
|
||||||
|
<transformations>
|
||||||
|
<transformation writer="twig" query="namespace" source="templates/combodo-wiki/namespace.txt.twig" artifact="start.txt"/>
|
||||||
|
<transformation writer="twig" query="indexes.classes" source="templates/combodo-wiki/class.txt.twig" artifact="{{name}}.txt"/>
|
||||||
|
<transformation writer="twig" query="indexes.interfaces" source="templates/combodo-wiki/interface.txt.twig" artifact="{{name}}.txt" />
|
||||||
|
</transformations>
|
||||||
|
</template>
|
||||||
@@ -25,7 +25,7 @@ if (false === file_exists($sTcPdfRootFolder)) {
|
|||||||
echo $sCurrentScriptFileName.": No TCPDF lib detected, exiting !\n";
|
echo $sCurrentScriptFileName.": No TCPDF lib detected, exiting !\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$sTcPdfFontsFolder = $sTcPdfRootFolder.'/fonts/';
|
$sTcPdfFontsFolder = $sTcPdfRootFolder.'/Fonts/';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater
|
|||||||
libxml_clear_errors();
|
libxml_clear_errors();
|
||||||
$oFileXml->formatOutput = true;
|
$oFileXml->formatOutput = true;
|
||||||
$oFileXml->preserveWhiteSpace = false;
|
$oFileXml->preserveWhiteSpace = false;
|
||||||
$oFileXml->loadXML($sFileContent, LIBXML_BIGLINES);
|
$oFileXml->loadXML($sFileContent);
|
||||||
|
|
||||||
$oFileItopFormat = new iTopDesignFormat($oFileXml);
|
$oFileItopFormat = new iTopDesignFormat($oFileXml);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
<p align="center"><a href="https://www.combodo.com/itop-193" target="_blank">
|
<p align="center"><a href="https://www.combodo.com/itop-193" target="_blank">
|
||||||
<picture>
|
<img src="https://www.combodo.com/logos/logo-itop-baseline.svg" width=350>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="/images/logos/logo-itop-baseline-light.svg">
|
|
||||||
<source media="(prefers-color-scheme: light)" srcset="/images/logos/logo-itop-baseline-dark.svg">
|
|
||||||
<img src="/images/logos/logo-itop-baseline-light.svg" width="350" alt="Logo iTop with baseline" />
|
|
||||||
</picture>
|
|
||||||
</a></p>
|
</a></p>
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +106,6 @@ We would like to give a special thank you 🤗 to the people from the community
|
|||||||
- Raenker, Martin
|
- Raenker, Martin
|
||||||
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
|
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
|
||||||
- Rosenke, Stephan
|
- Rosenke, Stephan
|
||||||
- Rossi, Tommaso (a.k.a [@tomrss](https://www.github.com/tomrss))
|
|
||||||
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
|
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
|
||||||
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
|
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
|
||||||
- Seki, Shoji
|
- Seki, Shoji
|
||||||
@@ -120,7 +115,6 @@ We would like to give a special thank you 🤗 to the people from the community
|
|||||||
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
|
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
|
||||||
- Tulio, Marco
|
- Tulio, Marco
|
||||||
- Turrubiates, Miguel
|
- Turrubiates, Miguel
|
||||||
- Vlk, Karel (a.k.a [@vlk-charles](https://www.github.com/vlk-charles))
|
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -24,29 +23,30 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class UserRightsMatrixClassGrant extends DBObject
|
class UserRightsMatrixClassGrant extends DBObject
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "addon/userrights",
|
"category" => "addon/userrights",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_ur_matrixclasses",
|
"db_table" => "priv_ur_matrixclasses",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("class", ["allowed_values" => null, "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("action", ["allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", ["allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,25 +54,25 @@ class UserRightsMatrixClassStimulusGrant extends DBObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "addon/userrights",
|
"category" => "addon/userrights",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_ur_matrixclassesstimulus",
|
"db_table" => "priv_ur_matrixclassesstimulus",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("class", ["allowed_values" => null, "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", ["allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", ["allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,39 +80,42 @@ class UserRightsMatrixAttributeGrant extends DBObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "addon/userrights",
|
"category" => "addon/userrights",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_ur_matrixattributes",
|
"db_table" => "priv_ur_matrixattributes",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("class", ["allowed_values" => null, "sql" => "class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", ["allowed_values" => null, "sql" => "attcode", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("action", ["allowed_values" => null, "sql" => "action", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", ["allowed_values" => new ValueSetEnum('yes,no'), "sql" => "permission", "default_value" => "yes", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserRightsMatrix extends UserRightsAddOnAPI
|
class UserRightsMatrix extends UserRightsAddOnAPI
|
||||||
{
|
{
|
||||||
public static $m_aActionCodes = [
|
static public $m_aActionCodes = array(
|
||||||
UR_ACTION_READ => 'read',
|
UR_ACTION_READ => 'read',
|
||||||
UR_ACTION_MODIFY => 'modify',
|
UR_ACTION_MODIFY => 'modify',
|
||||||
UR_ACTION_DELETE => 'delete',
|
UR_ACTION_DELETE => 'delete',
|
||||||
UR_ACTION_BULK_READ => 'bulk read',
|
UR_ACTION_BULK_READ => 'bulk read',
|
||||||
UR_ACTION_BULK_MODIFY => 'bulk modify',
|
UR_ACTION_BULK_MODIFY => 'bulk modify',
|
||||||
UR_ACTION_BULK_DELETE => 'bulk delete',
|
UR_ACTION_BULK_DELETE => 'bulk delete',
|
||||||
];
|
);
|
||||||
|
|
||||||
// Installation: create the very first user
|
// Installation: create the very first user
|
||||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||||
@@ -146,7 +149,8 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
// Users must be added manually
|
// Users must be added manually
|
||||||
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
||||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT User"));
|
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT User"));
|
||||||
while ($oUser = $oUserSet->Fetch()) {
|
while ($oUser = $oUserSet->Fetch())
|
||||||
|
{
|
||||||
$this->SetupUser($oUser->GetKey());
|
$this->SetupUser($oUser->GetKey());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -154,16 +158,23 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
protected function SetupUser($iUserId, $bNewUser = false)
|
protected function SetupUser($iUserId, $bNewUser = false)
|
||||||
{
|
{
|
||||||
foreach (['bizmodel', 'application', 'gui', 'core/cmdb'] as $sCategory) {
|
foreach(array('bizmodel', 'application', 'gui', 'core/cmdb') as $sCategory)
|
||||||
foreach (MetaModel::GetClasses($sCategory) as $sClass) {
|
{
|
||||||
foreach (self::$m_aActionCodes as $iActionCode => $sAction) {
|
foreach (MetaModel::GetClasses($sCategory) as $sClass)
|
||||||
if ($bNewUser) {
|
{
|
||||||
|
foreach (self::$m_aActionCodes as $iActionCode => $sAction)
|
||||||
|
{
|
||||||
|
if ($bNewUser)
|
||||||
|
{
|
||||||
$bAddCell = true;
|
$bAddCell = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = $iUserId"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = $iUserId"));
|
||||||
$bAddCell = ($oSet->Count() < 1);
|
$bAddCell = ($oSet->Count() < 1);
|
||||||
}
|
}
|
||||||
if ($bAddCell) {
|
if ($bAddCell)
|
||||||
|
{
|
||||||
// Create a new entry
|
// Create a new entry
|
||||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassGrant");
|
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassGrant");
|
||||||
$oMyClassGrant->Set("userid", $iUserId);
|
$oMyClassGrant->Set("userid", $iUserId);
|
||||||
@@ -173,14 +184,19 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) {
|
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
||||||
if ($bNewUser) {
|
{
|
||||||
|
if ($bNewUser)
|
||||||
|
{
|
||||||
$bAddCell = true;
|
$bAddCell = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = $iUserId"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = $iUserId"));
|
||||||
$bAddCell = ($oSet->Count() < 1);
|
$bAddCell = ($oSet->Count() < 1);
|
||||||
}
|
}
|
||||||
if ($bAddCell) {
|
if ($bAddCell)
|
||||||
|
{
|
||||||
// Create a new entry
|
// Create a new entry
|
||||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassStimulusGrant");
|
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassStimulusGrant");
|
||||||
$oMyClassGrant->Set("userid", $iUserId);
|
$oMyClassGrant->Set("userid", $iUserId);
|
||||||
@@ -190,15 +206,21 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode) {
|
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode)
|
||||||
if ($bNewUser) {
|
{
|
||||||
|
if ($bNewUser)
|
||||||
|
{
|
||||||
$bAddCell = true;
|
$bAddCell = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND userid = $iUserId"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND userid = $iUserId"));
|
||||||
$bAddCell = ($oSet->Count() < 1);
|
$bAddCell = ($oSet->Count() < 1);
|
||||||
}
|
}
|
||||||
if ($bAddCell) {
|
if ($bAddCell)
|
||||||
foreach (['read', 'modify'] as $sAction) {
|
{
|
||||||
|
foreach (array('read', 'modify') as $sAction)
|
||||||
|
{
|
||||||
// Create a new entry
|
// Create a new entry
|
||||||
$oMyAttGrant = MetaModel::NewObject("UserRightsMatrixAttributeGrant");
|
$oMyAttGrant = MetaModel::NewObject("UserRightsMatrixAttributeGrant");
|
||||||
$oMyAttGrant->Set("userid", $iUserId);
|
$oMyAttGrant->Set("userid", $iUserId);
|
||||||
@@ -239,13 +261,14 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function Init()
|
public function Init()
|
||||||
{
|
{
|
||||||
// Could be loaded in a shared memory (?)
|
// Could be loaded in a shared memory (?)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||||
{
|
{
|
||||||
$oNullFilter = new DBObjectSearch($sClass);
|
$oNullFilter = new DBObjectSearch($sClass);
|
||||||
return $oNullFilter;
|
return $oNullFilter;
|
||||||
@@ -253,18 +276,21 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes)) {
|
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||||
|
{
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||||
if ($oSet->Count() < 1) {
|
if ($oSet->Count() < 1)
|
||||||
|
{
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oGrantRecord = $oSet->Fetch();
|
$oGrantRecord = $oSet->Fetch();
|
||||||
switch ($oGrantRecord->Get('permission')) {
|
switch ($oGrantRecord->Get('permission'))
|
||||||
|
{
|
||||||
case 'yes':
|
case 'yes':
|
||||||
$iRetCode = UR_ALLOWED_YES;
|
$iRetCode = UR_ALLOWED_YES;
|
||||||
break;
|
break;
|
||||||
@@ -278,18 +304,21 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes)) {
|
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||||
|
{
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
|
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||||
if ($oSet->Count() < 1) {
|
if ($oSet->Count() < 1)
|
||||||
|
{
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oGrantRecord = $oSet->Fetch();
|
$oGrantRecord = $oSet->Fetch();
|
||||||
switch ($oGrantRecord->Get('permission')) {
|
switch ($oGrantRecord->Get('permission'))
|
||||||
|
{
|
||||||
case 'yes':
|
case 'yes':
|
||||||
$iRetCode = UR_ALLOWED_YES;
|
$iRetCode = UR_ALLOWED_YES;
|
||||||
break;
|
break;
|
||||||
@@ -304,12 +333,14 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||||
{
|
{
|
||||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '{$oUser->GetKey()}'"));
|
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '{$oUser->GetKey()}'"));
|
||||||
if ($oSet->Count() < 1) {
|
if ($oSet->Count() < 1)
|
||||||
|
{
|
||||||
return UR_ALLOWED_NO;
|
return UR_ALLOWED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oGrantRecord = $oSet->Fetch();
|
$oGrantRecord = $oSet->Fetch();
|
||||||
switch ($oGrantRecord->Get('permission')) {
|
switch ($oGrantRecord->Get('permission'))
|
||||||
|
{
|
||||||
case 'yes':
|
case 'yes':
|
||||||
$iRetCode = UR_ALLOWED_YES;
|
$iRetCode = UR_ALLOWED_YES;
|
||||||
break;
|
break;
|
||||||
@@ -327,3 +358,5 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsMatrix');
|
UserRights::SelectModule('UserRightsMatrix');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -48,7 +47,7 @@ class UserRightsNull extends UserRightsAddOnAPI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||||
{
|
{
|
||||||
$oNullFilter = new DBObjectSearch($sClass);
|
$oNullFilter = new DBObjectSearch($sClass);
|
||||||
return $oNullFilter;
|
return $oNullFilter;
|
||||||
@@ -75,3 +74,5 @@ class UserRightsNull extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsNull');
|
UserRights::SelectModule('UserRightsNull');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -30,52 +29,56 @@ class UserRightsBaseClassGUI extends cmdbAbstractObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class URP_Profiles extends UserRightsBaseClassGUI
|
class URP_Profiles extends UserRightsBaseClassGUI
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "addon/userrights,grant_by_profile,filter",
|
"category" => "addon/userrights,grant_by_profile,filter",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"complementary_name_attcode" => ['description'],
|
"complementary_name_attcode" => array('description'),
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_urp_profiles",
|
"db_table" => "priv_urp_profiles",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("user_list", ["linked_class" => "URP_UserProfile", "ext_key_to_me" => "profileid", "ext_key_to_remote" => "userid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("user_list", array("linked_class"=>"URP_UserProfile", "ext_key_to_me"=>"profileid", "ext_key_to_remote"=>"userid", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['name', 'description', 'user_list']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'user_list')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('description')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['name','description']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('name','description')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', ['name','description']);
|
MetaModel::Init_SetZListItems('default_search', array ('name','description'));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static $m_aCacheProfiles = null;
|
protected static $m_aCacheProfiles = null;
|
||||||
|
|
||||||
public static function DoCreateProfile($sName, $sDescription)
|
public static function DoCreateProfile($sName, $sDescription)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aCacheProfiles)) {
|
if (is_null(self::$m_aCacheProfiles))
|
||||||
self::$m_aCacheProfiles = [];
|
{
|
||||||
|
self::$m_aCacheProfiles = array();
|
||||||
$oFilterAll = new DBObjectSearch('URP_Profiles');
|
$oFilterAll = new DBObjectSearch('URP_Profiles');
|
||||||
$oSet = new DBObjectSet($oFilterAll);
|
$oSet = new DBObjectSet($oFilterAll);
|
||||||
while ($oProfile = $oSet->Fetch()) {
|
while ($oProfile = $oSet->Fetch())
|
||||||
|
{
|
||||||
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
self::$m_aCacheProfiles[$oProfile->Get('name')] = $oProfile->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sCacheKey = $sName;
|
$sCacheKey = $sName;
|
||||||
if (isset(self::$m_aCacheProfiles[$sCacheKey])) {
|
if (isset(self::$m_aCacheProfiles[$sCacheKey]))
|
||||||
|
{
|
||||||
return self::$m_aCacheProfiles[$sCacheKey];
|
return self::$m_aCacheProfiles[$sCacheKey];
|
||||||
}
|
}
|
||||||
$oNewObj = MetaModel::NewObject("URP_Profiles");
|
$oNewObj = MetaModel::NewObject("URP_Profiles");
|
||||||
@@ -86,21 +89,27 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
return $iId;
|
return $iId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
function GetGrantAsHtml($oUserRights, $sClass, $sAction)
|
||||||
{
|
{
|
||||||
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
$bGrant = $oUserRights->GetProfileActionGrant($this->GetKey(), $sClass, $sAction);
|
||||||
if (is_null($bGrant)) {
|
if (is_null($bGrant))
|
||||||
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
{
|
||||||
} elseif ($bGrant) {
|
return '<span style="background-color: #ffdddd;">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||||
return '<span class="ibo-user-rights ibo-is-success">'.Dict::S('UI:UserManagement:ActionAllowed:Yes').'</span>';
|
}
|
||||||
} else {
|
elseif ($bGrant)
|
||||||
return '<span class="ibo-user-rights ibo-is-failure">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
{
|
||||||
|
return '<span style="background-color: #ddffdd;">'.Dict::S('UI:UserManagement:ActionAllowed:Yes').'</span>';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '<span style="background-color: #ffdddd;">'.Dict::S('UI:UserManagement:ActionAllowed:No').'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DoShowGrantSumary($oPage)
|
function DoShowGrantSumary($oPage)
|
||||||
|
{
|
||||||
|
if ($this->GetRawName() == "Administrator")
|
||||||
{
|
{
|
||||||
if ($this->GetRawName() == "Administrator") {
|
|
||||||
// Looks dirty, but ok that's THE ONE
|
// Looks dirty, but ok that's THE ONE
|
||||||
$oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
|
$oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
|
||||||
return;
|
return;
|
||||||
@@ -109,18 +118,21 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
// Note: for sure, we assume that the instance is derived from UserRightsProfile
|
||||||
$oUserRights = UserRights::GetModuleInstance();
|
$oUserRights = UserRights::GetModuleInstance();
|
||||||
|
|
||||||
$aDisplayData = [];
|
$aDisplayData = array();
|
||||||
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass) {
|
foreach (MetaModel::GetClasses('bizmodel,grant_by_profile') as $sClass)
|
||||||
$aStimuli = [];
|
{
|
||||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) {
|
$aStimuli = array();
|
||||||
|
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
||||||
|
{
|
||||||
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
$bGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
|
||||||
if ($bGrant === true) {
|
if ($bGrant === true)
|
||||||
|
{
|
||||||
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
$aStimuli[] = '<span title="'.$sStimulusCode.': '.utils::EscapeHtml($oStimulus->GetDescription()).'">'.utils::EscapeHtml($oStimulus->GetLabel()).'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sStimuli = implode(', ', $aStimuli);
|
$sStimuli = implode(', ', $aStimuli);
|
||||||
|
|
||||||
$aDisplayData[] = [
|
$aDisplayData[] = array(
|
||||||
'class' => MetaModel::GetName($sClass),
|
'class' => MetaModel::GetName($sClass),
|
||||||
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'r'),
|
||||||
'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'br'),
|
'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'br'),
|
||||||
@@ -129,22 +141,22 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'd'),
|
'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'd'),
|
||||||
'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'bd'),
|
'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'bd'),
|
||||||
'stimuli' => $sStimuli,
|
'stimuli' => $sStimuli,
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$aDisplayConfig = [];
|
$aDisplayConfig = array();
|
||||||
$aDisplayConfig['class'] = ['label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+')];
|
$aDisplayConfig['class'] = array('label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+'));
|
||||||
$aDisplayConfig['read'] = ['label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+')];
|
$aDisplayConfig['read'] = array('label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+'));
|
||||||
$aDisplayConfig['bulkread'] = ['label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+')];
|
$aDisplayConfig['bulkread'] = array('label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+'));
|
||||||
$aDisplayConfig['write'] = ['label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+')];
|
$aDisplayConfig['write'] = array('label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+'));
|
||||||
$aDisplayConfig['bulkwrite'] = ['label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+')];
|
$aDisplayConfig['bulkwrite'] = array('label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+'));
|
||||||
$aDisplayConfig['delete'] = ['label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+')];
|
$aDisplayConfig['delete'] = array('label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+'));
|
||||||
$aDisplayConfig['bulkdelete'] = ['label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+')];
|
$aDisplayConfig['bulkdelete'] = array('label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+'));
|
||||||
$aDisplayConfig['stimuli'] = ['label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+')];
|
$aDisplayConfig['stimuli'] = array('label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+'));
|
||||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
function DisplayBareRelations(WebPage $oPage, $bEditMode = false)
|
||||||
{
|
{
|
||||||
parent::DisplayBareRelations($oPage, $bEditMode);
|
parent::DisplayBareRelations($oPage, $bEditMode);
|
||||||
|
|
||||||
@@ -154,9 +166,10 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
|
|
||||||
public static function GetReadOnlyAttributes()
|
public static function GetReadOnlyAttributes()
|
||||||
{
|
{
|
||||||
return ['name', 'description'];
|
return array('name', 'description');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// returns an array of id => array of column => php value(so-called "real value")
|
// returns an array of id => array of column => php value(so-called "real value")
|
||||||
public static function GetPredefinedObjects()
|
public static function GetPredefinedObjects()
|
||||||
{
|
{
|
||||||
@@ -168,13 +181,15 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
protected function OnDelete()
|
protected function OnDelete()
|
||||||
{
|
{
|
||||||
// Don't remove admin profile
|
// Don't remove admin profile
|
||||||
if ($this->Get('name') === ADMIN_PROFILE_NAME) {
|
if ($this->Get('name') === ADMIN_PROFILE_NAME)
|
||||||
|
{
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this may break the rule that says: "a user must have at least ONE profile" !
|
// Note: this may break the rule that says: "a user must have at least ONE profile" !
|
||||||
$oLnkSet = $this->Get('user_list');
|
$oLnkSet = $this->Get('user_list');
|
||||||
while ($oLnk = $oLnkSet->Fetch()) {
|
while($oLnk = $oLnkSet->Fetch())
|
||||||
|
{
|
||||||
$oLnk->DBDelete();
|
$oLnk->DBDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,10 +202,11 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
* @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
|
||||||
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
* @return integer Flags: the binary combination of the flags applicable to this attribute
|
||||||
*/
|
*/
|
||||||
public function GetAttributeFlags($sAttCode, &$aReasons = [], $sTargetState = '')
|
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
|
||||||
{
|
{
|
||||||
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
$iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||||
|
{
|
||||||
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
$aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
|
||||||
$iFlags |= OPT_ATT_READONLY;
|
$iFlags |= OPT_ATT_READONLY;
|
||||||
}
|
}
|
||||||
@@ -198,52 +214,52 @@ class URP_Profiles extends UserRightsBaseClassGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class URP_UserProfile extends UserRightsBaseClassGUI
|
class URP_UserProfile extends UserRightsBaseClassGUI
|
||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "addon/userrights,grant_by_profile,filter",
|
"category" => "addon/userrights,grant_by_profile,filter",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => ["userlogin", "profile"],
|
"name_attcode" => array("userlogin", "profile"),
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_urp_userprofile",
|
"db_table" => "priv_urp_userprofile",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"is_link" => true, /** @since 3.1.0 N°6482 */
|
"is_link" => true, /** @since 3.1.0 N°6482 */
|
||||||
'uniqueness_rules' => [
|
'uniqueness_rules' => array(
|
||||||
'no_duplicate' => [
|
'no_duplicate' => array(
|
||||||
'attributes' => [
|
'attributes' => array(
|
||||||
0 => 'userid',
|
0 => 'userid',
|
||||||
1 => 'profileid',
|
1 => 'profileid',
|
||||||
],
|
),
|
||||||
'filter' => '',
|
'filter' => '',
|
||||||
'disabled' => false,
|
'disabled' => false,
|
||||||
'is_blocking' => true,
|
'is_blocking' => true,
|
||||||
],
|
),
|
||||||
],
|
),
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login")));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey(
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid",
|
||||||
"profileid",
|
array("targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array(), "allow_target_creation" => false)));
|
||||||
["targetclass" => "URP_Profiles", "jointype" => "", "allowed_values" => null, "sql" => "profileid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => [], "allow_target_creation" => false]
|
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name")));
|
||||||
));
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("profile", ["allowed_values" => null, "extkey_attcode" => 'profileid', "target_attcode" => "name"]));
|
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reason", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['userid', 'profileid', 'reason']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('userid', 'profileid', 'reason')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['userid', 'profileid', 'reason']); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('userid', 'profileid', 'reason')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['userid', 'profileid']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('userid', 'profileid')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', ['userid', 'profileid']); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', array('userid', 'profileid')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CheckToDelete(&$oDeletionPlan)
|
public function CheckToDelete(&$oDeletionPlan)
|
||||||
@@ -251,14 +267,15 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, ['deletion not allowed in demo mode.'], true);
|
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||||
} catch (SecurityException $e) {
|
}
|
||||||
|
catch (SecurityException $e) {
|
||||||
// Users deletion is NOT allowed
|
// Users deletion is NOT allowed
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||||
@@ -275,14 +292,15 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
if (MetaModel::GetConfig()->Get('demo_mode')) {
|
||||||
// Users deletion is NOT allowed in demo mode
|
// Users deletion is NOT allowed in demo mode
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, ['deletion not allowed in demo mode.'], true);
|
$oDeletionPlan->SetDeletionIssues($this, array('deletion not allowed in demo mode.'), true);
|
||||||
$oDeletionPlan->ComputeResults();
|
$oDeletionPlan->ComputeResults();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
$this->CheckIfProfileIsAllowed(UR_ACTION_DELETE);
|
||||||
} catch (SecurityException $e) {
|
}
|
||||||
|
catch (SecurityException $e) {
|
||||||
// Users deletion is NOT allowed
|
// Users deletion is NOT allowed
|
||||||
$oDeletionPlan->AddToDelete($this, null);
|
$oDeletionPlan->AddToDelete($this, null);
|
||||||
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
$oDeletionPlan->SetDeletionIssues($this, [$e->getMessage()], true);
|
||||||
@@ -318,26 +336,29 @@ class URP_UserProfile extends UserRightsBaseClassGUI
|
|||||||
protected function CheckIfProfileIsAllowed($iActionCode)
|
protected function CheckIfProfileIsAllowed($iActionCode)
|
||||||
{
|
{
|
||||||
// When initializing or admin, we need to let everything pass trough
|
// When initializing or admin, we need to let everything pass trough
|
||||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) {
|
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only administrators can manage administrators
|
// Only administrators can manage administrators
|
||||||
$iOrigUserId = $this->GetOriginal('userid');
|
$iOrigUserId = $this->GetOriginal('userid');
|
||||||
if (!empty($iOrigUserId)) {
|
if (!empty($iOrigUserId))
|
||||||
|
{
|
||||||
$oUser = MetaModel::GetObject('User', $iOrigUserId, true, true);
|
$oUser = MetaModel::GetObject('User', $iOrigUserId, true, true);
|
||||||
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator()) {
|
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator())
|
||||||
|
{
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oUser = MetaModel::GetObject('User', $this->Get('userid'), true, true);
|
$oUser = MetaModel::GetObject('User', $this->Get('userid'), true, true);
|
||||||
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator()) {
|
if (UserRights::IsAdministrator($oUser) && !UserRights::IsAdministrator())
|
||||||
|
{
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessRestricted'));
|
||||||
}
|
}
|
||||||
if (!UserRights::IsActionAllowed(get_class($this), $iActionCode, DBObjectSet::FromObject($this))) {
|
if (!UserRights::IsActionAllowed(get_class($this), $iActionCode, DBObjectSet::FromObject($this)))
|
||||||
|
{
|
||||||
throw new SecurityException(Dict::Format('UI:Error:ObjectCannotBeUpdated'));
|
throw new SecurityException(Dict::Format('UI:Error:ObjectCannotBeUpdated'));
|
||||||
}
|
}
|
||||||
if (!UserRights::IsAdministrator() && ($this->Get('profile') === ADMIN_PROFILE_NAME)) {
|
if (!UserRights::IsAdministrator() && ($this->Get('profile') === ADMIN_PROFILE_NAME))
|
||||||
|
{
|
||||||
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
throw new SecurityException(Dict::Format('UI:Login:Error:AccessAdmin'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,33 +369,33 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "addon/userrights,grant_by_profile",
|
"category" => "addon/userrights,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => ["userlogin", "allowed_org_name"],
|
"name_attcode" => array("userlogin", "allowed_org_name"),
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_urp_userorg",
|
"db_table" => "priv_urp_userorg",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
//MetaModel::Init_InheritAttributes();
|
//MetaModel::Init_InheritAttributes();
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "userid", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", ["allowed_values" => null, "extkey_attcode" => 'userid', "target_attcode" => "login"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("userlogin", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("allowed_org_id", ["targetclass" => "Organization", "jointype" => "", "allowed_values" => null, "sql" => "allowed_org_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("allowed_org_id", array("targetclass"=>"Organization", "jointype"=> "", "allowed_values"=>null, "sql"=>"allowed_org_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("allowed_org_name", ["allowed_values" => null, "extkey_attcode" => 'allowed_org_id', "target_attcode" => "name"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("allowed_org_name", array("allowed_values"=>null, "extkey_attcode"=> 'allowed_org_id', "target_attcode"=>"name")));
|
||||||
|
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("reason", ["allowed_values" => null, "sql" => "reason", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("reason", array("allowed_values"=>null, "sql"=>"reason", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['userid', 'allowed_org_id', 'reason']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('userid', 'allowed_org_id', 'reason')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['allowed_org_id', 'reason']); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('allowed_org_id', 'reason')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['userid', 'allowed_org_id']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('userid', 'allowed_org_id')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', ['userid', 'allowed_org_id']); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', array('userid', 'allowed_org_id')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function OnInsert()
|
protected function OnInsert()
|
||||||
@@ -397,32 +418,35 @@ class URP_UserOrg extends UserRightsBaseClassGUI
|
|||||||
*/
|
*/
|
||||||
protected function CheckIfOrgIsAllowed()
|
protected function CheckIfOrgIsAllowed()
|
||||||
{
|
{
|
||||||
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) {
|
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
$oAddon = UserRights::GetModuleInstance();
|
$oAddon = UserRights::GetModuleInstance();
|
||||||
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
|
||||||
if (count($aOrgs) > 0) {
|
if (count($aOrgs) > 0)
|
||||||
|
{
|
||||||
$iOrigOrgId = $this->GetOriginal('allowed_org_id');
|
$iOrigOrgId = $this->GetOriginal('allowed_org_id');
|
||||||
if ((!empty($iOrigOrgId) && !in_array($iOrigOrgId, $aOrgs)) || !in_array($this->Get('allowed_org_id'), $aOrgs)) {
|
if ((!empty($iOrigOrgId) && !in_array($iOrigOrgId, $aOrgs)) || !in_array($this->Get('allowed_org_id'), $aOrgs))
|
||||||
|
{
|
||||||
throw new SecurityException(Dict::Format('Class:User/Error:OrganizationNotAllowed'));
|
throw new SecurityException(Dict::Format('Class:User/Error:OrganizationNotAllowed'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UserRightsProfile extends UserRightsAddOnAPI
|
class UserRightsProfile extends UserRightsAddOnAPI
|
||||||
{
|
{
|
||||||
public static $m_aActionCodes = [
|
static public $m_aActionCodes = array(
|
||||||
UR_ACTION_READ => 'r',
|
UR_ACTION_READ => 'r',
|
||||||
UR_ACTION_MODIFY => 'w',
|
UR_ACTION_MODIFY => 'w',
|
||||||
UR_ACTION_DELETE => 'd',
|
UR_ACTION_DELETE => 'd',
|
||||||
UR_ACTION_BULK_READ => 'br',
|
UR_ACTION_BULK_READ => 'br',
|
||||||
UR_ACTION_BULK_MODIFY => 'bw',
|
UR_ACTION_BULK_MODIFY => 'bw',
|
||||||
UR_ACTION_BULK_DELETE => 'bd',
|
UR_ACTION_BULK_DELETE => 'bd',
|
||||||
];
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
|
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
|
||||||
@@ -448,7 +472,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oContact = MetaModel::NewObject('Person');
|
$oContact = MetaModel::NewObject('Person');
|
||||||
$oContact->Set('name', 'My last name');
|
$oContact->Set('name', 'My last name');
|
||||||
$oContact->Set('first_name', 'My first name');
|
$oContact->Set('first_name', 'My first name');
|
||||||
if (MetaModel::IsValidAttCode('Person', 'org_id')) {
|
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
||||||
|
{
|
||||||
$oContact->Set('org_id', $iOrgId);
|
$oContact->Set('org_id', $iOrgId);
|
||||||
}
|
}
|
||||||
$oContact->Set('email', 'my.email@foo.org');
|
$oContact->Set('email', 'my.email@foo.org');
|
||||||
@@ -456,17 +481,20 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$oUser = new UserLocal();
|
$oUser = new UserLocal();
|
||||||
$oUser->Set('login', $sAdminUser);
|
$oUser->Set('login', $sAdminUser);
|
||||||
$oUser->Set('password', $sAdminPwd);
|
$oUser->Set('password', $sAdminPwd);
|
||||||
if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && ($iContactId != 0)) {
|
if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && ($iContactId != 0))
|
||||||
|
{
|
||||||
$oUser->Set('contactid', $iContactId);
|
$oUser->Set('contactid', $iContactId);
|
||||||
}
|
}
|
||||||
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
||||||
|
|
||||||
// Add this user to the very specific 'admin' profile
|
// Add this user to the very specific 'admin' profile
|
||||||
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => ADMIN_PROFILE_NAME], true /*all data*/);
|
$oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => ADMIN_PROFILE_NAME), true /*all data*/);
|
||||||
if (is_object($oAdminProfile)) {
|
if (is_object($oAdminProfile))
|
||||||
|
{
|
||||||
$oUserProfile = new URP_UserProfile();
|
$oUserProfile = new URP_UserProfile();
|
||||||
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
$oUserProfile->Set('profileid', $oAdminProfile->GetKey());
|
||||||
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
$oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
|
||||||
@@ -481,11 +509,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $m_aUserOrgs = []; // userid -> array of orgid
|
protected $m_aUserOrgs = array(); // userid -> array of orgid
|
||||||
protected $m_aAdministrators = null; // [user id]
|
protected $m_aAdministrators = null; // [user id]
|
||||||
|
|
||||||
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
|
||||||
protected $m_aObjectActionGrants = [];
|
protected $m_aObjectActionGrants = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read and cache organizations allowed to the given user
|
* Read and cache organizations allowed to the given user
|
||||||
@@ -500,25 +528,31 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function GetUserOrgs($oUser, $sClass)
|
public function GetUserOrgs($oUser, $sClass)
|
||||||
{
|
{
|
||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
if (!array_key_exists($iUser, $this->m_aUserOrgs)) {
|
if (!array_key_exists($iUser, $this->m_aUserOrgs))
|
||||||
$this->m_aUserOrgs[$iUser] = [];
|
{
|
||||||
|
$this->m_aUserOrgs[$iUser] = array();
|
||||||
|
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
|
||||||
if ($sHierarchicalKeyCode !== false) {
|
if ($sHierarchicalKeyCode !== false)
|
||||||
|
{
|
||||||
$sUserOrgQuery = 'SELECT UserOrg, Org FROM Organization AS Org JOIN Organization AS Root ON Org.'.$sHierarchicalKeyCode.' BELOW Root.id JOIN URP_UserOrg AS UserOrg ON UserOrg.allowed_org_id = Root.id WHERE UserOrg.userid = :userid';
|
$sUserOrgQuery = 'SELECT UserOrg, Org FROM Organization AS Org JOIN Organization AS Root ON Org.'.$sHierarchicalKeyCode.' BELOW Root.id JOIN URP_UserOrg AS UserOrg ON UserOrg.allowed_org_id = Root.id WHERE UserOrg.userid = :userid';
|
||||||
$oUserOrgSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData($sUserOrgQuery), [], ['userid' => $iUser]);
|
$oUserOrgSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData($sUserOrgQuery), array(), array('userid' => $iUser));
|
||||||
while ($aRow = $oUserOrgSet->FetchAssoc()) {
|
while ($aRow = $oUserOrgSet->FetchAssoc())
|
||||||
|
{
|
||||||
$oOrg = $aRow['Org'];
|
$oOrg = $aRow['Org'];
|
||||||
$this->m_aUserOrgs[$iUser][] = $oOrg->GetKey();
|
$this->m_aUserOrgs[$iUser][] = $oOrg->GetKey();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oSearch = new DBObjectSearch('URP_UserOrg');
|
$oSearch = new DBObjectSearch('URP_UserOrg');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
|
||||||
$oSearch->AddConditionExpression($oCondition);
|
$oSearch->AddConditionExpression($oCondition);
|
||||||
|
|
||||||
$oUserOrgSet = new DBObjectSet($oSearch, [], ['userid' => $iUser]);
|
$oUserOrgSet = new DBObjectSet($oSearch, array(), array('userid' => $iUser));
|
||||||
while ($oUserOrg = $oUserOrgSet->Fetch()) {
|
while ($oUserOrg = $oUserOrgSet->Fetch())
|
||||||
|
{
|
||||||
$this->m_aUserOrgs[$iUser][] = $oUserOrg->Get('allowed_org_id');
|
$this->m_aUserOrgs[$iUser][] = $oUserOrg->Get('allowed_org_id');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,19 +563,21 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
public function ResetCache()
|
public function ResetCache()
|
||||||
{
|
{
|
||||||
// Loaded by Load cache
|
// Loaded by Load cache
|
||||||
$this->m_aUserOrgs = [];
|
$this->m_aUserOrgs = array();
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
$this->m_aObjectActionGrants = [];
|
$this->m_aObjectActionGrants = array();
|
||||||
$this->m_aAdministrators = null;
|
$this->m_aAdministrators = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function LoadCache()
|
public function LoadCache()
|
||||||
{
|
{
|
||||||
static $bSharedObjectInitialized = false;
|
static $bSharedObjectInitialized = false;
|
||||||
if (!$bSharedObjectInitialized) {
|
if (!$bSharedObjectInitialized)
|
||||||
|
{
|
||||||
$bSharedObjectInitialized = true;
|
$bSharedObjectInitialized = true;
|
||||||
if (self::HasSharing()) {
|
if (self::HasSharing())
|
||||||
|
{
|
||||||
SharedObject::InitSharedClassProperties();
|
SharedObject::InitSharedClassProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,40 +615,45 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
public function ListProfiles($oUser)
|
public function ListProfiles($oUser)
|
||||||
{
|
{
|
||||||
$aRet = [];
|
$aRet = array();
|
||||||
$oSearch = new DBObjectSearch('URP_UserProfile');
|
$oSearch = new DBObjectSearch('URP_UserProfile');
|
||||||
$oSearch->AllowAllData();
|
$oSearch->AllowAllData();
|
||||||
$oSearch->NoContextParameters();
|
$oSearch->NoContextParameters();
|
||||||
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
|
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
|
||||||
$oProfiles = new DBObjectSet($oSearch);
|
$oProfiles = new DBObjectSet($oSearch);
|
||||||
while ($oUserProfile = $oProfiles->Fetch()) {
|
while ($oUserProfile = $oProfiles->Fetch())
|
||||||
|
{
|
||||||
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
|
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
|
||||||
}
|
}
|
||||||
return $aRet;
|
return $aRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSelectFilter($oUser, $sClass, $aSettings = [])
|
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||||
{
|
{
|
||||||
$this->LoadCache();
|
$this->LoadCache();
|
||||||
|
|
||||||
// Let us pass an administrator for bypassing the grant matrix check in order to test this method without the need to set up a complex profile
|
// Let us pass an administrator for bypassing the grant matrix check in order to test this method without the need to set up a complex profile
|
||||||
// In the nominal case Administrators never end up here (since they completely bypass GetSelectFilter)
|
// In the nominal case Administrators never end up here (since they completely bypass GetSelectFilter)
|
||||||
if (!static::IsAdministrator($oUser) && (MetaModel::HasCategory($sClass, 'silo') || MetaModel::HasCategory($sClass, 'bizmodel'))) {
|
if (!static::IsAdministrator($oUser) && (MetaModel::HasCategory($sClass, 'silo') || MetaModel::HasCategory($sClass, 'bizmodel')))
|
||||||
|
{
|
||||||
// N°4354 - Categories 'silo' and 'bizmodel' do check the grant matrix. Whereas 'filter' always allows to read (but the result can be filtered)
|
// N°4354 - Categories 'silo' and 'bizmodel' do check the grant matrix. Whereas 'filter' always allows to read (but the result can be filtered)
|
||||||
$aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ);
|
$aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ);
|
||||||
if ($aObjectPermissions['permission'] == UR_ALLOWED_NO) {
|
if ($aObjectPermissions['permission'] == UR_ALLOWED_NO)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oFilter = true;
|
$oFilter = true;
|
||||||
$aConditions = [];
|
$aConditions = array();
|
||||||
|
|
||||||
// Determine if this class is part of a silo and build the filter for it
|
// Determine if this class is part of a silo and build the filter for it
|
||||||
$sAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
$sAttCode = UserRights::GetOwnerOrganizationAttCode($sClass);
|
||||||
if (!is_null($sAttCode)) {
|
if (!is_null($sAttCode))
|
||||||
|
{
|
||||||
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
||||||
if (count($aUserOrgs) > 0) {
|
if (count($aUserOrgs) > 0)
|
||||||
|
{
|
||||||
$oFilter = $this->MakeSelectFilter($sClass, $aUserOrgs, $aSettings, $sAttCode);
|
$oFilter = $this->MakeSelectFilter($sClass, $aUserOrgs, $aSettings, $sAttCode);
|
||||||
}
|
}
|
||||||
// else: No org means 'any org'
|
// else: No org means 'any org'
|
||||||
@@ -621,15 +662,20 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
// Specific conditions to hide, for non-administrators, the Administrator Users, the Administrator Profile and related links
|
// Specific conditions to hide, for non-administrators, the Administrator Users, the Administrator Profile and related links
|
||||||
// Note: when logged as an administrator, GetSelectFilter is completely bypassed.
|
// Note: when logged as an administrator, GetSelectFilter is completely bypassed.
|
||||||
if ($this->AdministratorsAreHidden()) {
|
if ($this->AdministratorsAreHidden())
|
||||||
if ($sClass == 'URP_Profiles') {
|
{
|
||||||
|
if ($sClass == 'URP_Profiles')
|
||||||
|
{
|
||||||
$oExpression = new FieldExpression('id', $sClass);
|
$oExpression = new FieldExpression('id', $sClass);
|
||||||
$oScalarExpr = new ScalarExpression(1);
|
$oScalarExpr = new ScalarExpression(1);
|
||||||
|
|
||||||
$aConditions[] = new BinaryExpression($oExpression, '!=', $oScalarExpr);
|
$aConditions[] = new BinaryExpression($oExpression, '!=', $oScalarExpr);
|
||||||
} elseif (($sClass == 'URP_UserProfile') || ($sClass == 'User') || (is_subclass_of($sClass, 'User'))) {
|
}
|
||||||
|
else if (($sClass == 'URP_UserProfile') || ($sClass == 'User') || (is_subclass_of($sClass, 'User')))
|
||||||
|
{
|
||||||
$aAdministrators = $this->GetAdministrators();
|
$aAdministrators = $this->GetAdministrators();
|
||||||
if (count($aAdministrators) > 0) {
|
if (count($aAdministrators) > 0)
|
||||||
|
{
|
||||||
$sAttCode = ($sClass == 'URP_UserProfile') ? 'userid' : 'id';
|
$sAttCode = ($sClass == 'URP_UserProfile') ? 'userid' : 'id';
|
||||||
$oExpression = new FieldExpression($sAttCode, $sClass);
|
$oExpression = new FieldExpression($sAttCode, $sClass);
|
||||||
$oListExpr = ListExpression::FromScalars($aAdministrators);
|
$oListExpr = ListExpression::FromScalars($aAdministrators);
|
||||||
@@ -639,14 +685,17 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handling of the added conditions
|
// Handling of the added conditions
|
||||||
if (count($aConditions) > 0) {
|
if (count($aConditions) > 0)
|
||||||
if ($oFilter === true) {
|
{
|
||||||
|
if($oFilter === true)
|
||||||
|
{
|
||||||
// No 'silo' filter, let's build a clean one
|
// No 'silo' filter, let's build a clean one
|
||||||
$oFilter = new DBObjectSearch($sClass);
|
$oFilter = new DBObjectSearch($sClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the conditions to the filter
|
// Add the conditions to the filter
|
||||||
foreach ($aConditions as $oCondition) {
|
foreach($aConditions as $oCondition)
|
||||||
|
{
|
||||||
$oFilter->AddConditionExpression($oCondition);
|
$oFilter->AddConditionExpression($oCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -661,9 +710,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
*/
|
*/
|
||||||
private function GetAdministrators()
|
private function GetAdministrators()
|
||||||
{
|
{
|
||||||
if ($this->m_aAdministrators === null) {
|
if ($this->m_aAdministrators === null)
|
||||||
|
{
|
||||||
// Find all administrators
|
// Find all administrators
|
||||||
$this->m_aAdministrators = [];
|
$this->m_aAdministrators = array();
|
||||||
$oAdministratorsFilter = new DBObjectSearch('User');
|
$oAdministratorsFilter = new DBObjectSearch('User');
|
||||||
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
|
||||||
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
|
||||||
@@ -673,8 +723,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$oAdministratorsFilter->AddCondition_ReferencedBy($oLnkFilter, 'userid');
|
$oAdministratorsFilter->AddCondition_ReferencedBy($oLnkFilter, 'userid');
|
||||||
$oAdministratorsFilter->AllowAllData(true); // Mandatory to prevent infinite recursion !!
|
$oAdministratorsFilter->AllowAllData(true); // Mandatory to prevent infinite recursion !!
|
||||||
$oSet = new DBObjectSet($oAdministratorsFilter);
|
$oSet = new DBObjectSet($oAdministratorsFilter);
|
||||||
$oSet->OptimizeColumnLoad(['User' => ['login']]);
|
$oSet->OptimizeColumnLoad(array('User' => array('login')));
|
||||||
while ($oUser = $oSet->Fetch()) {
|
while($oUser = $oSet->Fetch())
|
||||||
|
{
|
||||||
$this->m_aAdministrators[] = $oUser->GetKey();
|
$this->m_aAdministrators[] = $oUser->GetKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -690,6 +741,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
return ((bool)MetaModel::GetConfig()->Get('security.hide_administrators'));
|
return ((bool)MetaModel::GetConfig()->Get('security.hide_administrators'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This verb has been made public to allow the development of an accurate feedback for the current configuration
|
// This verb has been made public to allow the development of an accurate feedback for the current configuration
|
||||||
public function GetProfileActionGrant($iProfile, $sClass, $sAction)
|
public function GetProfileActionGrant($iProfile, $sClass, $sAction)
|
||||||
{
|
{
|
||||||
@@ -708,9 +760,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$iUser = $oUser->GetKey();
|
$iUser = $oUser->GetKey();
|
||||||
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])){
|
if (isset($this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode])){
|
||||||
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
$aTest = $this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode];
|
||||||
if (is_array($aTest)) {
|
if (is_array($aTest)) return $aTest;
|
||||||
return $aTest;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||||
@@ -721,14 +771,20 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
|
||||||
}
|
}
|
||||||
// Call the API of UserRights because it caches the list for us
|
// Call the API of UserRights because it caches the list for us
|
||||||
foreach ($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile) {
|
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
|
||||||
|
{
|
||||||
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
|
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
|
||||||
if (!is_null($bGrant)) {
|
if (!is_null($bGrant))
|
||||||
if ($bGrant) {
|
{
|
||||||
if (is_null($bStatus)) {
|
if ($bGrant)
|
||||||
|
{
|
||||||
|
if (is_null($bStatus))
|
||||||
|
{
|
||||||
$bStatus = true;
|
$bStatus = true;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$bStatus = false;
|
$bStatus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -736,9 +792,9 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
|
|
||||||
$iPermission = $bStatus ? UR_ALLOWED_YES : UR_ALLOWED_NO;
|
$iPermission = $bStatus ? UR_ALLOWED_YES : UR_ALLOWED_NO;
|
||||||
|
|
||||||
$aRes = [
|
$aRes = array(
|
||||||
'permission' => $iPermission,
|
'permission' => $iPermission,
|
||||||
];
|
);
|
||||||
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
|
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
|
||||||
return $aRes;
|
return $aRes;
|
||||||
}
|
}
|
||||||
@@ -753,51 +809,69 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets
|
// Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets
|
||||||
// and acceptable to consider only the root class of the object set
|
// and acceptable to consider only the root class of the object set
|
||||||
|
|
||||||
if ($iPermission != UR_ALLOWED_YES) {
|
if ($iPermission != UR_ALLOWED_YES)
|
||||||
|
{
|
||||||
// It is already NO for everyone... that's the final word!
|
// It is already NO for everyone... that's the final word!
|
||||||
} elseif ($iActionCode == UR_ACTION_READ) {
|
}
|
||||||
|
elseif ($iActionCode == UR_ACTION_READ)
|
||||||
|
{
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
} elseif ($iActionCode == UR_ACTION_BULK_READ) {
|
}
|
||||||
|
elseif ($iActionCode == UR_ACTION_BULK_READ)
|
||||||
|
{
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
} elseif ($oInstanceSet) {
|
}
|
||||||
|
elseif ($oInstanceSet)
|
||||||
|
{
|
||||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||||
// We have to answer NO for objects shared for reading purposes
|
// We have to answer NO for objects shared for reading purposes
|
||||||
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
|
if (self::HasSharing())
|
||||||
|
{
|
||||||
|
$aClassProps = SharedObject::GetSharedClassProperties($sClass);
|
||||||
|
if ($aClassProps)
|
||||||
|
{
|
||||||
// This class is shared, GetSelectFilter may allow some objects for read only
|
// This class is shared, GetSelectFilter may allow some objects for read only
|
||||||
// But currently we are checking whether the objects might be written...
|
// But currently we are checking wether the objects might be written...
|
||||||
// Let's exclude the objects based on the relevant criteria
|
// Let's exclude the objects based on the relevant criteria
|
||||||
|
|
||||||
// Use $oInstanceSet only if sClass is the main class
|
$sOrgAttCode = UserRights::GetOwnerOrganizationAttCode($sClass);
|
||||||
if (!is_a($oInstanceSet->GetClass(), $sClass, true)) {
|
if (!is_null($sOrgAttCode))
|
||||||
/** @var \DBObjectSet $oInstanceSet */
|
{
|
||||||
throw new CoreException(__FUNCTION__.': Expecting object set to be of class '.$sClass.' but it is of class '.$oInstanceSet->GetClass(), ['OQL_Query' => $oInstanceSet->GetFilter()->ToOQL(), 'classes' => $oInstanceSet->GetSelectedClasses()]);
|
|
||||||
}
|
|
||||||
$sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
|
||||||
if (!is_null($sOrgAttCode)) {
|
|
||||||
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
||||||
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) {
|
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0)
|
||||||
|
{
|
||||||
$iCountNO = 0;
|
$iCountNO = 0;
|
||||||
$iCountYES = 0;
|
$iCountYES = 0;
|
||||||
$oInstanceSet->Rewind();
|
$oInstanceSet->Rewind();
|
||||||
while ($oObject = $oInstanceSet->Fetch()) {
|
while($oObject = $oInstanceSet->Fetch())
|
||||||
|
{
|
||||||
$iOrg = $oObject->Get($sOrgAttCode);
|
$iOrg = $oObject->Get($sOrgAttCode);
|
||||||
if (in_array($iOrg, $aUserOrgs)) {
|
if (in_array($iOrg, $aUserOrgs))
|
||||||
|
{
|
||||||
$iCountYES++;
|
$iCountYES++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$iCountNO++;
|
$iCountNO++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($iCountNO == 0) {
|
if ($iCountNO == 0)
|
||||||
|
{
|
||||||
$iPermission = UR_ALLOWED_YES;
|
$iPermission = UR_ALLOWED_YES;
|
||||||
} elseif ($iCountYES == 0) {
|
}
|
||||||
|
elseif ($iCountYES == 0)
|
||||||
|
{
|
||||||
$iPermission = UR_ALLOWED_NO;
|
$iPermission = UR_ALLOWED_NO;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$iPermission = UR_ALLOWED_DEPENDS;
|
$iPermission = UR_ALLOWED_DEPENDS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $iPermission;
|
return $iPermission;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,14 +906,20 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
// and acceptable to consider only the root class of the object set
|
// and acceptable to consider only the root class of the object set
|
||||||
$bStatus = null;
|
$bStatus = null;
|
||||||
// Call the API of UserRights because it caches the list for us
|
// Call the API of UserRights because it caches the list for us
|
||||||
foreach ($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile) {
|
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
|
||||||
|
{
|
||||||
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
|
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
|
||||||
if (!is_null($bGrant)) {
|
if (!is_null($bGrant))
|
||||||
if ($bGrant) {
|
{
|
||||||
if (is_null($bStatus)) {
|
if ($bGrant)
|
||||||
|
{
|
||||||
|
if (is_null($bStatus))
|
||||||
|
{
|
||||||
$bStatus = true;
|
$bStatus = true;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$bStatus = false;
|
$bStatus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -858,25 +938,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
* @param string $sClass
|
* @param string $sClass
|
||||||
* @return string|null Find out which attribute is corresponding the dimension 'owner org'
|
* @return string|null Find out which attribute is corresponding the dimension 'owner org'
|
||||||
* returns null if no such attribute has been found (no filtering should occur)
|
* returns null if no such attribute has been found (no filtering should occur)
|
||||||
|
* @deprecated 3.3.0 use @UserRights::GetOwnerOrganizationAttCode instead
|
||||||
*/
|
*/
|
||||||
public static function GetOwnerOrganizationAttCode($sClass)
|
public static function GetOwnerOrganizationAttCode($sClass)
|
||||||
{
|
{
|
||||||
$sAttCode = null;
|
return UserRights::GetOwnerOrganizationAttCode($sClass);
|
||||||
|
|
||||||
$aCallSpec = [$sClass, 'MapContextParam'];
|
|
||||||
if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization')) {
|
|
||||||
$sAttCode = 'id';
|
|
||||||
} elseif (is_callable($aCallSpec)) {
|
|
||||||
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
|
|
||||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
|
||||||
// Skip silently. The data model checker will tell you something about this...
|
|
||||||
$sAttCode = null;
|
|
||||||
}
|
|
||||||
} elseif (MetaModel::IsValidAttCode($sClass, 'org_id')) {
|
|
||||||
$sAttCode = 'org_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sAttCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -885,11 +951,15 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
|||||||
protected static function HasSharing()
|
protected static function HasSharing()
|
||||||
{
|
{
|
||||||
static $bHasSharing;
|
static $bHasSharing;
|
||||||
if (!isset($bHasSharing)) {
|
if (!isset($bHasSharing))
|
||||||
|
{
|
||||||
$bHasSharing = class_exists('SharedObject');
|
$bHasSharing = class_exists('SharedObject');
|
||||||
}
|
}
|
||||||
return $bHasSharing;
|
return $bHasSharing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UserRights::SelectModule('UserRightsProfile');
|
UserRights::SelectModule('UserRightsProfile');
|
||||||
|
|
||||||
|
?>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1
app.php
1
app.php
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -49,7 +48,8 @@ class DBSearchHelper
|
|||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
|
||||||
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
$oSearch->AddCondition_PointingTo($oHKFilter, $sAttCode);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
// If filtering fails just ignore it
|
// If filtering fails just ignore it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -17,9 +16,10 @@ use Combodo\iTop\Application\WebPage\AjaxPage;
|
|||||||
*/
|
*/
|
||||||
class ajax_page extends AjaxPage
|
class ajax_page extends AjaxPage
|
||||||
{
|
{
|
||||||
public function __construct($s_title)
|
function __construct($s_title)
|
||||||
{
|
{
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('ajax_page is deprecated. Please use AjaxPage instead');
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('ajax_page is deprecated. Please use AjaxPage instead');
|
||||||
parent::__construct($s_title);
|
parent::__construct($s_title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ApplicationContext
|
* Class ApplicationContext
|
||||||
*
|
*
|
||||||
@@ -86,6 +86,7 @@ class PortalURLMaker implements iDBObjectURLMaker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to store and manipulate the parameters that make the application's context
|
* Helper class to store and manipulate the parameters that make the application's context
|
||||||
*
|
*
|
||||||
@@ -114,10 +115,11 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function __construct($bReadContext = true)
|
public function __construct($bReadContext = true)
|
||||||
{
|
{
|
||||||
$this->aNames = [
|
$this->aNames = array(
|
||||||
'org_id', 'menu',
|
'org_id', 'menu'
|
||||||
];
|
);
|
||||||
if ($bReadContext) {
|
if ($bReadContext)
|
||||||
|
{
|
||||||
$this->ReadContext();
|
$this->ReadContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,29 +133,36 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
protected function ReadContext()
|
protected function ReadContext()
|
||||||
{
|
{
|
||||||
if (!isset(self::$aDefaultValues)) {
|
if (!isset(self::$aDefaultValues))
|
||||||
self::$aDefaultValues = [];
|
{
|
||||||
$aContext = utils::ReadParam('c', [], false, 'context_param');
|
self::$aDefaultValues = array();
|
||||||
foreach ($this->aNames as $sName) {
|
$aContext = utils::ReadParam('c', array(), false, 'context_param');
|
||||||
|
foreach($this->aNames as $sName)
|
||||||
|
{
|
||||||
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
$sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
|
||||||
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
// TO DO: check if some of the context parameters are mandatory (or have default values)
|
||||||
if (!empty($sValue)) {
|
if (!empty($sValue))
|
||||||
|
{
|
||||||
self::$aDefaultValues[$sName] = $sValue;
|
self::$aDefaultValues[$sName] = $sValue;
|
||||||
}
|
}
|
||||||
// Hmm, there must be a better (more generic) way to handle the case below:
|
// Hmm, there must be a better (more generic) way to handle the case below:
|
||||||
// When there is only one possible (allowed) organization, the context must be
|
// When there is only one possible (allowed) organization, the context must be
|
||||||
// fixed to this org unless there is only one organization in the system then
|
// fixed to this org unless there is only one organization in the system then
|
||||||
// no filter is applied
|
// no filter is applied
|
||||||
if ($sName == 'org_id') {
|
if ($sName == 'org_id')
|
||||||
if (MetaModel::IsValidClass('Organization')) {
|
{
|
||||||
|
if (MetaModel::IsValidClass('Organization'))
|
||||||
|
{
|
||||||
$oSearchFilter = new DBObjectSearch('Organization');
|
$oSearchFilter = new DBObjectSearch('Organization');
|
||||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||||
$iCount = $oSet->CountWithLimit(2);
|
$iCount = $oSet->CountWithLimit(2);
|
||||||
if ($iCount > 1) {
|
if ($iCount > 1)
|
||||||
|
{
|
||||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||||
$iCount = $oSet->CountWithLimit(2);
|
$iCount = $oSet->CountWithLimit(2);
|
||||||
if ($iCount == 1) {
|
if ($iCount == 1)
|
||||||
|
{
|
||||||
// Only one possible value for org_id, set it in the context
|
// Only one possible value for org_id, set it in the context
|
||||||
$oOrg = $oSet->Fetch();
|
$oOrg = $oSet->Fetch();
|
||||||
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
self::$aDefaultValues[$sName] = $oOrg->GetKey();
|
||||||
@@ -176,7 +185,8 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function GetCurrentValue($sParamName, $defaultValue = '')
|
public function GetCurrentValue($sParamName, $defaultValue = '')
|
||||||
{
|
{
|
||||||
if (isset($this->aValues[$sParamName])) {
|
if (isset($this->aValues[$sParamName]))
|
||||||
|
{
|
||||||
return $this->aValues[$sParamName];
|
return $this->aValues[$sParamName];
|
||||||
}
|
}
|
||||||
return $defaultValue;
|
return $defaultValue;
|
||||||
@@ -185,30 +195,16 @@ class ApplicationContext
|
|||||||
/**
|
/**
|
||||||
* Returns the context as string with the format name1=value1&name2=value2....
|
* Returns the context as string with the format name1=value1&name2=value2....
|
||||||
* @return string The context as a string to be appended to an href property
|
* @return string The context as a string to be appended to an href property
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public function GetForLink(bool $bWithLeadingAmpersand = false)
|
public function GetForLink()
|
||||||
|
{
|
||||||
|
$aParams = array();
|
||||||
|
foreach($this->aValues as $sName => $sValue)
|
||||||
{
|
{
|
||||||
// If there are no parameters, return an empty string
|
|
||||||
if (empty($this->aValues)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the query string with ampersand separated parameters
|
|
||||||
$aParams = [];
|
|
||||||
foreach ($this->aValues as $sName => $sValue) {
|
|
||||||
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
$sReturnValue = implode('&', $aParams);
|
return implode("&", $aParams);
|
||||||
|
|
||||||
// add the leading ampersand if requested
|
|
||||||
if ($bWithLeadingAmpersand) {
|
|
||||||
$sReturnValue = '&'.$sReturnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0.0 N°2534 - dashboard: bug with autorefresh that deactivates filtering on organisation
|
* @since 3.0.0 N°2534 - dashboard: bug with autorefresh that deactivates filtering on organisation
|
||||||
* Returns the params as c[menu]:..., c[org_id]:....
|
* Returns the params as c[menu]:..., c[org_id]:....
|
||||||
@@ -267,8 +263,9 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function GetAsHash()
|
public function GetAsHash()
|
||||||
{
|
{
|
||||||
$aReturn = [];
|
$aReturn = array();
|
||||||
foreach ($this->aValues as $sName => $sValue) {
|
foreach($this->aValues as $sName => $sValue)
|
||||||
|
{
|
||||||
$aReturn["c[$sName]"] = $sValue;
|
$aReturn["c[$sName]"] = $sValue;
|
||||||
}
|
}
|
||||||
return $aReturn;
|
return $aReturn;
|
||||||
@@ -289,7 +286,8 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public function Reset($sParamName)
|
public function Reset($sParamName)
|
||||||
{
|
{
|
||||||
if (isset($this->aValues[$sParamName])) {
|
if (isset($this->aValues[$sParamName]))
|
||||||
|
{
|
||||||
unset($this->aValues[$sParamName]);
|
unset($this->aValues[$sParamName]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,16 +303,21 @@ class ApplicationContext
|
|||||||
public function InitObjectFromContext(DBObject &$oObj)
|
public function InitObjectFromContext(DBObject &$oObj)
|
||||||
{
|
{
|
||||||
$sClass = get_class($oObj);
|
$sClass = get_class($oObj);
|
||||||
foreach ($this->GetNames() as $key) {
|
foreach($this->GetNames() as $key)
|
||||||
$aCallSpec = [$sClass, 'MapContextParam'];
|
{
|
||||||
if (is_callable($aCallSpec)) {
|
$aCallSpec = array($sClass, 'MapContextParam');
|
||||||
|
if (is_callable($aCallSpec))
|
||||||
|
{
|
||||||
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
$sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
|
||||||
|
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
|
||||||
|
{
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef->IsWritable()) {
|
if ($oAttDef->IsWritable())
|
||||||
|
{
|
||||||
$value = $this->GetCurrentValue($key, null);
|
$value = $this->GetCurrentValue($key, null);
|
||||||
if (!is_null($value)) {
|
if (!is_null($value))
|
||||||
|
{
|
||||||
$oObj->Set($sAttCode, $value);
|
$oObj->Set($sAttCode, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,10 +347,14 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function GetUrlMakerClass()
|
public static function GetUrlMakerClass()
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_sUrlMakerClass)) {
|
if (is_null(self::$m_sUrlMakerClass))
|
||||||
if (Session::IsSet('UrlMakerClass')) {
|
{
|
||||||
|
if (Session::IsSet('UrlMakerClass'))
|
||||||
|
{
|
||||||
self::$m_sUrlMakerClass = Session::Get('UrlMakerClass');
|
self::$m_sUrlMakerClass = Session::Get('UrlMakerClass');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,10 +379,10 @@ class ApplicationContext
|
|||||||
if (is_null($sUrlMakerClass)) {
|
if (is_null($sUrlMakerClass)) {
|
||||||
$sUrlMakerClass = self::GetUrlMakerClass();
|
$sUrlMakerClass = self::GetUrlMakerClass();
|
||||||
}
|
}
|
||||||
$sUrl = call_user_func([$sUrlMakerClass, 'MakeObjectUrl'], $sObjClass, $sObjKey);
|
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
|
||||||
if (utils::StrLen($sUrl) > 0) {
|
if (utils::StrLen($sUrl) > 0) {
|
||||||
if ($bWithNavigationContext) {
|
if ($bWithNavigationContext) {
|
||||||
return $sUrl.$oAppContext->GetForLink(true);
|
return $sUrl."&".$oAppContext->GetForLink();
|
||||||
} else {
|
} else {
|
||||||
return $sUrl;
|
return $sUrl;
|
||||||
}
|
}
|
||||||
@@ -390,10 +397,13 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
protected static function LoadPluginProperties()
|
protected static function LoadPluginProperties()
|
||||||
{
|
{
|
||||||
if (Session::IsSet('PluginProperties')) {
|
if (Session::IsSet('PluginProperties'))
|
||||||
|
{
|
||||||
self::$m_aPluginProperties = Session::Get('PluginProperties');
|
self::$m_aPluginProperties = Session::Get('PluginProperties');
|
||||||
} else {
|
}
|
||||||
self::$m_aPluginProperties = [];
|
else
|
||||||
|
{
|
||||||
|
self::$m_aPluginProperties = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,9 +416,7 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
public static function SetPluginProperty($sPluginClass, $sProperty, $value)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aPluginProperties)) {
|
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
||||||
self::LoadPluginProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
self::$m_aPluginProperties[$sPluginClass][$sProperty] = $value;
|
||||||
Session::Set(['PluginProperties', $sPluginClass, $sProperty], $value);
|
Session::Set(['PluginProperties', $sPluginClass, $sProperty], $value);
|
||||||
@@ -421,14 +429,15 @@ class ApplicationContext
|
|||||||
*/
|
*/
|
||||||
public static function GetPluginProperties($sPluginClass)
|
public static function GetPluginProperties($sPluginClass)
|
||||||
{
|
{
|
||||||
if (is_null(self::$m_aPluginProperties)) {
|
if (is_null(self::$m_aPluginProperties)) self::LoadPluginProperties();
|
||||||
self::LoadPluginProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists($sPluginClass, self::$m_aPluginProperties)) {
|
if (array_key_exists($sPluginClass, self::$m_aPluginProperties))
|
||||||
|
{
|
||||||
return self::$m_aPluginProperties[$sPluginClass];
|
return self::$m_aPluginProperties[$sPluginClass];
|
||||||
} else {
|
}
|
||||||
return [];
|
else
|
||||||
|
{
|
||||||
|
return array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
*/
|
*/
|
||||||
public function EnumUsedAttributes($oObject)
|
public function EnumUsedAttributes($oObject)
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -548,7 +548,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
|||||||
*/
|
*/
|
||||||
public function EnumAllowedActions(DBObjectSet $oSet)
|
public function EnumAllowedActions(DBObjectSet $oSet)
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -686,7 +686,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE
|
|||||||
*/
|
*/
|
||||||
public function OnCheckToWrite($oObject)
|
public function OnCheckToWrite($oObject)
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -694,7 +694,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE
|
|||||||
*/
|
*/
|
||||||
public function OnCheckToDelete($oObject)
|
public function OnCheckToDelete($oObject)
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -739,21 +739,21 @@ interface iPopupMenuExtension
|
|||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MENU_OBJLIST_ACTIONS = 1;
|
const MENU_OBJLIST_ACTIONS = 1;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Toolkit menu of a list
|
* Insert an item into the Toolkit menu of a list
|
||||||
*
|
*
|
||||||
* $param is a DBObjectSet containing the list of objects
|
* $param is a DBObjectSet containing the list of objects
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MENU_OBJLIST_TOOLKIT = 2;
|
const MENU_OBJLIST_TOOLKIT = 2;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Actions menu on an object details page
|
* Insert an item into the Actions menu on an object details page
|
||||||
*
|
*
|
||||||
* $param is a DBObject instance: the object currently displayed
|
* $param is a DBObject instance: the object currently displayed
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MENU_OBJDETAILS_ACTIONS = 3;
|
const MENU_OBJDETAILS_ACTIONS = 3;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Dashboard menu
|
* Insert an item into the Dashboard menu
|
||||||
*
|
*
|
||||||
@@ -763,14 +763,14 @@ interface iPopupMenuExtension
|
|||||||
* $param is a Dashboard instance: the dashboard currently displayed
|
* $param is a Dashboard instance: the dashboard currently displayed
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MENU_DASHBOARD_ACTIONS = 4;
|
const MENU_DASHBOARD_ACTIONS = 4;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the User menu (upper right corner)
|
* Insert an item into the User menu (upper right corner)
|
||||||
*
|
*
|
||||||
* $param is null
|
* $param is null
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MENU_USER_ACTIONS = 5;
|
const MENU_USER_ACTIONS = 5;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Action menu on an object item in an objects list in the portal
|
* Insert an item into the Action menu on an object item in an objects list in the portal
|
||||||
*
|
*
|
||||||
@@ -778,7 +778,7 @@ interface iPopupMenuExtension
|
|||||||
* the current line)
|
* the current line)
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Action menu on an object details page in the portal
|
* Insert an item into the Action menu on an object details page in the portal
|
||||||
*
|
*
|
||||||
@@ -786,7 +786,7 @@ interface iPopupMenuExtension
|
|||||||
* currently displayed)
|
* currently displayed)
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const PORTAL_OBJDETAILS_ACTIONS = 8;
|
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert an item into the Actions menu of a list in the portal
|
* Insert an item into the Actions menu of a list in the portal
|
||||||
@@ -796,7 +796,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
public const PORTAL_OBJLIST_ACTIONS = 6;
|
const PORTAL_OBJLIST_ACTIONS = 6;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the user menu of the portal
|
* Insert an item into the user menu of the portal
|
||||||
* Note: This is not implemented yet !
|
* Note: This is not implemented yet !
|
||||||
@@ -805,7 +805,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
public const PORTAL_USER_ACTIONS = 9;
|
const PORTAL_USER_ACTIONS = 9;
|
||||||
/**
|
/**
|
||||||
* Insert an item into the navigation menu of the portal
|
* Insert an item into the navigation menu of the portal
|
||||||
* Note: This is not implemented yet !
|
* Note: This is not implemented yet !
|
||||||
@@ -814,7 +814,7 @@ interface iPopupMenuExtension
|
|||||||
*
|
*
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
public const PORTAL_MENU_ACTIONS = 10;
|
const PORTAL_MENU_ACTIONS = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of items to be added to a menu.
|
* Get the list of items to be added to a menu.
|
||||||
@@ -864,7 +864,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
$this->sLabel = $sLabel;
|
$this->sLabel = $sLabel;
|
||||||
$this->sTooltip = '';
|
$this->sTooltip = '';
|
||||||
$this->sIconClass = '';
|
$this->sIconClass = '';
|
||||||
$this->aCssClasses = [];
|
$this->aCssClasses = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -920,6 +920,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
$this->aCssClasses[] = $sCssClass;
|
$this->aCssClasses[] = $sCssClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sTooltip
|
* @param $sTooltip
|
||||||
*
|
*
|
||||||
@@ -975,7 +976,7 @@ abstract class ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetLinkedScripts()
|
public function GetLinkedScripts()
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,13 +1015,13 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return ['label' => $this->GetLabel(),
|
return array('label' => $this->GetLabel(),
|
||||||
'url' => $this->GetUrl(),
|
'url' => $this->GetUrl(),
|
||||||
'target' => $this-> GetTarget(),
|
'target' => $this-> GetTarget(),
|
||||||
'css_classes' => $this->aCssClasses,
|
'css_classes' => $this->aCssClasses,
|
||||||
'icon_class' => $this->sIconClass,
|
'icon_class' => $this->sIconClass,
|
||||||
'tooltip' => $this->sTooltip,
|
'tooltip' => $this->sTooltip
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
@@ -1064,7 +1065,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
* ans $sTarget will be ignored
|
* ans $sTarget will be ignored
|
||||||
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
||||||
*/
|
*/
|
||||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = [])
|
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
||||||
{
|
{
|
||||||
parent::__construct($sUID, $sLabel);
|
parent::__construct($sUID, $sLabel);
|
||||||
$this->sJsCode = $sJSCode;
|
$this->sJsCode = $sJSCode;
|
||||||
@@ -1076,14 +1077,14 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
// Note: the semicolumn is a must here!
|
// Note: the semicolumn is a must here!
|
||||||
return [
|
return array(
|
||||||
'label' => $this->GetLabel(),
|
'label' => $this->GetLabel(),
|
||||||
'onclick' => $this->GetJsCode().'; return false;',
|
'onclick' => $this->GetJsCode().'; return false;',
|
||||||
'url' => $this->GetUrl(),
|
'url' => $this->GetUrl(),
|
||||||
'css_classes' => $this->GetCssClasses(),
|
'css_classes' => $this->GetCssClasses(),
|
||||||
'icon_class' => $this->sIconClass,
|
'icon_class' => $this->sIconClass,
|
||||||
'tooltip' => $this->sTooltip,
|
'tooltip' => $this->sTooltip
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ignore */
|
/** @ignore */
|
||||||
@@ -1115,7 +1116,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||||
{
|
{
|
||||||
public static $idx = 0;
|
static $idx = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
@@ -1129,7 +1130,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
/** @ignore */
|
/** @ignore */
|
||||||
public function GetMenuItem()
|
public function GetMenuItem()
|
||||||
{
|
{
|
||||||
return ['label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses];
|
return array('label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1142,6 +1143,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
class URLButtonItem extends URLPopupMenuItem
|
class URLButtonItem extends URLPopupMenuItem
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1153,6 +1155,7 @@ class URLButtonItem extends URLPopupMenuItem
|
|||||||
*/
|
*/
|
||||||
class JSButtonItem extends JSPopupMenuItem
|
class JSButtonItem extends JSPopupMenuItem
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1501,9 +1504,9 @@ interface iBackofficeDictEntriesPrefixesExtension
|
|||||||
*/
|
*/
|
||||||
interface iPortalUIExtension
|
interface iPortalUIExtension
|
||||||
{
|
{
|
||||||
public const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
||||||
public const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
||||||
public const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of CSS file urls
|
* Returns an array of CSS file urls
|
||||||
@@ -1590,7 +1593,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
*/
|
*/
|
||||||
public function GetCSSFiles(Container $oContainer)
|
public function GetCSSFiles(Container $oContainer)
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1606,7 +1609,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
|||||||
*/
|
*/
|
||||||
public function GetJSFiles(Container $oContainer)
|
public function GetJSFiles(Container $oContainer)
|
||||||
{
|
{
|
||||||
return [];
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1708,11 +1711,6 @@ interface iRestServiceProvider
|
|||||||
public function ExecOperation($sVersion, $sVerb, $aParams);
|
public function ExecOperation($sVersion, $sVerb, $aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface iRestInputSanitizer
|
|
||||||
{
|
|
||||||
public function SanitizeJsonInput(string $sJsonInput): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal REST response structure. Derive this structure to add response data and error codes.
|
* Minimal REST response structure. Derive this structure to add response data and error codes.
|
||||||
*
|
*
|
||||||
@@ -1726,62 +1724,62 @@ class RestResult
|
|||||||
* Result: no issue has been encountered
|
* Result: no issue has been encountered
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const OK = 0;
|
const OK = 0;
|
||||||
/**
|
/**
|
||||||
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const UNAUTHORIZED = 1;
|
const UNAUTHORIZED = 1;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'version' is missing
|
* Result: the parameter 'version' is missing
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MISSING_VERSION = 2;
|
const MISSING_VERSION = 2;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'json_data' is missing
|
* Result: the parameter 'json_data' is missing
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MISSING_JSON = 3;
|
const MISSING_JSON = 3;
|
||||||
/**
|
/**
|
||||||
* Result: the input structure is not a valid JSON string
|
* Result: the input structure is not a valid JSON string
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const INVALID_JSON = 4;
|
const INVALID_JSON = 4;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MISSING_AUTH_USER = 5;
|
const MISSING_AUTH_USER = 5;
|
||||||
/**
|
/**
|
||||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const MISSING_AUTH_PWD = 6;
|
const MISSING_AUTH_PWD = 6;
|
||||||
/**
|
/**
|
||||||
* Result: no operation is available for the specified version
|
* Result: no operation is available for the specified version
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const UNSUPPORTED_VERSION = 10;
|
const UNSUPPORTED_VERSION = 10;
|
||||||
/**
|
/**
|
||||||
* Result: the requested operation is not valid for the specified version
|
* Result: the requested operation is not valid for the specified version
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const UNKNOWN_OPERATION = 11;
|
const UNKNOWN_OPERATION = 11;
|
||||||
/**
|
/**
|
||||||
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const UNSAFE = 12;
|
const UNSAFE = 12;
|
||||||
/**
|
/**
|
||||||
* Result: the request page number is not valid. It must be an integer greater than 0
|
* Result: the request page number is not valid. It must be an integer greater than 0
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const INVALID_PAGE = 13;
|
const INVALID_PAGE = 13;
|
||||||
/**
|
/**
|
||||||
* Result: the operation could not be performed, see the message for troubleshooting
|
* Result: the operation could not be performed, see the message for troubleshooting
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public const INTERNAL_ERROR = 100;
|
const INTERNAL_ERROR = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor - ok!
|
* Default constructor - ok!
|
||||||
@@ -1804,14 +1802,6 @@ class RestResult
|
|||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public $message;
|
public $message;
|
||||||
|
|
||||||
/**
|
|
||||||
* Sanitize the content of this result to hide sensitive information
|
|
||||||
*/
|
|
||||||
public function SanitizeContent()
|
|
||||||
{
|
|
||||||
// The default implementation does nothing
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1851,13 +1841,17 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function GetMandatoryParam($oData, $sParamName)
|
public static function GetMandatoryParam($oData, $sParamName)
|
||||||
{
|
{
|
||||||
if (isset($oData->$sParamName)) {
|
if (isset($oData->$sParamName))
|
||||||
|
{
|
||||||
return $oData->$sParamName;
|
return $oData->$sParamName;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new Exception("Missing parameter '$sParamName'");
|
throw new Exception("Missing parameter '$sParamName'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read an optional parameter from a Rest/Json structure.
|
* Read an optional parameter from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -1872,13 +1866,17 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function GetOptionalParam($oData, $sParamName, $default)
|
public static function GetOptionalParam($oData, $sParamName, $default)
|
||||||
{
|
{
|
||||||
if (isset($oData->$sParamName)) {
|
if (isset($oData->$sParamName))
|
||||||
|
{
|
||||||
return $oData->$sParamName;
|
return $oData->$sParamName;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a class from a Rest/Json structure.
|
* Read a class from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -1892,13 +1890,15 @@ class RestUtils
|
|||||||
public static function GetClass($oData, $sParamName)
|
public static function GetClass($oData, $sParamName)
|
||||||
{
|
{
|
||||||
$sClass = self::GetMandatoryParam($oData, $sParamName);
|
$sClass = self::GetMandatoryParam($oData, $sParamName);
|
||||||
if (!MetaModel::IsValidClass($sClass)) {
|
if (!MetaModel::IsValidClass($sClass))
|
||||||
|
{
|
||||||
throw new Exception("$sParamName: '$sClass' is not a valid class'");
|
throw new Exception("$sParamName: '$sClass' is not a valid class'");
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sClass;
|
return $sClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a list of attribute codes from a Rest/Json structure.
|
* Read a list of attribute codes from a Rest/Json structure.
|
||||||
*
|
*
|
||||||
@@ -1914,21 +1914,31 @@ class RestUtils
|
|||||||
public static function GetFieldList($sClass, $oData, $sParamName)
|
public static function GetFieldList($sClass, $oData, $sParamName)
|
||||||
{
|
{
|
||||||
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
||||||
$aShowFields = [];
|
$aShowFields = array();
|
||||||
if ($sFields == '*') {
|
if ($sFields == '*')
|
||||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
{
|
||||||
|
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||||
|
{
|
||||||
$aShowFields[$sClass][] = $sAttCode;
|
$aShowFields[$sClass][] = $sAttCode;
|
||||||
}
|
}
|
||||||
} elseif ($sFields == '*+') {
|
}
|
||||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass) {
|
elseif ($sFields == '*+')
|
||||||
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef) {
|
{
|
||||||
|
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass)
|
||||||
|
{
|
||||||
|
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef)
|
||||||
|
{
|
||||||
$aShowFields[$sRefClass][] = $sAttCode;
|
$aShowFields[$sRefClass][] = $sAttCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
foreach (explode(',', $sFields) as $sAttCode) {
|
else
|
||||||
|
{
|
||||||
|
foreach (explode(',', $sFields) as $sAttCode)
|
||||||
|
{
|
||||||
$sAttCode = trim($sAttCode);
|
$sAttCode = trim($sAttCode);
|
||||||
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode))) {
|
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode)))
|
||||||
|
{
|
||||||
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
||||||
}
|
}
|
||||||
$aShowFields[$sClass][] = $sAttCode;
|
$aShowFields[$sClass][] = $sAttCode;
|
||||||
@@ -1951,30 +1961,38 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
||||||
{
|
{
|
||||||
$aCriteriaReport = [];
|
$aCriteriaReport = array();
|
||||||
if (isset($oCriteria->finalclass)) {
|
if (isset($oCriteria->finalclass))
|
||||||
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
|
{
|
||||||
|
if (!MetaModel::IsValidClass($oCriteria->finalclass))
|
||||||
|
{
|
||||||
throw new Exception("finalclass: Unknown class '".$oCriteria->finalclass."'");
|
throw new Exception("finalclass: Unknown class '".$oCriteria->finalclass."'");
|
||||||
}
|
}
|
||||||
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
|
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass))
|
||||||
|
{
|
||||||
throw new Exception("finalclass: '".$oCriteria->finalclass."' is not a child class of '$sClass'");
|
throw new Exception("finalclass: '".$oCriteria->finalclass."' is not a child class of '$sClass'");
|
||||||
}
|
}
|
||||||
$sClass = $oCriteria->finalclass;
|
$sClass = $oCriteria->finalclass;
|
||||||
}
|
}
|
||||||
$oSearch = new DBObjectSearch($sClass);
|
$oSearch = new DBObjectSearch($sClass);
|
||||||
foreach ($oCriteria as $sAttCode => $value) {
|
foreach ($oCriteria as $sAttCode => $value)
|
||||||
|
{
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||||
if (is_object($value) || is_array($value)) {
|
if (is_object($value) || is_array($value))
|
||||||
|
{
|
||||||
$value = json_encode($value);
|
$value = json_encode($value);
|
||||||
}
|
}
|
||||||
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
|
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
|
||||||
}
|
}
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->Count();
|
$iCount = $oSet->Count();
|
||||||
if ($iCount == 0) {
|
if ($iCount == 0)
|
||||||
|
{
|
||||||
throw new Exception("No item found with criteria: ".implode(', ', $aCriteriaReport));
|
throw new Exception("No item found with criteria: ".implode(', ', $aCriteriaReport));
|
||||||
} elseif ($iCount > 1) {
|
}
|
||||||
|
elseif ($iCount > 1)
|
||||||
|
{
|
||||||
throw new Exception("Several items found ($iCount) with criteria: ".implode(', ', $aCriteriaReport));
|
throw new Exception("Several items found ($iCount) with criteria: ".implode(', ', $aCriteriaReport));
|
||||||
}
|
}
|
||||||
$res = $oSet->Fetch();
|
$res = $oSet->Fetch();
|
||||||
@@ -1982,6 +2000,7 @@ class RestUtils
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find an object from a polymorph search specification (Rest/Json)
|
* Find an object from a polymorph search specification (Rest/Json)
|
||||||
*
|
*
|
||||||
@@ -1997,29 +2016,43 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
|
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
|
||||||
{
|
{
|
||||||
if (is_object($key)) {
|
if (is_object($key))
|
||||||
|
{
|
||||||
$res = static::FindObjectFromCriteria($sClass, $key);
|
$res = static::FindObjectFromCriteria($sClass, $key);
|
||||||
} elseif (is_numeric($key)) {
|
}
|
||||||
if ($bAllowNullValue && ($key == 0)) {
|
elseif (is_numeric($key))
|
||||||
|
{
|
||||||
|
if ($bAllowNullValue && ($key == 0))
|
||||||
|
{
|
||||||
$res = null;
|
$res = null;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$res = MetaModel::GetObject($sClass, $key, false);
|
$res = MetaModel::GetObject($sClass, $key, false);
|
||||||
if (is_null($res)) {
|
if (is_null($res))
|
||||||
|
{
|
||||||
throw new Exception("Invalid object $sClass::$key");
|
throw new Exception("Invalid object $sClass::$key");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif (is_string($key)) {
|
}
|
||||||
|
elseif (is_string($key))
|
||||||
|
{
|
||||||
// OQL
|
// OQL
|
||||||
$oSearch = DBObjectSearch::FromOQL($key);
|
$oSearch = DBObjectSearch::FromOQL($key);
|
||||||
$oSet = new DBObjectSet($oSearch);
|
$oSet = new DBObjectSet($oSearch);
|
||||||
$iCount = $oSet->Count();
|
$iCount = $oSet->Count();
|
||||||
if ($iCount == 0) {
|
if ($iCount == 0)
|
||||||
|
{
|
||||||
throw new Exception("No item found for query: $key");
|
throw new Exception("No item found for query: $key");
|
||||||
} elseif ($iCount > 1) {
|
}
|
||||||
|
elseif ($iCount > 1)
|
||||||
|
{
|
||||||
throw new Exception("Several items found ($iCount) for query: $key");
|
throw new Exception("Several items found ($iCount) for query: $key");
|
||||||
}
|
}
|
||||||
$res = $oSet->Fetch();
|
$res = $oSet->Fetch();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new Exception("Wrong format for key");
|
throw new Exception("Wrong format for key");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2040,23 +2073,31 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
||||||
{
|
{
|
||||||
if (is_object($key)) {
|
if (is_object($key))
|
||||||
if (isset($key->finalclass)) {
|
{
|
||||||
|
if (isset($key->finalclass))
|
||||||
|
{
|
||||||
$sClass = $key->finalclass;
|
$sClass = $key->finalclass;
|
||||||
if (!MetaModel::IsValidClass($sClass)) {
|
if (!MetaModel::IsValidClass($sClass))
|
||||||
|
{
|
||||||
throw new Exception("finalclass: Unknown class '$sClass'");
|
throw new Exception("finalclass: Unknown class '$sClass'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oSearch = new DBObjectSearch($sClass);
|
$oSearch = new DBObjectSearch($sClass);
|
||||||
foreach ($key as $sAttCode => $value) {
|
foreach ($key as $sAttCode => $value)
|
||||||
|
{
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||||
}
|
}
|
||||||
} elseif (is_numeric($key)) {
|
}
|
||||||
|
elseif (is_numeric($key))
|
||||||
|
{
|
||||||
$oSearch = new DBObjectSearch($sClass);
|
$oSearch = new DBObjectSearch($sClass);
|
||||||
$oSearch->AddCondition('id', $key);
|
$oSearch->AddCondition('id', $key);
|
||||||
} elseif (is_string($key)) {
|
}
|
||||||
|
elseif (is_string($key))
|
||||||
|
{
|
||||||
// OQL
|
// OQL
|
||||||
try {
|
try {
|
||||||
$oSearch = DBObjectSearch::FromOQL($key);
|
$oSearch = DBObjectSearch::FromOQL($key);
|
||||||
@@ -2067,10 +2108,12 @@ class RestUtils
|
|||||||
'exception_message' => $e->getMessage(),
|
'exception_message' => $e->getMessage(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
throw new Exception("Wrong format for key");
|
throw new Exception("Wrong format for key");
|
||||||
}
|
}
|
||||||
$oObjectSet = new DBObjectSet($oSearch, [], [], null, $iLimit, $iOffset);
|
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
|
||||||
|
|
||||||
return $oObjectSet;
|
return $oObjectSet;
|
||||||
}
|
}
|
||||||
@@ -2088,38 +2131,53 @@ class RestUtils
|
|||||||
*/
|
*/
|
||||||
public static function MakeValue($sClass, $sAttCode, $value)
|
public static function MakeValue($sClass, $sAttCode, $value)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
{
|
||||||
|
if (!MetaModel::IsValidAttCode($sClass, $sAttCode))
|
||||||
|
{
|
||||||
throw new Exception("Unknown attribute");
|
throw new Exception("Unknown attribute");
|
||||||
}
|
}
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
if ($oAttDef instanceof AttributeExternalKey) {
|
if ($oAttDef instanceof AttributeExternalKey)
|
||||||
|
{
|
||||||
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
|
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
|
||||||
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
|
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
|
||||||
} elseif ($oAttDef instanceof AttributeLinkedSet) {
|
}
|
||||||
if (!is_array($value)) {
|
elseif ($oAttDef instanceof AttributeLinkedSet)
|
||||||
|
{
|
||||||
|
if (!is_array($value))
|
||||||
|
{
|
||||||
throw new Exception("A link set must be defined by an array of objects");
|
throw new Exception("A link set must be defined by an array of objects");
|
||||||
}
|
}
|
||||||
$sLnkClass = $oAttDef->GetLinkedClass();
|
$sLnkClass = $oAttDef->GetLinkedClass();
|
||||||
$aLinks = [];
|
$aLinks = array();
|
||||||
foreach ($value as $oValues) {
|
foreach ($value as $oValues)
|
||||||
|
{
|
||||||
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
||||||
// Fix for N°1939
|
// Fix for N°1939
|
||||||
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0)) {
|
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$aLinks[] = $oLnk;
|
$aLinks[] = $oLnk;
|
||||||
}
|
}
|
||||||
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
||||||
} elseif ($oAttDef instanceof AttributeTagSet) {
|
}
|
||||||
if (!is_array($value)) {
|
elseif ($oAttDef instanceof AttributeTagSet)
|
||||||
|
{
|
||||||
|
if (!is_array($value))
|
||||||
|
{
|
||||||
throw new Exception("A tag set must be defined by an array of tag codes");
|
throw new Exception("A tag set must be defined by an array of tag codes");
|
||||||
}
|
}
|
||||||
$value = $oAttDef->FromJSONToValue($value);
|
$value = $oAttDef->FromJSONToValue($value);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$value = $oAttDef->FromJSONToValue($value);
|
$value = $oAttDef->FromJSONToValue($value);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2139,11 +2197,15 @@ class RestUtils
|
|||||||
public static function MakeObjectFromFields($sClass, $aFields)
|
public static function MakeObjectFromFields($sClass, $aFields)
|
||||||
{
|
{
|
||||||
$oObject = MetaModel::NewObject($sClass);
|
$oObject = MetaModel::NewObject($sClass);
|
||||||
foreach ($aFields as $sAttCode => $value) {
|
foreach ($aFields as $sAttCode => $value)
|
||||||
|
{
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
$oObject->Set($sAttCode, $realValue);
|
$oObject->Set($sAttCode, $realValue);
|
||||||
} catch (Exception $e) {
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2164,11 +2226,15 @@ class RestUtils
|
|||||||
public static function UpdateObjectFromFields($oObject, $aFields)
|
public static function UpdateObjectFromFields($oObject, $aFields)
|
||||||
{
|
{
|
||||||
$sClass = get_class($oObject);
|
$sClass = get_class($oObject);
|
||||||
foreach ($aFields as $sAttCode => $value) {
|
foreach ($aFields as $sAttCode => $value)
|
||||||
|
{
|
||||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
$oObject->Set($sAttCode, $realValue);
|
$oObject->Set($sAttCode, $realValue);
|
||||||
} catch (Exception $e) {
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
throw new Exception("$sAttCode: ".$e->getMessage(), $e->getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2177,6 +2243,7 @@ class RestUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers for modules extensibility, with discover performed by the MetaModel.
|
* Helpers for modules extensibility, with discover performed by the MetaModel.
|
||||||
*
|
*
|
||||||
@@ -2231,6 +2298,7 @@ interface iBackupExtraFilesExtension
|
|||||||
public function GetExtraFilesRelPaths(): array;
|
public function GetExtraFilesRelPaths(): array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to provide messages to be displayed in the "Welcome Popup"
|
* Interface to provide messages to be displayed in the "Welcome Popup"
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "categories". Each category defines a set of objects
|
* This class manages the audit "categories". Each category defines a set of objects
|
||||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
@@ -32,36 +32,34 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => ['name'],
|
"reconc_keys" => array('name'),
|
||||||
"db_table" => "priv_auditcategory",
|
"db_table" => "priv_auditcategory",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-folder.svg'),
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", ["description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("description"=>"Short name for this category", "allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", ["allowed_values" => null, "sql" => "definition_set", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeOQL("definition_set", array("allowed_values"=>null, "sql"=>"definition_set", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", ["linked_class" => "AuditRule", "ext_key_to_me" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => [], "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL]));
|
MetaModel::Init_AddAttribute(new AttributeLinkedSet("rules_list", array("linked_class"=>"AuditRule", "ext_key_to_me"=>"category_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(), "edit_mode" => LINKSET_EDITMODE_INPLACE, "tracking_level" => LINKSET_TRACKING_ALL)));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", ["allowed_values" => null, "sql" => "ok_error_tolerance", "default_value" => 5, "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeInteger("ok_error_tolerance", array("allowed_values"=>null, "sql"=>"ok_error_tolerance", "default_value"=>5, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", ["allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeInteger("warning_error_tolerance", array("allowed_values" => null, "sql" => "warning_error_tolerance", "default_value" => 25, "is_null_allowed" => true, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("domains_list",
|
||||||
"domains_list",
|
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array(), "display_style" => 'property')));
|
||||||
["linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "category_id", "ext_key_to_remote" => "domain_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => [], "display_style" => 'property']
|
|
||||||
));
|
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'definition_set', 'ok_error_tolerance', 'warning_error_tolerance', 'rules_list', 'domains_list')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['description', ]); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('description', )); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['description', 'definition_set']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('description', 'definition_set')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', ['name', 'description']); // Criteria of the default search form
|
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,3 +93,4 @@ class AuditCategory extends cmdbAbstractObject
|
|||||||
return $aShortcutActions;
|
return $aShortcutActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "categories". Each category defines a set of objects
|
* This class manages the audit "categories". Each category defines a set of objects
|
||||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||||
@@ -33,34 +33,32 @@ class AuditDomain extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"complementary_name_attcode" => ['description'],
|
"complementary_name_attcode" => array('description'),
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => ['name'],
|
"reconc_keys" => array('name'),
|
||||||
"db_table" => "priv_auditdomain",
|
"db_table" => "priv_auditdomain",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit-album.svg'),
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", ["description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("description" => "Short name for this category", "allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeImage("icon", ["is_null_allowed" => true, "depends_on" => [], "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false]));
|
MetaModel::Init_AddAttribute(new AttributeImage("icon", array("is_null_allowed" => true, "depends_on" => array(), "display_max_width" => 96, "display_max_height" => 96, "storage_max_width" => 256, "storage_max_height" => 256, "default_image" => null, "always_load_in_tables" => false)));
|
||||||
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
|
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("categories_list",
|
||||||
"categories_list",
|
array("linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => array())));
|
||||||
["linked_class" => "lnkAuditCategoryToAuditDomain", "ext_key_to_me" => "domain_id", "ext_key_to_remote" => "category_id", "allowed_values" => null, "count_min" => 0, "count_max" => 0, "depends_on" => []]
|
|
||||||
));
|
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['name', 'description', 'icon', 'categories_list']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'icon', 'categories_list')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['description',]); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('description',)); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['description']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('description')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', ['name', 'description']); // Criteria of the default search form
|
MetaModel::Init_SetZListItems('default_search', array('name', 'description')); // Criteria of the default search form
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetShortcutActions($sFinalClass)
|
public static function GetShortcutActions($sFinalClass)
|
||||||
@@ -86,39 +84,40 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
|
|||||||
*/
|
*/
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "",
|
"name_attcode" => "",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => ['category_id', 'domain_id'],
|
"reconc_keys" => array('category_id', 'domain_id'),
|
||||||
"db_table" => "priv_link_audit_category_domain",
|
"db_table" => "priv_link_audit_category_domain",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
"is_link" => true,
|
"is_link" => true,
|
||||||
'uniqueness_rules' => [
|
'uniqueness_rules' => array(
|
||||||
'no_duplicate' => [
|
'no_duplicate' => array(
|
||||||
'attributes' => [
|
'attributes' => array(
|
||||||
0 => 'category_id',
|
0 => 'category_id',
|
||||||
1 => 'domain_id',
|
1 => 'domain_id',
|
||||||
],
|
),
|
||||||
'filter' => '',
|
'filter' => '',
|
||||||
'disabled' => false,
|
'disabled' => false,
|
||||||
'is_blocking' => true,
|
'is_blocking' => true,
|
||||||
],
|
),
|
||||||
],
|
),
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", ["targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("targetclass" => "AuditCategory", "jointype" => '', "allowed_values" => null, "sql" => "category_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", ["allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("domain_id", ["targetclass" => "AuditDomain", "jointype" => '', "allowed_values" => null, "sql" => "domain_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("domain_id", array("targetclass" => "AuditDomain", "jointype" => '', "allowed_values" => null, "sql" => "domain_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("domain_name", ["allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("domain_name", array("allowed_values" => null, "extkey_attcode" => 'domain_id', "target_attcode" => "name")));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['category_id', 'domain_id']);
|
MetaModel::Init_SetZListItems('details', array('category_id', 'domain_id'));
|
||||||
MetaModel::Init_SetZListItems('list', ['category_id', 'domain_id']);
|
MetaModel::Init_SetZListItems('list', array('category_id', 'domain_id'));
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['category_id', 'domain_id']);
|
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'domain_id'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages the audit "rule" linked to a given audit category.
|
* This class manages the audit "rule" linked to a given audit category.
|
||||||
* Each rule is based on an OQL expression that returns either the "good" objects
|
* Each rule is based on an OQL expression that returns either the "good" objects
|
||||||
@@ -33,34 +33,35 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "application,grant_by_profile",
|
"category" => "application,grant_by_profile",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => ['name'],
|
"reconc_keys" => array('name'),
|
||||||
"db_table" => "priv_auditrule",
|
"db_table" => "priv_auditrule",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-audit.svg'),
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeOQL("query", ["allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeOQL("query", array("allowed_values" => null, "sql" => "query", "default_value" => "", "is_null_allowed" => false, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", ["allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("valid_flag", array("allowed_values" => new ValueSetEnum('true,false'), "sql" => "valid_flag", "default_value" => "true", "is_null_allowed" => false, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", ["allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeExternalKey("category_id", array("allowed_values" => null, "sql" => "category_id", "targetclass" => "AuditCategory", "is_null_allowed" => false, "on_target_delete" => DEL_MANUAL, "depends_on" => array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", ["allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name"]));
|
MetaModel::Init_AddAttribute(new AttributeExternalField("category_name", array("allowed_values" => null, "extkey_attcode" => 'category_id', "target_attcode" => "name")));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['category_id', 'name', 'description', 'query', 'valid_flag']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('category_id', 'name', 'description', 'query', 'valid_flag')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['category_id', 'description', 'valid_flag']); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('category_id', 'description', 'valid_flag')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['category_id', 'name', 'description', 'valid_flag', 'query']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('category_id', 'name', 'description', 'valid_flag', 'query')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('default_search', ['name', 'description', 'category_id']); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('default_search', array('name', 'description', 'category_id')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function GetShortcutActions($sFinalClass)
|
public static function GetShortcutActions($sFinalClass)
|
||||||
{
|
{
|
||||||
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
$aShortcutActions = parent::GetShortcutActions($sFinalClass);
|
||||||
@@ -71,3 +72,4 @@ class AuditRule extends cmdbAbstractObject
|
|||||||
return $aShortcutActions;
|
return $aShortcutActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -33,8 +32,7 @@ class CompileCSSService
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = [])
|
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
||||||
{
|
|
||||||
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -54,7 +53,7 @@ abstract class Dashboard
|
|||||||
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
||||||
$this->bAutoReload = false;
|
$this->bAutoReload = false;
|
||||||
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
||||||
$this->aCells = [];
|
$this->aCells = array();
|
||||||
$this->oDOMNode = null;
|
$this->oDOMNode = null;
|
||||||
$this->sId = $sId;
|
$this->sId = $sId;
|
||||||
}
|
}
|
||||||
@@ -66,8 +65,8 @@ abstract class Dashboard
|
|||||||
*/
|
*/
|
||||||
public function FromXml($sXml)
|
public function FromXml($sXml)
|
||||||
{
|
{
|
||||||
$this->aCells = []; // reset the content of the dashboard
|
$this->aCells = array(); // reset the content of the dashboard
|
||||||
set_error_handler(['Dashboard', 'ErrorHandler']);
|
set_error_handler(array('Dashboard', 'ErrorHandler'));
|
||||||
$oDoc = new DOMDocument();
|
$oDoc = new DOMDocument();
|
||||||
$oDoc->loadXML($sXml);
|
$oDoc->loadXML($sXml);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
@@ -81,68 +80,86 @@ abstract class Dashboard
|
|||||||
{
|
{
|
||||||
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
||||||
|
|
||||||
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0)) {
|
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0))
|
||||||
|
{
|
||||||
$this->sLayoutClass = $oLayoutNode->textContent;
|
$this->sLayoutClass = $oLayoutNode->textContent;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
$this->sLayoutClass = 'DashboardLayoutOneCol';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0)) {
|
if ($oTitleNode = $this->oDOMNode->getElementsByTagName('title')->item(0))
|
||||||
|
{
|
||||||
$this->sTitle = $oTitleNode->textContent;
|
$this->sTitle = $oTitleNode->textContent;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$this->sTitle = '';
|
$this->sTitle = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->bAutoReload = false;
|
$this->bAutoReload = false;
|
||||||
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
$this->iAutoReloadSec = MetaModel::GetConfig()->GetStandardReloadInterval();
|
||||||
if ($oAutoReloadNode = $this->oDOMNode->getElementsByTagName('auto_reload')->item(0)) {
|
if ($oAutoReloadNode = $this->oDOMNode->getElementsByTagName('auto_reload')->item(0))
|
||||||
if ($oAutoReloadEnabled = $oAutoReloadNode->getElementsByTagName('enabled')->item(0)) {
|
{
|
||||||
|
if ($oAutoReloadEnabled = $oAutoReloadNode->getElementsByTagName('enabled')->item(0))
|
||||||
|
{
|
||||||
$this->bAutoReload = ($oAutoReloadEnabled->textContent == 'true');
|
$this->bAutoReload = ($oAutoReloadEnabled->textContent == 'true');
|
||||||
}
|
}
|
||||||
if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0)) {
|
if ($oAutoReloadInterval = $oAutoReloadNode->getElementsByTagName('interval')->item(0))
|
||||||
|
{
|
||||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
|
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$oAutoReloadInterval->textContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0)) {
|
if ($oCellsNode = $this->oDOMNode->getElementsByTagName('cells')->item(0))
|
||||||
|
{
|
||||||
$oCellsList = $oCellsNode->getElementsByTagName('cell');
|
$oCellsList = $oCellsNode->getElementsByTagName('cell');
|
||||||
$aCellOrder = [];
|
$aCellOrder = array();
|
||||||
$iCellRank = 0;
|
$iCellRank = 0;
|
||||||
/** @var \DOMElement $oCellNode */
|
/** @var \DOMElement $oCellNode */
|
||||||
foreach ($oCellsList as $oCellNode) {
|
foreach($oCellsList as $oCellNode)
|
||||||
|
{
|
||||||
$oCellRank = $oCellNode->getElementsByTagName('rank')->item(0);
|
$oCellRank = $oCellNode->getElementsByTagName('rank')->item(0);
|
||||||
if ($oCellRank) {
|
if ($oCellRank)
|
||||||
|
{
|
||||||
$iCellRank = (float)$oCellRank->textContent;
|
$iCellRank = (float)$oCellRank->textContent;
|
||||||
}
|
}
|
||||||
$oDashletsNode = $oCellNode->getElementsByTagName('dashlets')->item(0);
|
$oDashletsNode = $oCellNode->getElementsByTagName('dashlets')->item(0);
|
||||||
{
|
{
|
||||||
$oDashletList = $oDashletsNode->getElementsByTagName('dashlet');
|
$oDashletList = $oDashletsNode->getElementsByTagName('dashlet');
|
||||||
$iRank = 0;
|
$iRank = 0;
|
||||||
$aDashletOrder = [];
|
$aDashletOrder = array();
|
||||||
/** @var \DOMElement $oDomNode */
|
/** @var \DOMElement $oDomNode */
|
||||||
foreach ($oDashletList as $oDomNode) {
|
foreach($oDashletList as $oDomNode)
|
||||||
|
{
|
||||||
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
||||||
if ($oRank) {
|
if ($oRank)
|
||||||
|
{
|
||||||
$iRank = (float)$oRank->textContent;
|
$iRank = (float)$oRank->textContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
$oNewDashlet = $this->InitDashletFromDOMNode($oDomNode);
|
$oNewDashlet = $this->InitDashletFromDOMNode($oDomNode);
|
||||||
$aDashletOrder[] = ['rank' => $iRank, 'dashlet' => $oNewDashlet];
|
$aDashletOrder[] = array('rank' => $iRank, 'dashlet' => $oNewDashlet);
|
||||||
}
|
}
|
||||||
usort($aDashletOrder, [get_class($this), 'SortOnRank']);
|
usort($aDashletOrder, array(get_class($this), 'SortOnRank'));
|
||||||
$aDashletList = [];
|
$aDashletList = array();
|
||||||
foreach ($aDashletOrder as $aItem) {
|
foreach($aDashletOrder as $aItem)
|
||||||
|
{
|
||||||
$aDashletList[] = $aItem['dashlet'];
|
$aDashletList[] = $aItem['dashlet'];
|
||||||
}
|
}
|
||||||
$aCellOrder[] = ['rank' => $iCellRank, 'dashlets' => $aDashletList];
|
$aCellOrder[] = array('rank' => $iCellRank, 'dashlets' => $aDashletList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usort($aCellOrder, [get_class($this), 'SortOnRank']);
|
usort($aCellOrder, array(get_class($this), 'SortOnRank'));
|
||||||
foreach ($aCellOrder as $aItem) {
|
foreach($aCellOrder as $aItem)
|
||||||
|
{
|
||||||
$this->aCells[] = $aItem['dashlets'];
|
$this->aCells[] = $aItem['dashlets'];
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
$this->aCells = [];
|
else
|
||||||
|
{
|
||||||
|
$this->aCells = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,9 +208,12 @@ abstract class Dashboard
|
|||||||
*/
|
*/
|
||||||
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
public static function ErrorHandler($errno, $errstr, $errfile, $errline)
|
||||||
{
|
{
|
||||||
if ($errno == E_WARNING && (substr_count($errstr, "DOMDocument::loadXML()") > 0)) {
|
if ($errno == E_WARNING && (substr_count($errstr,"DOMDocument::loadXML()")>0))
|
||||||
|
{
|
||||||
throw new DOMException($errstr);
|
throw new DOMException($errstr);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +263,8 @@ abstract class Dashboard
|
|||||||
$oDefinition->appendChild($oCellsNode);
|
$oDefinition->appendChild($oCellsNode);
|
||||||
|
|
||||||
$iCellRank = 0;
|
$iCellRank = 0;
|
||||||
foreach ($this->aCells as $aCell) {
|
foreach ($this->aCells as $aCell)
|
||||||
|
{
|
||||||
$oCellNode = $oDoc->createElement('cell');
|
$oCellNode = $oDoc->createElement('cell');
|
||||||
$oCellNode->setAttribute('id', $iCellRank);
|
$oCellNode->setAttribute('id', $iCellRank);
|
||||||
$oCellsNode->appendChild($oCellNode);
|
$oCellsNode->appendChild($oCellNode);
|
||||||
@@ -255,7 +276,8 @@ abstract class Dashboard
|
|||||||
$oDashletsNode = $oDoc->createElement('dashlets');
|
$oDashletsNode = $oDoc->createElement('dashlets');
|
||||||
$oCellNode->appendChild($oDashletsNode);
|
$oCellNode->appendChild($oDashletsNode);
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach ($aCell as $oDashlet) {
|
foreach ($aCell as $oDashlet)
|
||||||
|
{
|
||||||
$oNode = $oDoc->createElement('dashlet');
|
$oNode = $oDoc->createElement('dashlet');
|
||||||
$oDashletsNode->appendChild($oNode);
|
$oDashletsNode->appendChild($oNode);
|
||||||
$oNode->setAttribute('id', $oDashlet->GetID());
|
$oNode->setAttribute('id', $oDashlet->GetID());
|
||||||
@@ -278,14 +300,17 @@ abstract class Dashboard
|
|||||||
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
||||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
||||||
|
|
||||||
foreach ($aParams['cells'] as $aCell) {
|
foreach($aParams['cells'] as $aCell)
|
||||||
$aCellDashlets = [];
|
{
|
||||||
foreach ($aCell as $aDashletParams) {
|
$aCellDashlets = array();
|
||||||
|
foreach($aCell as $aDashletParams)
|
||||||
|
{
|
||||||
$sDashletClass = $aDashletParams['dashlet_class'];
|
$sDashletClass = $aDashletParams['dashlet_class'];
|
||||||
$sId = $aDashletParams['dashlet_id'];
|
$sId = $aDashletParams['dashlet_id'];
|
||||||
/** @var \Dashlet $oNewDashlet */
|
/** @var \Dashlet $oNewDashlet */
|
||||||
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
|
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
|
||||||
if (isset($aDashletParams['dashlet_type'])) {
|
if (isset($aDashletParams['dashlet_type']))
|
||||||
|
{
|
||||||
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
|
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
|
||||||
}
|
}
|
||||||
$oForm = $oNewDashlet->GetForm();
|
$oForm = $oNewDashlet->GetForm();
|
||||||
@@ -395,7 +420,7 @@ abstract class Dashboard
|
|||||||
{
|
{
|
||||||
$sId = $this->GetNewDashletId();
|
$sId = $this->GetNewDashletId();
|
||||||
$oDashlet->SetId($sId);
|
$oDashlet->SetId($sId);
|
||||||
$this->aCells[] = [$oDashlet];
|
$this->aCells[] = array($oDashlet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -405,7 +430,7 @@ abstract class Dashboard
|
|||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderProperties($oPage, $aExtraParams = [])
|
public function RenderProperties($oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
// menu to pick a layout and edit other properties of the dashboard
|
// menu to pick a layout and edit other properties of the dashboard
|
||||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashboard-editor--properties"><div class="ui-widget-header ui-corner-all ibo-dashboard-editor--properties-title">'.Dict::S('UI:DashboardEdit:Properties').'</div>');
|
||||||
@@ -417,7 +442,7 @@ abstract class Dashboard
|
|||||||
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
if (is_subclass_of($sLayoutClass, 'DashboardLayout')) {
|
||||||
$oReflection = new ReflectionClass($sLayoutClass);
|
$oReflection = new ReflectionClass($sLayoutClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract()) {
|
||||||
$aCallSpec = [$sLayoutClass, 'GetInfo'];
|
$aCallSpec = array($sLayoutClass, 'GetInfo');
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
$sChecked = ($this->sLayoutClass == $sLayoutClass) ? 'checked' : '';
|
||||||
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
$oPage->add('<input type="radio" name="layout_class" '.$sChecked.' value="'.$sLayoutClass.'" id="layout_'.$sLayoutClass.'"><label for="layout_'.$sLayoutClass.'"><img src="'.$sUrl.$aInfo['icon'].'" class="ibo-dashboard--properties--icon" data-role="ibo-dashboard--properties--icon"/></label>'); // title="" on either the img or the label does nothing !
|
||||||
@@ -441,6 +466,7 @@ abstract class Dashboard
|
|||||||
$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
|
$oField->SetBoundaries(MetaModel::GetConfig()->Get('min_reload_interval'), null); // no upper limit
|
||||||
$oForm->AddField($oField);
|
$oForm->AddField($oField);
|
||||||
|
|
||||||
|
|
||||||
$this->SetFormParams($oForm, $aExtraParams);
|
$this->SetFormParams($oForm, $aExtraParams);
|
||||||
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
|
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
|
||||||
|
|
||||||
@@ -496,9 +522,11 @@ EOF
|
|||||||
*
|
*
|
||||||
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
* @return \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = [], $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
||||||
{
|
{
|
||||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
if (!array_key_exists('dashboard_div_id', $aExtraParams)) {
|
||||||
|
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||||
|
}
|
||||||
|
|
||||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||||
$oLayout = new $this->sLayoutClass();
|
$oLayout = new $this->sLayoutClass();
|
||||||
@@ -525,8 +553,7 @@ EOF
|
|||||||
|
|
||||||
$oToolbar->AddHtml($sHtml);
|
$oToolbar->AddHtml($sHtml);
|
||||||
} else {
|
} else {
|
||||||
$oPage->add_script(
|
$oPage->add_script(<<<JS
|
||||||
<<<JS
|
|
||||||
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML").attr("title", $('<div>').html("$sTitleForHTML").text());
|
$(".ibo-top-bar--toolbar-dashboard-title").html("$sTitleForHTML").attr("title", $('<div>').html("$sTitleForHTML").text());
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
@@ -570,7 +597,7 @@ JS
|
|||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = [])
|
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
// Toolbox/palette to edit the properties of each dashlet
|
// Toolbox/palette to edit the properties of each dashlet
|
||||||
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
$oPage->add('<div class="ui-widget-content ui-corner-all ibo-dashlet--properties"><div class="ui-widget-header ui-corner-all ibo-dashlet--properties--title">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
|
||||||
@@ -579,10 +606,13 @@ JS
|
|||||||
$oLayout = new $this->sLayoutClass();
|
$oLayout = new $this->sLayoutClass();
|
||||||
|
|
||||||
$oPage->add('<div id="dashlet_properties">');
|
$oPage->add('<div id="dashlet_properties">');
|
||||||
foreach ($this->aCells as $iCellIdx => $aCell) {
|
foreach($this->aCells as $iCellIdx => $aCell)
|
||||||
|
{
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach ($aCell as $oDashlet) {
|
foreach($aCell as $oDashlet)
|
||||||
if ($oDashlet->IsVisible()) {
|
{
|
||||||
|
if ($oDashlet->IsVisible())
|
||||||
|
{
|
||||||
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
|
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
|
||||||
$oForm = $oDashlet->GetForm();
|
$oForm = $oDashlet->GetForm();
|
||||||
$this->SetFormParams($oForm, $aExtraParams);
|
$this->SetFormParams($oForm, $aExtraParams);
|
||||||
@@ -604,17 +634,18 @@ JS
|
|||||||
*/
|
*/
|
||||||
protected function GetAvailableDashlets()
|
protected function GetAvailableDashlets()
|
||||||
{
|
{
|
||||||
$aDashlets = [];
|
$aDashlets = array();
|
||||||
|
|
||||||
foreach (get_declared_classes() as $sDashletClass) {
|
foreach( get_declared_classes() as $sDashletClass)
|
||||||
|
{
|
||||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
||||||
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, ['DashletUnknown', 'DashletProxy'])) {
|
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, array('DashletUnknown', 'DashletProxy'))) {
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract()) {
|
||||||
$aCallSpec = [$sDashletClass, 'IsVisible'];
|
$aCallSpec = array($sDashletClass, 'IsVisible');
|
||||||
$bVisible = call_user_func($aCallSpec);
|
$bVisible = call_user_func($aCallSpec);
|
||||||
if ($bVisible) {
|
if ($bVisible) {
|
||||||
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
$aCallSpec = array($sDashletClass, 'GetInfo');
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$aDashlets[$sDashletClass] = $aInfo;
|
$aDashlets[$sDashletClass] = $aInfo;
|
||||||
}
|
}
|
||||||
@@ -631,9 +662,11 @@ JS
|
|||||||
protected function GetNewDashletId()
|
protected function GetNewDashletId()
|
||||||
{
|
{
|
||||||
$iNewId = 0;
|
$iNewId = 0;
|
||||||
foreach ($this->aCells as $aDashlets) {
|
foreach($this->aCells as $aDashlets)
|
||||||
|
{
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
foreach ($aDashlets as $oDashlet) {
|
foreach($aDashlets as $oDashlet)
|
||||||
|
{
|
||||||
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -650,7 +683,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = []);
|
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \DesignerForm $oForm
|
* @param \DesignerForm $oForm
|
||||||
@@ -658,7 +691,7 @@ JS
|
|||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
abstract protected function SetFormParams($oForm, $aExtraParams = []);
|
abstract protected function SetFormParams($oForm, $aExtraParams = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sType
|
* @param string $sType
|
||||||
@@ -668,7 +701,8 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function GetDashletClassFromType($sType, $oFactory = null)
|
public static function GetDashletClassFromType($sType, $oFactory = null)
|
||||||
{
|
{
|
||||||
if (is_subclass_of($sType, 'Dashlet')) {
|
if (is_subclass_of($sType, 'Dashlet'))
|
||||||
|
{
|
||||||
return $sType;
|
return $sType;
|
||||||
}
|
}
|
||||||
return 'DashletUnknown';
|
return 'DashletUnknown';
|
||||||
@@ -691,12 +725,14 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
|
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
|
||||||
{
|
{
|
||||||
if (strpos($sDashletOrigId, '_ID_row') !== false) {
|
if(strpos($sDashletOrigId, '_ID_row') !== false)
|
||||||
|
{
|
||||||
return $sDashletOrigId;
|
return $sDashletOrigId;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
|
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
|
||||||
if ($bIsCustomized) {
|
if ($bIsCustomized)
|
||||||
|
{
|
||||||
$sDashletId = 'CUSTOM_'.$sDashletId;
|
$sDashletId = 'CUSTOM_'.$sDashletId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,9 +784,9 @@ class RuntimeDashboard extends Dashboard
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function SetFormParams($oForm, $aExtraParams = [])
|
protected function SetFormParams($oForm, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', ['operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams]);
|
$oForm->SetSubmitParams(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php', array('operation' => 'update_dashlet_property', 'extra_params' => $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -766,11 +802,14 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
$bIsNew = false;
|
$bIsNew = false;
|
||||||
if ($oUDSet->Count() > 0) {
|
if ($oUDSet->Count() > 0)
|
||||||
|
{
|
||||||
// Assuming there is at most one couple {user, menu}!
|
// Assuming there is at most one couple {user, menu}!
|
||||||
$oUserDashboard = $oUDSet->Fetch();
|
$oUserDashboard = $oUDSet->Fetch();
|
||||||
$oUserDashboard->Set('contents', $sXml);
|
$oUserDashboard->Set('contents', $sXml);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// No such customized dashboard for the current user, let's create a new record
|
// No such customized dashboard for the current user, let's create a new record
|
||||||
$oUserDashboard = new UserDashboard();
|
$oUserDashboard = new UserDashboard();
|
||||||
$oUserDashboard->Set('user_id', UserRights::GetUserId());
|
$oUserDashboard->Set('user_id', UserRights::GetUserId());
|
||||||
@@ -801,7 +840,8 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
if ($oUDSet->Count() > 0) {
|
if ($oUDSet->Count() > 0)
|
||||||
|
{
|
||||||
// Assuming there is at most one couple {user, menu}!
|
// Assuming there is at most one couple {user, menu}!
|
||||||
$oUserDashboard = $oUDSet->Fetch();
|
$oUserDashboard = $oUDSet->Fetch();
|
||||||
utils::PushArchiveMode(false);
|
utils::PushArchiveMode(false);
|
||||||
@@ -845,11 +885,14 @@ class RuntimeDashboard extends Dashboard
|
|||||||
} else {
|
} else {
|
||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($sDashboardDefinition !== false) {
|
if ($sDashboardDefinition !== false)
|
||||||
|
{
|
||||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
$oDashboard->SetCustomFlag($bCustomized);
|
$oDashboard->SetCustomFlag($bCustomized);
|
||||||
@@ -896,6 +939,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
$sDashboardDefinition = @file_get_contents($sDashboardFileSanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($sDashboardDefinition !== false) {
|
if ($sDashboardDefinition !== false) {
|
||||||
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
$oDashboard = new RuntimeDashboard($sDashBoardId);
|
||||||
$oDashboard->FromXml($sDashboardDefinition);
|
$oDashboard->FromXml($sDashboardDefinition);
|
||||||
@@ -912,11 +956,11 @@ class RuntimeDashboard extends Dashboard
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $bEditMode = false, $aExtraParams = [], $bCanEdit = true)
|
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
||||||
{
|
{
|
||||||
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
if (!isset($aExtraParams['query_params']) && isset($aExtraParams['this->class'])) {
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = ['query_params' => $oObj->ToArgsForQuery()];
|
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
||||||
} else {
|
} else {
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
@@ -926,7 +970,7 @@ class RuntimeDashboard extends Dashboard
|
|||||||
if (isset($aExtraParams['query_params']['this->object()'])) {
|
if (isset($aExtraParams['query_params']['this->object()'])) {
|
||||||
/** @var \DBObject $oObj */
|
/** @var \DBObject $oObj */
|
||||||
$oObj = $aExtraParams['query_params']['this->object()'];
|
$oObj = $aExtraParams['query_params']['this->object()'];
|
||||||
$aAjaxParams = ['this->class' => get_class($oObj), 'this->id' => $oObj->GetKey()];
|
$aAjaxParams = array('this->class' => get_class($oObj), 'this->id' => $oObj->GetKey());
|
||||||
if (isset($aExtraParams['from_dashboard_page'])) {
|
if (isset($aExtraParams['from_dashboard_page'])) {
|
||||||
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
$aAjaxParams['from_dashboard_page'] = $aExtraParams['from_dashboard_page'];
|
||||||
}
|
}
|
||||||
@@ -959,7 +1003,9 @@ class RuntimeDashboard extends Dashboard
|
|||||||
}
|
}
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||||
@@ -988,7 +1034,7 @@ EOF
|
|||||||
* @throws \CoreUnexpectedValue
|
* @throws \CoreUnexpectedValue
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = [])
|
protected function RenderSelector(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aAjaxParams = array())
|
||||||
{
|
{
|
||||||
if (!$this->HasCustomDashboard()) {
|
if (!$this->HasCustomDashboard()) {
|
||||||
return;
|
return;
|
||||||
@@ -1006,7 +1052,7 @@ EOF
|
|||||||
$sSelectorHtml .= '</div>';
|
$sSelectorHtml .= '</div>';
|
||||||
|
|
||||||
$sFile = addslashes($this->GetDefinitionFile());
|
$sFile = addslashes($this->GetDefinitionFile());
|
||||||
$sReloadURL = json_encode($this->GetReloadURL());
|
$sReloadURL = $this->GetReloadURL();
|
||||||
|
|
||||||
$bFromDashboardPage = isset($aAjaxParams['from_dashboard_page']) ? isset($aAjaxParams['from_dashboard_page']) : false;
|
$bFromDashboardPage = isset($aAjaxParams['from_dashboard_page']) ? isset($aAjaxParams['from_dashboard_page']) : false;
|
||||||
if ($bFromDashboardPage) {
|
if ($bFromDashboardPage) {
|
||||||
@@ -1048,7 +1094,8 @@ JS
|
|||||||
*/
|
*/
|
||||||
protected function HasCustomDashboard()
|
protected function HasCustomDashboard()
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
// Search for an eventual user defined dashboard
|
// Search for an eventual user defined dashboard
|
||||||
$oUDSearch = new DBObjectSearch('UserDashboard');
|
$oUDSearch = new DBObjectSearch('UserDashboard');
|
||||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||||
@@ -1056,7 +1103,9 @@ JS
|
|||||||
$oUDSet = new DBObjectSet($oUDSearch);
|
$oUDSet = new DBObjectSet($oUDSearch);
|
||||||
|
|
||||||
return ($oUDSet->Count() > 0);
|
return ($oUDSet->Count() > 0);
|
||||||
} catch (Exception $e) {
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1092,23 +1141,22 @@ JS
|
|||||||
->AddCSSClass('ibo-action-button');
|
->AddCSSClass('ibo-action-button');
|
||||||
|
|
||||||
$oToolbar->AddSubBlock($oActionButton);
|
$oToolbar->AddSubBlock($oActionButton);
|
||||||
$aActions = [];
|
|
||||||
|
$aActions = array();
|
||||||
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
||||||
$sJSExtraParams = json_encode($aExtraParams);
|
$sJSExtraParams = json_encode($aExtraParams);
|
||||||
if ($this->HasCustomDashboard()) {
|
if ($this->HasCustomDashboard()) {
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
$oRevert = new JSPopupMenuItem(
|
$oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:DeleteCustom'),
|
||||||
'UI:Dashboard:RevertConfirm',
|
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false");
|
||||||
Dict::S('UI:Dashboard:DeleteCustom'),
|
|
||||||
"if (confirm('".addslashes(Dict::S('UI:Dashboard:RevertConfirm'))."')) return RevertDashboard('{$this->sId}', $sJSExtraParams); else return false"
|
|
||||||
);
|
|
||||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||||
} else {
|
} else {
|
||||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||||
|
|
||||||
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
$oActionsMenu = $oPage->GetPopoverMenu($sPopoverMenuId, $aActions)
|
||||||
@@ -1118,7 +1166,7 @@ JS
|
|||||||
$oToolbar->AddSubBlock($oActionButton)
|
$oToolbar->AddSubBlock($oActionButton)
|
||||||
->AddSubBlock($oActionsMenu);
|
->AddSubBlock($oActionsMenu);
|
||||||
|
|
||||||
$sReloadURL = json_encode($this->GetReloadURL());
|
$sReloadURL = $this->GetReloadURL();
|
||||||
$oPage->add_script(
|
$oPage->add_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
function EditDashboard(sId, sDashboardFile, aExtraParams)
|
function EditDashboard(sId, sDashboardFile, aExtraParams)
|
||||||
@@ -1148,7 +1196,7 @@ EOF
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function RenderProperties($oPage, $aExtraParams = [])
|
public function RenderProperties($oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
parent::RenderProperties($oPage, $aExtraParams);
|
parent::RenderProperties($oPage, $aExtraParams);
|
||||||
|
|
||||||
@@ -1180,6 +1228,7 @@ EOF
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param WebPage $oPage
|
* @param WebPage $oPage
|
||||||
*
|
*
|
||||||
@@ -1190,11 +1239,11 @@ EOF
|
|||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function RenderEditor($oPage, $aExtraParams = [])
|
public function RenderEditor($oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
if (isset($aExtraParams['this->class'])) {
|
if (isset($aExtraParams['this->class'])) {
|
||||||
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
$oObj = MetaModel::GetObject($aExtraParams['this->class'], $aExtraParams['this->id']);
|
||||||
$aRenderParams = ['query_params' => $oObj->ToArgsForQuery()];
|
$aRenderParams = array('query_params' => $oObj->ToArgsForQuery());
|
||||||
} else {
|
} else {
|
||||||
$aRenderParams = $aExtraParams;
|
$aRenderParams = $aExtraParams;
|
||||||
}
|
}
|
||||||
@@ -1217,14 +1266,15 @@ EOF
|
|||||||
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
||||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||||
|
|
||||||
$sId = json_encode($this->sId);
|
$sId = utils::HtmlEntities($this->sId);
|
||||||
$sLayoutClass = json_encode($this->sLayoutClass);
|
$sLayoutClass = utils::HtmlEntities($this->sLayoutClass);
|
||||||
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
|
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
|
||||||
$sAutoReloadSec = (string) $this->iAutoReloadSec;
|
$sAutoReloadSec = (string) $this->iAutoReloadSec;
|
||||||
$sTitle = json_encode($this->sTitle);
|
$sTitle = utils::HtmlEntities($this->sTitle);
|
||||||
$sFile = json_encode($this->GetDefinitionFile());
|
$sFile = utils::HtmlEntities($this->GetDefinitionFile());
|
||||||
|
$sFileForJS = json_encode($this->GetDefinitionFile());
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
|
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
|
||||||
$sReloadURL = json_encode($this->GetReloadURL());
|
$sReloadURL = $this->GetReloadURL();
|
||||||
|
|
||||||
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
|
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
|
||||||
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));
|
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));
|
||||||
@@ -1278,15 +1328,15 @@ $('#dashboard_editor').dialog({
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('#dashboard_editor .ui-layout-center').runtimedashboard({
|
$('#dashboard_editor .ui-layout-center').runtimedashboard({
|
||||||
dashboard_id: $sId,
|
dashboard_id: '$sId',
|
||||||
layout_class: $sLayoutClass,
|
layout_class: '$sLayoutClass',
|
||||||
title: $sTitle,
|
title: '$sTitle',
|
||||||
auto_reload: $sAutoReload,
|
auto_reload: $sAutoReload,
|
||||||
auto_reload_sec: $sAutoReloadSec,
|
auto_reload_sec: $sAutoReloadSec,
|
||||||
submit_to: '$sUrl',
|
submit_to: '$sUrl',
|
||||||
submit_parameters: {operation: 'save_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
submit_parameters: {operation: 'save_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
||||||
render_to: '$sUrl',
|
render_to: '$sUrl',
|
||||||
render_parameters: {operation: 'render_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
render_parameters: {operation: 'render_dashboard', file: {$sFileForJS}, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
||||||
new_dashlet_parameters: {operation: 'new_dashlet'}
|
new_dashlet_parameters: {operation: 'new_dashlet'}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1343,41 +1393,51 @@ JS
|
|||||||
// Get the list of all 'dashboard' menus in which we can insert a dashlet
|
// Get the list of all 'dashboard' menus in which we can insert a dashlet
|
||||||
$aAllMenus = ApplicationMenu::ReflectionMenuNodes();
|
$aAllMenus = ApplicationMenu::ReflectionMenuNodes();
|
||||||
$sRootMenuId = ApplicationMenu::GetRootMenuId($sContextMenuId);
|
$sRootMenuId = ApplicationMenu::GetRootMenuId($sContextMenuId);
|
||||||
$aAllowedDashboards = [];
|
$aAllowedDashboards = array();
|
||||||
$sDefaultDashboard = null;
|
$sDefaultDashboard = null;
|
||||||
|
|
||||||
// Store the parent menus for acces check
|
// Store the parent menus for acces check
|
||||||
$aParentMenus = [];
|
$aParentMenus = array();
|
||||||
foreach ($aAllMenus as $idx => $aMenu) {
|
foreach($aAllMenus as $idx => $aMenu)
|
||||||
|
{
|
||||||
/** @var MenuNode $oMenu */
|
/** @var MenuNode $oMenu */
|
||||||
$oMenu = $aMenu['node'];
|
$oMenu = $aMenu['node'];
|
||||||
if (count(ApplicationMenu::GetChildren($oMenu->GetIndex())) > 0) {
|
if (count(ApplicationMenu::GetChildren($oMenu->GetIndex())) > 0)
|
||||||
|
{
|
||||||
$aParentMenus[$oMenu->GetMenuId()] = $aMenu;
|
$aParentMenus[$oMenu->GetMenuId()] = $aMenu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($aAllMenus as $idx => $aMenu) {
|
foreach($aAllMenus as $idx => $aMenu)
|
||||||
|
{
|
||||||
$oMenu = $aMenu['node'];
|
$oMenu = $aMenu['node'];
|
||||||
if ($oMenu instanceof DashboardMenuNode) {
|
if ($oMenu instanceof DashboardMenuNode)
|
||||||
|
{
|
||||||
// Get the root parent for access check
|
// Get the root parent for access check
|
||||||
$sParentId = $aMenu['parent'];
|
$sParentId = $aMenu['parent'];
|
||||||
$aParentMenu = $aParentMenus[$sParentId];
|
$aParentMenu = $aParentMenus[$sParentId];
|
||||||
while (isset($aParentMenus[$aParentMenu['parent']])) {
|
while (isset($aParentMenus[$aParentMenu['parent']]))
|
||||||
|
{
|
||||||
// grand parent exists
|
// grand parent exists
|
||||||
$sParentId = $aParentMenu['parent'];
|
$sParentId = $aParentMenu['parent'];
|
||||||
$aParentMenu = $aParentMenus[$sParentId];
|
$aParentMenu = $aParentMenus[$sParentId];
|
||||||
}
|
}
|
||||||
/** @var \MenuNode $oParentMenu */
|
/** @var \MenuNode $oParentMenu */
|
||||||
$oParentMenu = $aParentMenu['node'];
|
$oParentMenu = $aParentMenu['node'];
|
||||||
if ($oMenu->IsEnabled() && $oParentMenu->IsEnabled()) {
|
if ($oMenu->IsEnabled() && $oParentMenu->IsEnabled())
|
||||||
|
{
|
||||||
$sMenuLabel = $oMenu->GetTitle();
|
$sMenuLabel = $oMenu->GetTitle();
|
||||||
$sParentLabel = Dict::S('Menu:'.$sParentId);
|
$sParentLabel = Dict::S('Menu:'.$sParentId);
|
||||||
if ($sParentLabel != $sMenuLabel) {
|
if ($sParentLabel != $sMenuLabel)
|
||||||
|
{
|
||||||
$aAllowedDashboards[$oMenu->GetMenuId()] = $sParentLabel.' - '.$sMenuLabel;
|
$aAllowedDashboards[$oMenu->GetMenuId()] = $sParentLabel.' - '.$sMenuLabel;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$aAllowedDashboards[$oMenu->GetMenuId()] = $sMenuLabel;
|
$aAllowedDashboards[$oMenu->GetMenuId()] = $sMenuLabel;
|
||||||
}
|
}
|
||||||
if (empty($sDefaultDashboard) && ($sRootMenuId == ApplicationMenu::GetRootMenuId($oMenu->GetMenuId()))) {
|
if (empty($sDefaultDashboard) && ($sRootMenuId == ApplicationMenu::GetRootMenuId($oMenu->GetMenuId())))
|
||||||
|
{
|
||||||
$sDefaultDashboard = $oMenu->GetMenuId();
|
$sDefaultDashboard = $oMenu->GetMenuId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1392,17 +1452,21 @@ JS
|
|||||||
|
|
||||||
// Get the list of possible dashlets that support a creation from
|
// Get the list of possible dashlets that support a creation from
|
||||||
// an OQL
|
// an OQL
|
||||||
$aDashlets = [];
|
$aDashlets = array();
|
||||||
foreach (get_declared_classes() as $sDashletClass) {
|
foreach(get_declared_classes() as $sDashletClass)
|
||||||
if (is_subclass_of($sDashletClass, 'Dashlet')) {
|
{
|
||||||
|
if (is_subclass_of($sDashletClass, 'Dashlet'))
|
||||||
|
{
|
||||||
$oReflection = new ReflectionClass($sDashletClass);
|
$oReflection = new ReflectionClass($sDashletClass);
|
||||||
if (!$oReflection->isAbstract()) {
|
if (!$oReflection->isAbstract())
|
||||||
$aCallSpec = [$sDashletClass, 'CanCreateFromOQL'];
|
{
|
||||||
|
$aCallSpec = array($sDashletClass, 'CanCreateFromOQL');
|
||||||
$bShorcutMode = call_user_func($aCallSpec);
|
$bShorcutMode = call_user_func($aCallSpec);
|
||||||
if ($bShorcutMode) {
|
if ($bShorcutMode)
|
||||||
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
{
|
||||||
|
$aCallSpec = array($sDashletClass, 'GetInfo');
|
||||||
$aInfo = call_user_func($aCallSpec);
|
$aInfo = call_user_func($aCallSpec);
|
||||||
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
|
$aDashlets[$sDashletClass] = array('label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1410,7 +1474,8 @@ JS
|
|||||||
|
|
||||||
$oSelectorField = new DesignerFormSelectorField('dashlet_class', Dict::S('UI:DashletCreation:DashletType'), '');
|
$oSelectorField = new DesignerFormSelectorField('dashlet_class', Dict::S('UI:DashletCreation:DashletType'), '');
|
||||||
$oForm->AddField($oSelectorField);
|
$oForm->AddField($oSelectorField);
|
||||||
foreach ($aDashlets as $sDashletClass => $aDashletInfo) {
|
foreach($aDashlets as $sDashletClass => $aDashletInfo)
|
||||||
|
{
|
||||||
$oSubForm = new DesignerForm();
|
$oSubForm = new DesignerForm();
|
||||||
$oMetaModel = new ModelReflectionRuntime();
|
$oMetaModel = new ModelReflectionRuntime();
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
@@ -1542,7 +1607,7 @@ JS
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = [])
|
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$sDashletIdOrig = $oDashlet->GetID();
|
$sDashletIdOrig = $oDashlet->GetID();
|
||||||
$sDashboardSanitizedId = $this->GetSanitizedId();
|
$sDashboardSanitizedId = $this->GetSanitizedId();
|
||||||
@@ -1569,27 +1634,31 @@ JS
|
|||||||
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
||||||
{
|
{
|
||||||
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
||||||
if (!$bIsDashletWithListPref) {
|
if (!$bIsDashletWithListPref)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/** @var \DashletObjectList $oDashlet */
|
/** @var \DashletObjectList $oDashlet */
|
||||||
|
|
||||||
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
|
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
|
||||||
if ($bDashletIdInNewFormat) {
|
if ($bDashletIdInNewFormat)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
|
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
|
||||||
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
|
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
|
||||||
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
|
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
|
||||||
if ($bHasPrefInNewFormat) {
|
if ($bHasPrefInNewFormat)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
|
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
|
||||||
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
|
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
|
||||||
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
|
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
|
||||||
if (!$bHasPrefInOldFormat) {
|
if (!$bHasPrefInOldFormat)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1608,7 +1677,7 @@ JS
|
|||||||
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
|
||||||
{
|
{
|
||||||
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
|
||||||
$aClassAliases = [];
|
$aClassAliases = array();
|
||||||
try {
|
try {
|
||||||
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
|
||||||
$aClassAliases = $oFilter->GetSelectedClasses();
|
$aClassAliases = $oFilter->GetSelectedClasses();
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -42,11 +41,11 @@ abstract class DashboardLayout
|
|||||||
|
|
||||||
public static function GetInfo()
|
public static function GetInfo()
|
||||||
{
|
{
|
||||||
return [
|
return array(
|
||||||
'label' => '',
|
'label' => '',
|
||||||
'icon' => '',
|
'icon' => '',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +63,16 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
$aKeys = array_reverse(array_keys($aDashlets));
|
$aKeys = array_reverse(array_keys($aDashlets));
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
$bNoVisibleFound = true;
|
$bNoVisibleFound = true;
|
||||||
while ($idx < count($aKeys) && $bNoVisibleFound) {
|
while($idx < count($aKeys) && $bNoVisibleFound)
|
||||||
|
{
|
||||||
/** @var \Dashlet $oDashlet */
|
/** @var \Dashlet $oDashlet */
|
||||||
$oDashlet = $aDashlets[$aKeys[$idx]];
|
$oDashlet = $aDashlets[$aKeys[$idx]];
|
||||||
if ($oDashlet::IsVisible()) {
|
if ($oDashlet::IsVisible())
|
||||||
|
{
|
||||||
$bNoVisibleFound = false;
|
$bNoVisibleFound = false;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
unset($aDashlets[$aKeys[$idx]]);
|
unset($aDashlets[$aKeys[$idx]]);
|
||||||
}
|
}
|
||||||
$idx++;
|
$idx++;
|
||||||
@@ -79,17 +82,22 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
|
|
||||||
protected function TrimCellsArray($aCells)
|
protected function TrimCellsArray($aCells)
|
||||||
{
|
{
|
||||||
foreach ($aCells as $key => $aDashlets) {
|
foreach($aCells as $key => $aDashlets)
|
||||||
|
{
|
||||||
$aCells[$key] = $this->TrimCell($aDashlets);
|
$aCells[$key] = $this->TrimCell($aDashlets);
|
||||||
}
|
}
|
||||||
$aKeys = array_reverse(array_keys($aCells));
|
$aKeys = array_reverse(array_keys($aCells));
|
||||||
$idx = 0;
|
$idx = 0;
|
||||||
$bNoVisibleFound = true;
|
$bNoVisibleFound = true;
|
||||||
while ($idx < count($aKeys) && $bNoVisibleFound) {
|
while($idx < count($aKeys) && $bNoVisibleFound)
|
||||||
|
{
|
||||||
$aDashlets = $aCells[$aKeys[$idx]];
|
$aDashlets = $aCells[$aKeys[$idx]];
|
||||||
if (count($aDashlets) > 0) {
|
if (count($aDashlets) > 0)
|
||||||
|
{
|
||||||
$bNoVisibleFound = false;
|
$bNoVisibleFound = false;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
unset($aCells[$aKeys[$idx]]);
|
unset($aCells[$aKeys[$idx]]);
|
||||||
}
|
}
|
||||||
$idx++;
|
$idx++;
|
||||||
@@ -104,7 +112,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
* @param bool $bEditMode
|
* @param bool $bEditMode
|
||||||
* @param array $aExtraParams
|
* @param array $aExtraParams
|
||||||
*/
|
*/
|
||||||
public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = [])
|
public function Render($oPage, $aCells, $bEditMode = false, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
||||||
$aCells = $this->TrimCellsArray($aCells);
|
$aCells = $this->TrimCellsArray($aCells);
|
||||||
@@ -149,7 +157,8 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
|
|
||||||
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
||||||
|
|
||||||
if ($bEditMode) { // Add one row for extensibility
|
if ($bEditMode) // Add one row for extensibility
|
||||||
|
{
|
||||||
$oDashboardRow = new DashboardRow();
|
$oDashboardRow = new DashboardRow();
|
||||||
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||||
|
|
||||||
@@ -171,7 +180,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
|||||||
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
||||||
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
||||||
|
|
||||||
return [$iColNumber, $iRowNumber];
|
return array($iColNumber, $iRowNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,13 +191,13 @@ class DashboardLayoutOneCol extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 1;
|
$this->iNbCols = 1;
|
||||||
}
|
}
|
||||||
public static function GetInfo()
|
static public function GetInfo()
|
||||||
{
|
{
|
||||||
return [
|
return array(
|
||||||
'label' => 'One Column',
|
'label' => 'One Column',
|
||||||
'icon' => 'images/layout_1col.png',
|
'icon' => 'images/layout_1col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,13 +208,13 @@ class DashboardLayoutTwoCols extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 2;
|
$this->iNbCols = 2;
|
||||||
}
|
}
|
||||||
public static function GetInfo()
|
static public function GetInfo()
|
||||||
{
|
{
|
||||||
return [
|
return array(
|
||||||
'label' => 'Two Columns',
|
'label' => 'Two Columns',
|
||||||
'icon' => 'images/layout_2col.png',
|
'icon' => 'images/layout_2col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,12 +225,12 @@ class DashboardLayoutThreeCols extends DashboardLayoutMultiCol
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->iNbCols = 3;
|
$this->iNbCols = 3;
|
||||||
}
|
}
|
||||||
public static function GetInfo()
|
static public function GetInfo()
|
||||||
{
|
{
|
||||||
return [
|
return array(
|
||||||
'label' => 'Two Columns',
|
'label' => 'Two Columns',
|
||||||
'icon' => 'images/layout_3col.png',
|
'icon' => 'images/layout_3col.png',
|
||||||
'description' => '',
|
'description' => '',
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -238,10 +238,6 @@ The object can be modified.]]></description>
|
|||||||
<description>Creation flag</description>
|
<description>Creation flag</description>
|
||||||
<type>boolean</type>
|
<type>boolean</type>
|
||||||
</event_datum>
|
</event_datum>
|
||||||
<event_datum id="stimulus_applied">
|
|
||||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
|
||||||
<type>string</type>
|
|
||||||
</event_datum>
|
|
||||||
<event_datum id="debug_info">
|
<event_datum id="debug_info">
|
||||||
<description>Debug string</description>
|
<description>Debug string</description>
|
||||||
<type>string</type>
|
<type>string</type>
|
||||||
@@ -267,10 +263,6 @@ Call $this->AddCheckWarning($sWarningMessage) to display a warning.
|
|||||||
<description>Creation flag</description>
|
<description>Creation flag</description>
|
||||||
<type>boolean</type>
|
<type>boolean</type>
|
||||||
</event_datum>
|
</event_datum>
|
||||||
<event_datum id="stimulus_applied">
|
|
||||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
|
||||||
<type>string</type>
|
|
||||||
</event_datum>
|
|
||||||
<event_datum id="debug_info">
|
<event_datum id="debug_info">
|
||||||
<description>Debug string</description>
|
<description>Debug string</description>
|
||||||
<type>string</type>
|
<type>string</type>
|
||||||
@@ -298,10 +290,6 @@ The modifications can be propagated to other objects.]]></description>
|
|||||||
<description><![CDATA[For updates, the list of changes done during this operation]]></description>
|
<description><![CDATA[For updates, the list of changes done during this operation]]></description>
|
||||||
<type>array</type>
|
<type>array</type>
|
||||||
</event_datum>
|
</event_datum>
|
||||||
<event_datum id="stimulus_applied">
|
|
||||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
|
||||||
<type>string</type>
|
|
||||||
</event_datum>
|
|
||||||
<event_datum id="debug_info">
|
<event_datum id="debug_info">
|
||||||
<description>Debug string</description>
|
<description>Debug string</description>
|
||||||
<type>string</type>
|
<type>string</type>
|
||||||
@@ -432,14 +420,6 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
|||||||
<description>The object inserted</description>
|
<description>The object inserted</description>
|
||||||
<type>DBObject</type>
|
<type>DBObject</type>
|
||||||
</event_datum>
|
</event_datum>
|
||||||
<event_datum id="is_new">
|
|
||||||
<description>Creation flag</description>
|
|
||||||
<type>boolean</type>
|
|
||||||
</event_datum>
|
|
||||||
<event_datum id="stimulus_applied">
|
|
||||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
|
||||||
<type>string</type>
|
|
||||||
</event_datum>
|
|
||||||
<event_datum id="debug_info">
|
<event_datum id="debug_info">
|
||||||
<description>Debug string</description>
|
<description>Debug string</description>
|
||||||
<type>string</type>
|
<type>string</type>
|
||||||
|
|||||||
@@ -81,29 +81,40 @@ class DataTable
|
|||||||
// Identified tables can have their own specific settings
|
// Identified tables can have their own specific settings
|
||||||
$oCustomSettings = DataTableSettings::GetTableSettings($this->aClassAliases, $this->sTableId);
|
$oCustomSettings = DataTableSettings::GetTableSettings($this->aClassAliases, $this->sTableId);
|
||||||
|
|
||||||
if ($oCustomSettings != null) {
|
if ($oCustomSettings != null)
|
||||||
|
{
|
||||||
// Custom settings overload the default ones
|
// Custom settings overload the default ones
|
||||||
$this->bUseCustomSettings = true;
|
$this->bUseCustomSettings = true;
|
||||||
if ($this->oDefaultSettings->iDefaultPageSize == 0) {
|
if ($this->oDefaultSettings->iDefaultPageSize == 0)
|
||||||
|
{
|
||||||
$oCustomSettings->iDefaultPageSize = 0;
|
$oCustomSettings->iDefaultPageSize = 0;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oCustomSettings = $oSettings;
|
$oCustomSettings = $oSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oCustomSettings->iDefaultPageSize > 0) {
|
if ($oCustomSettings->iDefaultPageSize > 0)
|
||||||
|
{
|
||||||
$this->oSet->SetLimit($oCustomSettings->iDefaultPageSize);
|
$this->oSet->SetLimit($oCustomSettings->iDefaultPageSize);
|
||||||
}
|
}
|
||||||
$this->oSet->SetOrderBy($oCustomSettings->GetSortOrder());
|
$this->oSet->SetOrderBy($oCustomSettings->GetSortOrder());
|
||||||
|
|
||||||
// Load only the requested columns
|
// Load only the requested columns
|
||||||
$aColumnsToLoad = [];
|
$aColumnsToLoad = array();
|
||||||
foreach ($oCustomSettings->aColumns as $sAlias => $aColumnsInfo) {
|
foreach($oCustomSettings->aColumns as $sAlias => $aColumnsInfo)
|
||||||
foreach ($aColumnsInfo as $sAttCode => $aData) {
|
{
|
||||||
if ($sAttCode != '_key_') {
|
foreach($aColumnsInfo as $sAttCode => $aData)
|
||||||
if ($aData['checked']) {
|
{
|
||||||
|
if ($sAttCode != '_key_')
|
||||||
|
{
|
||||||
|
if ($aData['checked'])
|
||||||
|
{
|
||||||
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// See if this column is a must to load
|
// See if this column is a must to load
|
||||||
$sClass = $this->aClassAliases[$sAlias];
|
$sClass = $this->aClassAliases[$sAlias];
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||||
@@ -116,11 +127,14 @@ class DataTable
|
|||||||
}
|
}
|
||||||
$this->oSet->OptimizeColumnLoad($aColumnsToLoad);
|
$this->oSet->OptimizeColumnLoad($aColumnsToLoad);
|
||||||
|
|
||||||
|
|
||||||
$bToolkitMenu = true;
|
$bToolkitMenu = true;
|
||||||
if (isset($aExtraParams['toolkit_menu'])) {
|
if (isset($aExtraParams['toolkit_menu']))
|
||||||
|
{
|
||||||
$bToolkitMenu = (bool) $aExtraParams['toolkit_menu'];
|
$bToolkitMenu = (bool) $aExtraParams['toolkit_menu'];
|
||||||
}
|
}
|
||||||
if (UserRights::IsPortalUser()) {
|
if (UserRights::IsPortalUser())
|
||||||
|
{
|
||||||
// Portal users have a limited access to data, for now they can only see what's configured for them
|
// Portal users have a limited access to data, for now they can only see what's configured for them
|
||||||
$bToolkitMenu = false;
|
$bToolkitMenu = false;
|
||||||
}
|
}
|
||||||
@@ -174,7 +188,7 @@ class DataTable
|
|||||||
|
|
||||||
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
||||||
|
|
||||||
$aOptions = [
|
$aOptions = array(
|
||||||
'sPersistentId' => '',
|
'sPersistentId' => '',
|
||||||
'sFilter' => $this->oSet->GetFilter()->serialize(),
|
'sFilter' => $this->oSet->GetFilter()->serialize(),
|
||||||
'oColumns' => $aColumns,
|
'oColumns' => $aColumns,
|
||||||
@@ -188,11 +202,12 @@ class DataTable
|
|||||||
'sTableId' => $this->sTableId,
|
'sTableId' => $this->sTableId,
|
||||||
'oExtraParams' => $aExtraParams,
|
'oExtraParams' => $aExtraParams,
|
||||||
'sRenderUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php',
|
'sRenderUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php',
|
||||||
'oRenderParameters' => ['str' => ''], // Forces JSON to encode this as a object...
|
'oRenderParameters' => array('str' => ''), // Forces JSON to encode this as a object...
|
||||||
'oDefaultSettings' => ['str' => ''], // Forces JSON to encode this as a object...
|
'oDefaultSettings' => array('str' => ''), // Forces JSON to encode this as a object...
|
||||||
'oLabels' => ['moveup' => Dict::S('UI:Button:MoveUp'), 'movedown' => Dict::S('UI:Button:MoveDown')],
|
'oLabels' => array('moveup' => Dict::S('UI:Button:MoveUp'), 'movedown' => Dict::S('UI:Button:MoveDown')),
|
||||||
];
|
);
|
||||||
if ($this->oDefaultSettings != null) {
|
if($this->oDefaultSettings != null)
|
||||||
|
{
|
||||||
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
||||||
}
|
}
|
||||||
$sJSOptions = json_encode($aOptions);
|
$sJSOptions = json_encode($aOptions);
|
||||||
@@ -207,14 +222,16 @@ class DataTable
|
|||||||
*/
|
*/
|
||||||
public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams)
|
public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
if ($iPageSize < 1) {
|
if ($iPageSize < 1)
|
||||||
|
{
|
||||||
$iPageSize = -1; // convention: no pagination
|
$iPageSize = -1; // convention: no pagination
|
||||||
}
|
}
|
||||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||||
|
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
foreach ($aValues as $aRow) {
|
foreach($aValues as $aRow)
|
||||||
|
{
|
||||||
$sHtml .= $oPage->GetTableRow($aRow, $aAttribs);
|
$sHtml .= $oPage->GetTableRow($aRow, $aAttribs);
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -228,9 +245,12 @@ class DataTable
|
|||||||
*/
|
*/
|
||||||
protected function GetObjectCount(WebPage $oPage, $sSelectMode)
|
protected function GetObjectCount(WebPage $oPage, $sSelectMode)
|
||||||
{
|
{
|
||||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) {
|
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
||||||
|
{
|
||||||
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderSelection', '<span id="total">'.$this->iNbObjects.'</span>', '<span class="selectedCount">0</span>').'</div>';
|
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderSelection', '<span id="total">'.$this->iNbObjects.'</span>', '<span class="selectedCount">0</span>').'</div>';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderNoSelection', '<span id="total">'.$this->iNbObjects.'</span>').'</div>';
|
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderNoSelection', '<span id="total">'.$this->iNbObjects.'</span>').'</div>';
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -247,19 +267,26 @@ class DataTable
|
|||||||
protected function GetPager(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex)
|
protected function GetPager(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex)
|
||||||
{
|
{
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
if ($iPageSize < 1) { // Display all
|
if ($iPageSize < 1) // Display all
|
||||||
|
{
|
||||||
$sPagerStyle = 'style="display:none"'; // no limit: display the full table, so hide the "pager" UI
|
$sPagerStyle = 'style="display:none"'; // no limit: display the full table, so hide the "pager" UI
|
||||||
// WARNING: mPDF does not take the "display" style into account
|
// WARNING: mPDF does not take the "display" style into account
|
||||||
// when applied to a <td> or a <table> tag, so make sure you apply this to a div
|
// when applied to a <td> or a <table> tag, so make sure you apply this to a div
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sPagerStyle = '';
|
$sPagerStyle = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$sCombo = '<select class="pagesize">';
|
$sCombo = '<select class="pagesize">';
|
||||||
if ($iPageSize < 1) {
|
if($iPageSize < 1)
|
||||||
|
{
|
||||||
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||||
} else {
|
}
|
||||||
for ($iPage = 1; $iPage < 5; $iPage++) {
|
else
|
||||||
|
{
|
||||||
|
for($iPage = 1; $iPage < 5; $iPage++)
|
||||||
|
{
|
||||||
$iNbItems = $iPage * $iDefaultPageSize;
|
$iNbItems = $iPage * $iDefaultPageSize;
|
||||||
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
||||||
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
||||||
@@ -273,20 +300,26 @@ class DataTable
|
|||||||
$sPageSizeCombo = Dict::Format('UI:Pagination:PageSize', $sCombo);
|
$sPageSizeCombo = Dict::Format('UI:Pagination:PageSize', $sCombo);
|
||||||
|
|
||||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||||
if ($iNbPages == 1) {
|
if ($iNbPages == 1)
|
||||||
|
{
|
||||||
// No need to display the pager
|
// No need to display the pager
|
||||||
$sPagerStyle = 'style="display:none"';
|
$sPagerStyle = 'style="display:none"';
|
||||||
}
|
}
|
||||||
$aPagesToDisplay = [];
|
$aPagesToDisplay = array();
|
||||||
for ($idx = 0; $idx <= min(4, $iNbPages - 1); $idx++) {
|
for($idx = 0; $idx <= min(4, $iNbPages-1); $idx++)
|
||||||
if ($idx == 0) {
|
{
|
||||||
|
if ($idx == 0)
|
||||||
|
{
|
||||||
$aPagesToDisplay[$idx] = '<span page="0" class="curr_page">1</span>';
|
$aPagesToDisplay[$idx] = '<span page="0" class="curr_page">1</span>';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$aPagesToDisplay[$idx] = "<span id=\"gotopage_$idx\" class=\"gotopage\" page=\"$idx\">".(1+$idx)."</span>";
|
$aPagesToDisplay[$idx] = "<span id=\"gotopage_$idx\" class=\"gotopage\" page=\"$idx\">".(1+$idx)."</span>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$iLastPageIdx = $iNbPages - 1;
|
$iLastPageIdx = $iNbPages - 1;
|
||||||
if (!isset($aPagesToDisplay[$iLastPageIdx])) {
|
if (!isset($aPagesToDisplay[$iLastPageIdx]))
|
||||||
|
{
|
||||||
unset($aPagesToDisplay[$idx - 1]); // remove the last page added to make room for the very last page
|
unset($aPagesToDisplay[$idx - 1]); // remove the last page added to make room for the very last page
|
||||||
$aPagesToDisplay[$iLastPageIdx] = "<span id=\"gotopage_$iLastPageIdx\" class=\"gotopage\" page=\"$iLastPageIdx\">... $iNbPages</span>";
|
$aPagesToDisplay[$iLastPageIdx] = "<span id=\"gotopage_$iLastPageIdx\" class=\"gotopage\" page=\"$iLastPageIdx\">... $iNbPages</span>";
|
||||||
}
|
}
|
||||||
@@ -353,19 +386,22 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams)
|
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams)
|
||||||
{
|
{
|
||||||
if (!$oPage->IsPrintableVersion()) {
|
if (!$oPage->IsPrintableVersion())
|
||||||
|
{
|
||||||
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
||||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
||||||
|
|
||||||
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
||||||
$aActions = [
|
$aActions = array(
|
||||||
$oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem(),
|
$oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem(),
|
||||||
];
|
);
|
||||||
$this->oSet->Rewind();
|
$this->oSet->Rewind();
|
||||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId);
|
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId);
|
||||||
$this->oSet->Rewind();
|
$this->oSet->Rewind();
|
||||||
$sHtml .= $oPage->RenderPopupMenuItems($aActions);
|
$sHtml .= $oPage->RenderPopupMenuItems($aActions);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sHtml = '';
|
$sHtml = '';
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -422,7 +458,7 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
public function GetAsHash($oSetting)
|
public function GetAsHash($oSetting)
|
||||||
{
|
{
|
||||||
$aSettings = ['iDefaultPageSize' => $oSetting->iDefaultPageSize, 'oColumns' => $oSetting->aColumns];
|
$aSettings = array('iDefaultPageSize' => $oSetting->iDefaultPageSize, 'oColumns' => $oSetting->aColumns);
|
||||||
return $aSettings;
|
return $aSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,46 +474,55 @@ EOF;
|
|||||||
*/
|
*/
|
||||||
protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink)
|
protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink)
|
||||||
{
|
{
|
||||||
$aAttribs = [];
|
$aAttribs = array();
|
||||||
if ($sSelectMode == 'multiple') {
|
if ($sSelectMode == 'multiple')
|
||||||
$aAttribs['form::select'] = [
|
{
|
||||||
|
$aAttribs['form::select'] = array(
|
||||||
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>",
|
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>",
|
||||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||||
'metadata' => [],
|
'metadata' => array(),
|
||||||
];
|
);
|
||||||
} elseif ($sSelectMode == 'single') {
|
}
|
||||||
$aAttribs['form::select'] = ['label' => '', 'description' => '', 'metadata' => []];
|
else if ($sSelectMode == 'single')
|
||||||
|
{
|
||||||
|
$aAttribs['form::select'] = array('label' => '', 'description' => '', 'metadata' => array());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->aClassAliases as $sAlias => $sClassName) {
|
foreach($this->aClassAliases as $sAlias => $sClassName)
|
||||||
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
{
|
||||||
if ($aData['checked']) {
|
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||||
if ($sAttCode == '_key_') {
|
{
|
||||||
|
if ($aData['checked'])
|
||||||
|
{
|
||||||
|
if ($sAttCode == '_key_')
|
||||||
|
{
|
||||||
$sAttLabel = MetaModel::GetName($sClassName);
|
$sAttLabel = MetaModel::GetName($sClassName);
|
||||||
|
|
||||||
$aAttribs['key_'.$sAlias] = [
|
$aAttribs['key_'.$sAlias] = array(
|
||||||
'label' => $sAttLabel,
|
'label' => $sAttLabel,
|
||||||
'description' => '',
|
'description' => '',
|
||||||
'metadata' => [
|
'metadata' => array(
|
||||||
'object_class' => $sClassName,
|
'object_class' => $sClassName,
|
||||||
'attribute_label' => $sAttLabel,
|
'attribute_label' => $sAttLabel,
|
||||||
],
|
),
|
||||||
];
|
);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
||||||
$sAttDefClass = get_class($oAttDef);
|
$sAttDefClass = get_class($oAttDef);
|
||||||
$sAttLabel = MetaModel::GetLabel($sClassName, $sAttCode);
|
$sAttLabel = MetaModel::GetLabel($sClassName, $sAttCode);
|
||||||
|
|
||||||
$aAttribs[$sAttCode.'_'.$sAlias] = [
|
$aAttribs[$sAttCode.'_'.$sAlias] = array(
|
||||||
'label' => $sAttLabel,
|
'label' => $sAttLabel,
|
||||||
'description' => $oAttDef->GetOrderByHint(),
|
'description' => $oAttDef->GetOrderByHint(),
|
||||||
'metadata' => [
|
'metadata' => array(
|
||||||
'object_class' => $sClassName,
|
'object_class' => $sClassName,
|
||||||
'attribute_code' => $sAttCode,
|
'attribute_code' => $sAttCode,
|
||||||
'attribute_type' => $sAttDefClass,
|
'attribute_type' => $sAttDefClass,
|
||||||
'attribute_label' => $sAttLabel,
|
'attribute_label' => $sAttLabel,
|
||||||
],
|
),
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,6 +530,7 @@ EOF;
|
|||||||
return $aAttribs;
|
return $aAttribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $aColumns
|
* @param $aColumns
|
||||||
* @param $sSelectMode
|
* @param $sSelectMode
|
||||||
@@ -503,74 +549,104 @@ EOF;
|
|||||||
protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
$bLocalize = true;
|
$bLocalize = true;
|
||||||
if (isset($aExtraParams['localize_values'])) {
|
if (isset($aExtraParams['localize_values']))
|
||||||
|
{
|
||||||
$bLocalize = (bool) $aExtraParams['localize_values'];
|
$bLocalize = (bool) $aExtraParams['localize_values'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aValues = [];
|
$aValues = array();
|
||||||
$aAttDefsCache = [];
|
$aAttDefsCache = array();
|
||||||
$this->oSet->Seek(0);
|
$this->oSet->Seek(0);
|
||||||
$iMaxObjects = $iPageSize;
|
$iMaxObjects = $iPageSize;
|
||||||
while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0)) {
|
while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0))
|
||||||
|
{
|
||||||
$bFirstObject = true;
|
$bFirstObject = true;
|
||||||
$aRow = [];
|
$aRow = array();
|
||||||
foreach ($this->aClassAliases as $sAlias => $sClassName) {
|
foreach($this->aClassAliases as $sAlias => $sClassName)
|
||||||
if (is_object($aObjects[$sAlias])) {
|
{
|
||||||
|
if (is_object($aObjects[$sAlias]))
|
||||||
|
{
|
||||||
$sHilightClass = MetaModel::GetHilightClass($sClassName, $aObjects[$sAlias]);
|
$sHilightClass = MetaModel::GetHilightClass($sClassName, $aObjects[$sAlias]);
|
||||||
if ($sHilightClass != '') {
|
if ($sHilightClass != '')
|
||||||
|
{
|
||||||
$aRow['@class'] = $sHilightClass;
|
$aRow['@class'] = $sHilightClass;
|
||||||
}
|
}
|
||||||
if ((($sSelectMode == 'single') || ($sSelectMode == 'multiple')) && $bFirstObject) {
|
if ((($sSelectMode == 'single') || ($sSelectMode == 'multiple')) && $bFirstObject)
|
||||||
if (array_key_exists('selection_enabled', $aExtraParams) && isset($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()])) {
|
{
|
||||||
|
if (array_key_exists('selection_enabled', $aExtraParams) && isset($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]))
|
||||||
|
{
|
||||||
$sDisabled = ($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]) ? '' : ' disabled="disabled"';
|
$sDisabled = ($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]) ? '' : ' disabled="disabled"';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sDisabled = '';
|
$sDisabled = '';
|
||||||
}
|
}
|
||||||
if ($sSelectMode == 'single') {
|
if ($sSelectMode == 'single')
|
||||||
|
{
|
||||||
$aRow['form::select'] = "<input type=\"radio\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
$aRow['form::select'] = "<input type=\"radio\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$aRow['form::select'] = "<input type=\"checkbox\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject[]\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
$aRow['form::select'] = "<input type=\"checkbox\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject[]\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||||
if ($aData['checked']) {
|
{
|
||||||
if ($sAttCode == '_key_') {
|
if ($aData['checked'])
|
||||||
$aRow['key_'.$sAlias] = [
|
{
|
||||||
|
if ($sAttCode == '_key_')
|
||||||
|
{
|
||||||
|
$aRow['key_'.$sAlias] = array(
|
||||||
'value_raw' => $aObjects[$sAlias]->GetKey(),
|
'value_raw' => $aObjects[$sAlias]->GetKey(),
|
||||||
'value_html' => $aObjects[$sAlias]->GetHyperLink(),
|
'value_html' => $aObjects[$sAlias]->GetHyperLink(),
|
||||||
];
|
);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Prepare att. def. classes cache to avoid retrieving AttDef for each row
|
// Prepare att. def. classes cache to avoid retrieving AttDef for each row
|
||||||
if (!isset($aAttDefsCache[$sClassName][$sAttCode])) {
|
if(!isset($aAttDefsCache[$sClassName][$sAttCode]))
|
||||||
|
{
|
||||||
$aAttDefClassesCache[$sClassName][$sAttCode] = get_class(MetaModel::GetAttributeDef($sClassName, $sAttCode));
|
$aAttDefClassesCache[$sClassName][$sAttCode] = get_class(MetaModel::GetAttributeDef($sClassName, $sAttCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only retrieve raw (stored) value for simple fields
|
// Only retrieve raw (stored) value for simple fields
|
||||||
$bExcludeRawValue = false;
|
$bExcludeRawValue = false;
|
||||||
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) {
|
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
||||||
if (is_a($aAttDefClassesCache[$sClassName][$sAttCode], $sAttDefClassToExclude, true)) {
|
{
|
||||||
|
if (is_a($aAttDefClassesCache[$sClassName][$sAttCode], $sAttDefClassToExclude, true))
|
||||||
|
{
|
||||||
$bExcludeRawValue = true;
|
$bExcludeRawValue = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($bExcludeRawValue) {
|
if($bExcludeRawValue)
|
||||||
|
{
|
||||||
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
|
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
|
||||||
} else {
|
}
|
||||||
$aRow[$sAttCode.'_'.$sAlias] = [
|
else
|
||||||
|
{
|
||||||
|
$aRow[$sAttCode.'_'.$sAlias] = array(
|
||||||
'value_raw' => $aObjects[$sAlias]->Get($sAttCode),
|
'value_raw' => $aObjects[$sAlias]->Get($sAttCode),
|
||||||
'value_html' => $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize),
|
'value_html' => $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize),
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
else
|
||||||
if ($aData['checked']) {
|
{
|
||||||
if ($sAttCode == '_key_') {
|
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||||
|
{
|
||||||
|
if ($aData['checked'])
|
||||||
|
{
|
||||||
|
if ($sAttCode == '_key_')
|
||||||
|
{
|
||||||
$aRow['key_'.$sAlias] = '';
|
$aRow['key_'.$sAlias] = '';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$aRow[$sAttCode.'_'.$sAlias] = '';
|
$aRow[$sAttCode.'_'.$sAlias] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -605,7 +681,8 @@ EOF;
|
|||||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||||
if ($iPageSize < 1) {
|
if ($iPageSize < 1)
|
||||||
|
{
|
||||||
$iPageSize = -1; // convention: no pagination
|
$iPageSize = -1; // convention: no pagination
|
||||||
}
|
}
|
||||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||||
@@ -614,7 +691,8 @@ EOF;
|
|||||||
|
|
||||||
$sHtml = '<table class="listContainer object-list">';
|
$sHtml = '<table class="listContainer object-list">';
|
||||||
|
|
||||||
foreach ($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue) {
|
foreach($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue)
|
||||||
|
{
|
||||||
$aExtraParams['query_params'][$sName] = $sValue;
|
$aExtraParams['query_params'][$sName] = $sValue;
|
||||||
}
|
}
|
||||||
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
||||||
@@ -629,16 +707,20 @@ EOF;
|
|||||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them
|
$sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them
|
||||||
$sSelectModeJS = '';
|
$sSelectModeJS = '';
|
||||||
$sHeaders = '';
|
$sHeaders = '';
|
||||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) {
|
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
||||||
|
{
|
||||||
$sSelectModeJS = $sSelectMode;
|
$sSelectModeJS = $sSelectMode;
|
||||||
$sHeaders = 'headers: { 0: {sorter: false}},';
|
$sHeaders = 'headers: { 0: {sorter: false}},';
|
||||||
}
|
}
|
||||||
$sDisplayKey = ($bViewLink) ? 'true' : 'false';
|
$sDisplayKey = ($bViewLink) ? 'true' : 'false';
|
||||||
// Protect against duplicate elements in the Zlist
|
// Protect against duplicate elements in the Zlist
|
||||||
$aUniqueOrderedList = [];
|
$aUniqueOrderedList = array();
|
||||||
foreach ($this->aClassAliases as $sAlias => $sClassName) {
|
foreach($this->aClassAliases as $sAlias => $sClassName)
|
||||||
foreach ($aColumns[$sAlias] as $sAttCode => $aData) {
|
{
|
||||||
if ($aData['checked']) {
|
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||||
|
{
|
||||||
|
if ($aData['checked'])
|
||||||
|
{
|
||||||
$aUniqueOrderedList[$sAttCode] = true;
|
$aUniqueOrderedList[$sAttCode] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -650,27 +732,36 @@ EOF;
|
|||||||
$this->oSet->ApplyParameters();
|
$this->oSet->ApplyParameters();
|
||||||
// Display the actual sort order of the table
|
// Display the actual sort order of the table
|
||||||
$aRealSortOrder = $this->oSet->GetRealSortOrder();
|
$aRealSortOrder = $this->oSet->GetRealSortOrder();
|
||||||
$aDefaultSort = [];
|
$aDefaultSort = array();
|
||||||
$iColOffset = 0;
|
$iColOffset = 0;
|
||||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple')) {
|
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
||||||
|
{
|
||||||
$iColOffset += 1;
|
$iColOffset += 1;
|
||||||
}
|
}
|
||||||
if ($bViewLink) {
|
if ($bViewLink)
|
||||||
|
{
|
||||||
// $iColOffset += 1;
|
// $iColOffset += 1;
|
||||||
}
|
}
|
||||||
foreach ($aRealSortOrder as $sColCode => $bAscending) {
|
foreach($aRealSortOrder as $sColCode => $bAscending)
|
||||||
|
{
|
||||||
$iPos = array_search($sColCode, $aUniqueOrderedList);
|
$iPos = array_search($sColCode, $aUniqueOrderedList);
|
||||||
if ($iPos !== false) {
|
if ($iPos !== false)
|
||||||
|
{
|
||||||
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
||||||
} elseif (($iPos = array_search(preg_replace('/_friendlyname$/', '', $sColCode), $aUniqueOrderedList)) !== false) {
|
}
|
||||||
|
else if (($iPos = array_search(preg_replace('/_friendlyname$/', '', $sColCode), $aUniqueOrderedList)) !== false)
|
||||||
|
{
|
||||||
// if sorted on the friendly name of an external key, then consider it sorted on the column that shows the links
|
// if sorted on the friendly name of an external key, then consider it sorted on the column that shows the links
|
||||||
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
||||||
} elseif ($sColCode == 'friendlyname' && $bViewLink) {
|
}
|
||||||
|
else if($sColCode == 'friendlyname' && $bViewLink)
|
||||||
|
{
|
||||||
$aDefaultSort[] = "[".($iColOffset).",".($bAscending ? '0' : '1')."]";
|
$aDefaultSort[] = "[".($iColOffset).",".($bAscending ? '0' : '1')."]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sFakeSortList = '';
|
$sFakeSortList = '';
|
||||||
if (count($aDefaultSort) > 0) {
|
if (count($aDefaultSort) > 0)
|
||||||
|
{
|
||||||
$sFakeSortList = '['.implode(',', $aDefaultSort).']';
|
$sFakeSortList = '['.implode(',', $aDefaultSort).']';
|
||||||
}
|
}
|
||||||
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
||||||
@@ -694,7 +785,8 @@ oTable
|
|||||||
});
|
});
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
if ($sFakeSortList != '') {
|
if ($sFakeSortList != '')
|
||||||
|
{
|
||||||
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
||||||
}
|
}
|
||||||
return $sHtml;
|
return $sHtml;
|
||||||
@@ -711,9 +803,12 @@ JS
|
|||||||
$iPageIndex = 0;
|
$iPageIndex = 0;
|
||||||
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||||
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
|
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
|
||||||
if ($iDefaultPageSize < 1) {
|
if ($iDefaultPageSize < 1)
|
||||||
|
{
|
||||||
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().hide()");
|
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().hide()");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().show()");
|
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().show()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -770,7 +865,8 @@ class PrintableDataTable extends DataTable
|
|||||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||||
{
|
{
|
||||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||||
if ($iPageSize < 1) {
|
if ($iPageSize < 1)
|
||||||
|
{
|
||||||
$iPageSize = -1; // convention: no pagination
|
$iPageSize = -1; // convention: no pagination
|
||||||
}
|
}
|
||||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -105,7 +104,7 @@ class DisplayBlock
|
|||||||
*/
|
*/
|
||||||
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
public const ENUM_STYLE_CHART_AJAX = 'chart_ajax';
|
||||||
|
|
||||||
public const TAG_BLOCK = 'itopblock';
|
const TAG_BLOCK = 'itopblock';
|
||||||
/** @var \DBSearch */
|
/** @var \DBSearch */
|
||||||
protected $m_oFilter;
|
protected $m_oFilter;
|
||||||
protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions
|
protected $m_aConditions; // Conditions added to the filter -> avoid duplicate conditions
|
||||||
@@ -138,18 +137,20 @@ class DisplayBlock
|
|||||||
*
|
*
|
||||||
* @throws \ApplicationException
|
* @throws \ApplicationException
|
||||||
*/
|
*/
|
||||||
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = [], $oSet = null)
|
public function __construct(DBSearch $oFilter, $sStyle = self::ENUM_STYLE_LIST, $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||||
{
|
{
|
||||||
$this->m_oFilter = $oFilter->DeepClone();
|
$this->m_oFilter = $oFilter->DeepClone();
|
||||||
$this->m_aConditions = [];
|
$this->m_aConditions = array();
|
||||||
$this->m_sStyle = $sStyle;
|
$this->m_sStyle = $sStyle;
|
||||||
$this->m_bAsynchronous = $bAsynchronous;
|
$this->m_bAsynchronous = $bAsynchronous;
|
||||||
$this->m_aParams = $aParams;
|
$this->m_aParams = $aParams;
|
||||||
$this->m_oSet = $oSet;
|
$this->m_oSet = $oSet;
|
||||||
if (array_key_exists('show_obsolete_data', $aParams)) {
|
if (array_key_exists('show_obsolete_data', $aParams))
|
||||||
|
{
|
||||||
$this->m_bShowObsoleteData = $aParams['show_obsolete_data'];
|
$this->m_bShowObsoleteData = $aParams['show_obsolete_data'];
|
||||||
}
|
}
|
||||||
if ($this->m_bShowObsoleteData === null) {
|
if ($this->m_bShowObsoleteData === null)
|
||||||
|
{
|
||||||
// User defined
|
// User defined
|
||||||
$this->m_bShowObsoleteData = utils::ShowObsoleteData();
|
$this->m_bShowObsoleteData = utils::ShowObsoleteData();
|
||||||
}
|
}
|
||||||
@@ -409,18 +410,22 @@ class DisplayBlock
|
|||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = [])
|
public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = array())
|
||||||
{
|
{
|
||||||
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
$oDummyFilter = new DBObjectSearch($oSet->GetClass());
|
||||||
$aKeys = [];
|
$aKeys = array();
|
||||||
$oSet->OptimizeColumnLoad([$oSet->GetClassAlias() => []]); // No need to load all the columns just to get the id
|
$oSet->OptimizeColumnLoad(array($oSet->GetClassAlias() => array())); // No need to load all the columns just to get the id
|
||||||
while ($oObject = $oSet->Fetch()) {
|
while($oObject = $oSet->Fetch())
|
||||||
|
{
|
||||||
$aKeys[] = $oObject->GetKey();
|
$aKeys[] = $oObject->GetKey();
|
||||||
}
|
}
|
||||||
$oSet->Rewind();
|
$oSet->Rewind();
|
||||||
if (count($aKeys) > 0) {
|
if (count($aKeys) > 0)
|
||||||
|
{
|
||||||
$oDummyFilter->AddCondition('id', $aKeys, 'IN');
|
$oDummyFilter->AddCondition('id', $aKeys, 'IN');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oDummyFilter->AddCondition('id', 0, '=');
|
$oDummyFilter->AddCondition('id', 0, '=');
|
||||||
}
|
}
|
||||||
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams); // DisplayBlocks built this way are synchronous
|
$oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams); // DisplayBlocks built this way are synchronous
|
||||||
@@ -441,7 +446,7 @@ class DisplayBlock
|
|||||||
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ', 0);
|
$iStartPos = stripos($sTemplate, '<'.self::TAG_BLOCK.' ', 0);
|
||||||
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
$iEndPos = stripos($sTemplate, '</'.self::TAG_BLOCK.'>', $iStartPos);
|
||||||
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
$iEndTag = stripos($sTemplate, '>', $iStartPos);
|
||||||
$aParams = [];
|
$aParams = array();
|
||||||
|
|
||||||
if (($iStartPos === false) || ($iEndPos === false)) {
|
if (($iStartPos === false) || ($iEndPos === false)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -449,7 +454,7 @@ class DisplayBlock
|
|||||||
$sITopData = substr($sTemplate, 1 + $iEndTag, $iEndPos - $iEndTag - 1);
|
$sITopData = substr($sTemplate, 1 + $iEndTag, $iEndPos - $iEndTag - 1);
|
||||||
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
$sITopTag = substr($sTemplate, $iStartPos + strlen('<'.self::TAG_BLOCK), $iEndTag - $iStartPos - strlen('<'.self::TAG_BLOCK));
|
||||||
|
|
||||||
$aMatches = [];
|
$aMatches = array();
|
||||||
$sBlockClass = "DisplayBlock";
|
$sBlockClass = "DisplayBlock";
|
||||||
$bAsynchronous = false;
|
$bAsynchronous = false;
|
||||||
$sBlockType = 'list';
|
$sBlockType = 'list';
|
||||||
@@ -515,28 +520,25 @@ class DisplayBlock
|
|||||||
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
return new $sBlockClass($oFilter, $sBlockType, $bAsynchronous, $aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = [])
|
public function DisplayIntoContentBlock(UIContentBlock $oContentBlock, WebPage $oPage, $sId, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
$oContentBlock->AddSubBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Display(WebPage $oPage, $sId, $aExtraParams = [])
|
public function Display(WebPage $oPage, $sId, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
$oPage->AddUiBlock($this->GetDisplay($oPage, $sId, $aExtraParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = []): UIContentBlock
|
public function GetDisplay(WebPage $oPage, $sId, $aExtraParams = array()): UIContentBlock
|
||||||
{
|
{
|
||||||
$oHtml = new UIContentBlock($sId);
|
$oHtml = new UIContentBlock($sId);
|
||||||
|
|
||||||
$oHtml->AddCSSClass("display_block");
|
$oHtml->AddCSSClass("display_block");
|
||||||
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
$aExtraParams = array_merge($aExtraParams, $this->m_aParams);
|
||||||
$aExtraParams['currentId'] = $sId;
|
$aExtraParams['currentId'] = $sId;
|
||||||
$sExtraParams = addslashes(str_replace(
|
$sExtraParams = addslashes(str_replace('"', "'",
|
||||||
'"',
|
json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
||||||
"'",
|
|
||||||
json_encode($aExtraParams)
|
|
||||||
)); // JSON encode, change the style of the quotes and escape them
|
|
||||||
|
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
@@ -545,9 +547,9 @@ class DisplayBlock
|
|||||||
$sClass = $aExtraParams['this->class'];
|
$sClass = $aExtraParams['this->class'];
|
||||||
$iKey = $aExtraParams['this->id'];
|
$iKey = $aExtraParams['this->id'];
|
||||||
$oObj = MetaModel::GetObject($sClass, $iKey);
|
$oObj = MetaModel::GetObject($sClass, $iKey);
|
||||||
$aQueryParams = ['this->object()' => $oObj];
|
$aQueryParams = array('this->object()' => $oObj);
|
||||||
} else {
|
} else {
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,7 +585,8 @@ class DisplayBlock
|
|||||||
');
|
');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->m_sStyle == static::ENUM_STYLE_LIST) { // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
if ($this->m_sStyle == static::ENUM_STYLE_LIST) // Search form need to extract result list extra data, the simplest way is to expose this configuration
|
||||||
|
{
|
||||||
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
$listJsonExtraParams = json_encode(json_encode($aExtraParams));
|
||||||
$oPage->add_ready_script("
|
$oPage->add_ready_script("
|
||||||
$('#$sId').data('sExtraParams', ".$listJsonExtraParams.");
|
$('#$sId').data('sExtraParams', ".$listJsonExtraParams.");
|
||||||
@@ -603,7 +606,7 @@ class DisplayBlock
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function RenderContent(WebPage $oPage, $aExtraParams = [])
|
public function RenderContent(WebPage $oPage, $aExtraParams = array())
|
||||||
{
|
{
|
||||||
if (!isset($aExtraParams['currentId'])) {
|
if (!isset($aExtraParams['currentId'])) {
|
||||||
$sId = utils::GetUniqueId(); // Works only if the page is not an Ajax one !
|
$sId = utils::GetUniqueId(); // Works only if the page is not an Ajax one !
|
||||||
@@ -635,7 +638,7 @@ class DisplayBlock
|
|||||||
$this->CheckParams($this->m_sStyle, $aExtraParams);
|
$this->CheckParams($this->m_sStyle, $aExtraParams);
|
||||||
// Add the extra params into the filter if they make sense for such a filter
|
// Add the extra params into the filter if they make sense for such a filter
|
||||||
$bDoSearch = utils::ReadParam('dosearch', false);
|
$bDoSearch = utils::ReadParam('dosearch', false);
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
} else {
|
} else {
|
||||||
@@ -643,7 +646,7 @@ class DisplayBlock
|
|||||||
$sClass = $aExtraParams['this->class'];
|
$sClass = $aExtraParams['this->class'];
|
||||||
$iKey = $aExtraParams['this->id'];
|
$iKey = $aExtraParams['this->id'];
|
||||||
$oObj = MetaModel::GetObject($sClass, $iKey);
|
$oObj = MetaModel::GetObject($sClass, $iKey);
|
||||||
$aQueryParams = ['this->object()' => $oObj];
|
$aQueryParams = array('this->object()' => $oObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->m_oSet == null) {
|
if ($this->m_oSet == null) {
|
||||||
@@ -653,7 +656,7 @@ class DisplayBlock
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
$aFilterCodes = MetaModel::GetFiltersList($sClass);
|
||||||
$aCallSpec = [$sClass, 'MapContextParam'];
|
$aCallSpec = array($sClass, 'MapContextParam');
|
||||||
if (is_callable($aCallSpec)) {
|
if (is_callable($aCallSpec)) {
|
||||||
foreach ($oAppContext->GetNames() as $sContextParam) {
|
foreach ($oAppContext->GetNames() as $sContextParam) {
|
||||||
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
|
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
|
||||||
@@ -688,9 +691,11 @@ class DisplayBlock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($condition)) {
|
if (!is_null($condition))
|
||||||
|
{
|
||||||
$sOpCode = null; // default operator
|
$sOpCode = null; // default operator
|
||||||
if (is_array($condition)) {
|
if (is_array($condition))
|
||||||
|
{
|
||||||
// Multiple values, add them as AND X IN (v1, v2, v3...)
|
// Multiple values, add them as AND X IN (v1, v2, v3...)
|
||||||
$sOpCode = 'IN';
|
$sOpCode = 'IN';
|
||||||
}
|
}
|
||||||
@@ -698,22 +703,26 @@ class DisplayBlock
|
|||||||
$this->AddCondition($sFilterCode, $condition, $sOpCode, $bParseSearchString);
|
$this->AddCondition($sFilterCode, $condition, $sOpCode, $bParseSearchString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bDoSearch) {
|
if ($bDoSearch)
|
||||||
|
{
|
||||||
// Keep the table_id identifying this table if we're performing a search
|
// Keep the table_id identifying this table if we're performing a search
|
||||||
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||||
if ($sTableId != null) {
|
if ($sTableId != null)
|
||||||
|
{
|
||||||
$aExtraParams['table_id'] = $sTableId;
|
$aExtraParams['table_id'] = $sTableId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aOrderBy = [];
|
$aOrderBy = array();
|
||||||
if (isset($aExtraParams['order_by'])) {
|
if (isset($aExtraParams['order_by']))
|
||||||
|
{
|
||||||
// Convert the string describing the order_by parameter into an array
|
// Convert the string describing the order_by parameter into an array
|
||||||
// The syntax is +attCode1,-attCode2
|
// The syntax is +attCode1,-attCode2
|
||||||
// attCode1 => ascending, attCode2 => descending
|
// attCode1 => ascending, attCode2 => descending
|
||||||
$aTemp = explode(',', $aExtraParams['order_by']);
|
$aTemp = explode(',', $aExtraParams['order_by']);
|
||||||
foreach ($aTemp as $sTemp) {
|
foreach($aTemp as $sTemp)
|
||||||
$aMatches = [];
|
{
|
||||||
|
$aMatches = array();
|
||||||
if (preg_match('/^([+-])?(.+)$/', $sTemp, $aMatches)) {
|
if (preg_match('/^([+-])?(.+)$/', $sTemp, $aMatches)) {
|
||||||
$bAscending = true;
|
$bAscending = true;
|
||||||
if ($aMatches[1] == '-') {
|
if ($aMatches[1] == '-') {
|
||||||
@@ -794,13 +803,17 @@ class DisplayBlock
|
|||||||
$sHtml .= Dict::format('UI:Error:UnsupportedStyleOfBlock', $this->m_sStyle);
|
$sHtml .= Dict::format('UI:Error:UnsupportedStyleOfBlock', $this->m_sStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$bAutoReload = false;
|
$bAutoReload = false;
|
||||||
if (isset($aExtraParams['auto_reload'])) {
|
if (isset($aExtraParams['auto_reload']))
|
||||||
if ($aExtraParams['auto_reload'] === true) {
|
{
|
||||||
|
if ($aExtraParams['auto_reload'] === true)
|
||||||
|
{
|
||||||
// Note: does not work in the switch (case true) because a positive number evaluates to true!!!
|
// Note: does not work in the switch (case true) because a positive number evaluates to true!!!
|
||||||
$aExtraParams['auto_reload'] = 'standard';
|
$aExtraParams['auto_reload'] = 'standard';
|
||||||
}
|
}
|
||||||
switch ($aExtraParams['auto_reload']) {
|
switch($aExtraParams['auto_reload'])
|
||||||
|
{
|
||||||
case 'fast':
|
case 'fast':
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = MetaModel::GetConfig()->GetFastReloadInterval()*1000;
|
$iReloadInterval = MetaModel::GetConfig()->GetFastReloadInterval()*1000;
|
||||||
@@ -813,16 +826,20 @@ class DisplayBlock
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0)) {
|
if (is_numeric($aExtraParams['auto_reload']) && ($aExtraParams['auto_reload'] > 0))
|
||||||
|
{
|
||||||
$bAutoReload = true;
|
$bAutoReload = true;
|
||||||
$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload'])*1000;
|
$iReloadInterval = max(MetaModel::GetConfig()->Get('min_reload_interval'), $aExtraParams['auto_reload'])*1000;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// incorrect config, ignore it
|
// incorrect config, ignore it
|
||||||
$bAutoReload = false;
|
$bAutoReload = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) { // Search form do NOT auto-reload
|
if (($bAutoReload) && ($this->m_sStyle != static::ENUM_STYLE_SEARCH)) // Search form do NOT auto-reload
|
||||||
|
{
|
||||||
// Used either for asynchronous or auto_reload
|
// Used either for asynchronous or auto_reload
|
||||||
// does a json_encode twice to get a string usable as function parameter
|
// does a json_encode twice to get a string usable as function parameter
|
||||||
$sFilterBefore = $this->m_oFilter->serialize();
|
$sFilterBefore = $this->m_oFilter->serialize();
|
||||||
@@ -869,7 +886,8 @@ JS
|
|||||||
{
|
{
|
||||||
// Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
|
// Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
|
||||||
// Moreover, it keeps the query as simple as possible
|
// Moreover, it keeps the query as simple as possible
|
||||||
if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode]) {
|
if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode])
|
||||||
|
{
|
||||||
// Skip
|
// Skip
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -879,40 +897,51 @@ JS
|
|||||||
$bConditionAdded = false;
|
$bConditionAdded = false;
|
||||||
|
|
||||||
// If the condition is an external key with a class having a hierarchy, use a "below" criteria
|
// If the condition is an external key with a class having a hierarchy, use a "below" criteria
|
||||||
if (MetaModel::IsValidAttCode($sClass, $sFilterCode)) {
|
if (MetaModel::IsValidAttCode($sClass, $sFilterCode))
|
||||||
|
{
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
$oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey()) {
|
if ($oAttDef->IsExternalKey())
|
||||||
|
{
|
||||||
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
$sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
|
||||||
|
|
||||||
if ($sHierarchicalKeyCode !== false) {
|
if ($sHierarchicalKeyCode !== false)
|
||||||
|
{
|
||||||
$oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
$oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||||
if (($sOpCode == 'IN') && is_array($condition)) {
|
if (($sOpCode == 'IN') && is_array($condition))
|
||||||
|
{
|
||||||
$oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
|
$oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oFilter->AddCondition('id', $condition);
|
$oFilter->AddCondition('id', $condition);
|
||||||
}
|
}
|
||||||
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
$oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
|
||||||
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
$oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default
|
||||||
$this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
|
$this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
} elseif (($sOpCode == 'IN') && is_array($condition)) {
|
}
|
||||||
|
else if (($sOpCode == 'IN') && is_array($condition))
|
||||||
|
{
|
||||||
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
}
|
||||||
} elseif (($sOpCode == 'IN') && is_array($condition)) {
|
}
|
||||||
|
else if (($sOpCode == 'IN') && is_array($condition))
|
||||||
|
{
|
||||||
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
$this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
|
||||||
$bConditionAdded = true;
|
$bConditionAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In all other cases, just add the condition directly
|
// In all other cases, just add the condition directly
|
||||||
if (!$bConditionAdded) {
|
if (!$bConditionAdded)
|
||||||
|
{
|
||||||
$this->m_oFilter->AddCondition($sFilterCode, $condition, null); // Use the default 'loose' operator
|
$this->m_oFilter->AddCondition($sFilterCode, $condition, null); // Use the default 'loose' operator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function GetConditionIN($oFilter, $sFilterCode, $condition)
|
static protected function GetConditionIN($oFilter, $sFilterCode, $condition)
|
||||||
{
|
{
|
||||||
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
$oField = new FieldExpression($sFilterCode, $oFilter->GetClassAlias());
|
||||||
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
$sListExpr = '('.implode(', ', CMDBSource::Quote($condition)).')';
|
||||||
@@ -945,10 +974,13 @@ JS
|
|||||||
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
|
protected function MakeGroupByQuery(&$aExtraParams, &$oGroupByExp, &$sGroupByLabel, &$aGroupBy, &$sAggregationFunction, &$sFctVar, &$sAggregationAttr, &$sSql)
|
||||||
{
|
{
|
||||||
$sAlias = $this->m_oFilter->GetClassAlias();
|
$sAlias = $this->m_oFilter->GetClassAlias();
|
||||||
if (isset($aExtraParams['group_by_label'])) {
|
if (isset($aExtraParams['group_by_label']))
|
||||||
|
{
|
||||||
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
|
$oGroupByExp = Expression::FromOQL($aExtraParams['group_by']);
|
||||||
$sGroupByLabel = $aExtraParams['group_by_label'];
|
$sGroupByLabel = $aExtraParams['group_by_label'];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Backward compatibility: group_by is simply a field id
|
// Backward compatibility: group_by is simply a field id
|
||||||
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
|
$oGroupByExp = new FieldExpression($aExtraParams['group_by'], $sAlias);
|
||||||
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
|
$sGroupByLabel = MetaModel::GetLabel($this->m_oFilter->GetClass(), $aExtraParams['group_by']);
|
||||||
@@ -956,52 +988,61 @@ JS
|
|||||||
|
|
||||||
// Security filtering
|
// Security filtering
|
||||||
$aFields = $oGroupByExp->ListRequiredFields();
|
$aFields = $oGroupByExp->ListRequiredFields();
|
||||||
foreach ($aFields as $sFieldAlias) {
|
foreach($aFields as $sFieldAlias)
|
||||||
$aMatches = [];
|
{
|
||||||
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches)) {
|
$aMatches = array();
|
||||||
|
if (preg_match('/^([^.]+)\\.([^.]+)$/', $sFieldAlias, $aMatches))
|
||||||
|
{
|
||||||
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
|
$sFieldClass = $this->m_oFilter->GetClassName($aMatches[1]);
|
||||||
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
$oAttDef = MetaModel::GetAttributeDef($sFieldClass, $aMatches[2]);
|
||||||
if ($oAttDef instanceof AttributeOneWayPassword) {
|
if ($oAttDef instanceof AttributeOneWayPassword)
|
||||||
|
{
|
||||||
throw new Exception('Grouping on password fields is not supported.');
|
throw new Exception('Grouping on password fields is not supported.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aGroupBy = [];
|
$aGroupBy = array();
|
||||||
$aGroupBy['grouped_by_1'] = $oGroupByExp;
|
$aGroupBy['grouped_by_1'] = $oGroupByExp;
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params']))
|
||||||
|
{
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$aFunctions = [];
|
$aFunctions = array();
|
||||||
$sAggregationFunction = 'count';
|
$sAggregationFunction = 'count';
|
||||||
$sFctVar = '_itop_count_';
|
$sFctVar = '_itop_count_';
|
||||||
$sAggregationAttr = '';
|
$sAggregationAttr = '';
|
||||||
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute'])) {
|
if (isset($aExtraParams['aggregation_function']) && !empty($aExtraParams['aggregation_attribute']))
|
||||||
|
{
|
||||||
$sAggregationFunction = $aExtraParams['aggregation_function'];
|
$sAggregationFunction = $aExtraParams['aggregation_function'];
|
||||||
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
|
$sAggregationAttr = $aExtraParams['aggregation_attribute'];
|
||||||
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
|
$oAttrExpr = Expression::FromOQL('`'.$sAlias.'`.`'.$sAggregationAttr.'`');
|
||||||
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), [$oAttrExpr]);
|
$oFctExpr = new FunctionExpression(strtoupper($sAggregationFunction), array($oAttrExpr));
|
||||||
$sFctVar = '_itop_'.$sAggregationFunction.'_';
|
$sFctVar = '_itop_'.$sAggregationFunction.'_';
|
||||||
$aFunctions = [$sFctVar => $oFctExpr];
|
$aFunctions = array($sFctVar => $oFctExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sAggregationAttr)) {
|
if (!empty($sAggregationAttr))
|
||||||
|
{
|
||||||
$sClass = $this->m_oFilter->GetClass();
|
$sClass = $this->m_oFilter->GetClass();
|
||||||
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
|
$sAggregationAttr = MetaModel::GetLabel($sClass, $sAggregationAttr);
|
||||||
}
|
}
|
||||||
$iLimit = 0;
|
$iLimit = 0;
|
||||||
if (isset($aExtraParams['limit'])) {
|
if (isset($aExtraParams['limit']))
|
||||||
|
{
|
||||||
$iLimit = intval($aExtraParams['limit']);
|
$iLimit = intval($aExtraParams['limit']);
|
||||||
}
|
}
|
||||||
$aOrderBy = [];
|
$aOrderBy = array();
|
||||||
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by'])) {
|
if (isset($aExtraParams['order_direction']) && isset($aExtraParams['order_by']))
|
||||||
switch ($aExtraParams['order_by']) {
|
{
|
||||||
|
switch ($aExtraParams['order_by'])
|
||||||
|
{
|
||||||
case 'attribute':
|
case 'attribute':
|
||||||
$aOrderBy = ['grouped_by_1' => ($aExtraParams['order_direction'] === 'asc')];
|
$aOrderBy = array('grouped_by_1' => ($aExtraParams['order_direction'] === 'asc'));
|
||||||
break;
|
break;
|
||||||
case 'function':
|
case 'function':
|
||||||
$aOrderBy = [$sFctVar => ($aExtraParams['order_direction'] === 'asc')];
|
$aOrderBy = array($sFctVar => ($aExtraParams['order_direction'] === 'asc'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1037,31 +1078,31 @@ JS
|
|||||||
$this->AddCondition($sFilterCode, $sContextParamValue);
|
$this->AddCondition($sFilterCode, $sContextParamValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, [], $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary details
|
// Summary details
|
||||||
$aCounts = [];
|
$aCounts = array();
|
||||||
$aStateLabels = [];
|
$aStateLabels = array();
|
||||||
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
|
if (!empty($sStateAttrCode) && !empty($sStatesList)) {
|
||||||
$aStates = explode(',', $sStatesList);
|
$aStates = explode(',', $sStatesList);
|
||||||
|
|
||||||
// Generate one count + group by query [#1330]
|
// Generate one count + group by query [#1330]
|
||||||
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
$sClassAlias = $this->m_oFilter->GetClassAlias();
|
||||||
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
|
$oGroupByExpr = Expression::FromOQL($sClassAlias.'.'.$sStateAttrCode);
|
||||||
$aGroupBy = ['group1' => $oGroupByExpr];
|
$aGroupBy = array('group1' => $oGroupByExpr);
|
||||||
$oGroupBySearch = $this->m_oFilter->DeepClone();
|
$oGroupBySearch = $this->m_oFilter->DeepClone();
|
||||||
if (isset($this->m_bShowObsoleteData)) {
|
if (isset($this->m_bShowObsoleteData)) {
|
||||||
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$oGroupBySearch->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery($aQueryParams, $aGroupBy, false);
|
$sCountGroupByQuery = $oGroupBySearch->MakeGroupByQuery($aQueryParams, $aGroupBy, false);
|
||||||
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
|
$aCountGroupByResults = CMDBSource::QueryToArray($sCountGroupByQuery);
|
||||||
$aCountsQueryResults = [];
|
$aCountsQueryResults = array();
|
||||||
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
|
foreach ($aCountGroupByResults as $aCountGroupBySingleResult) {
|
||||||
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
|
$aCountsQueryResults[$aCountGroupBySingleResult[0]] = $aCountGroupBySingleResult[1];
|
||||||
}
|
}
|
||||||
@@ -1075,8 +1116,7 @@ JS
|
|||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
if ($aCounts[$sStateValue] == 0) {
|
if ($aCounts[$sStateValue] == 0) {
|
||||||
$aCounts[$sStateValue] = ['link' => '-', 'label' => $aCounts[$sStateValue]];
|
$aCounts[$sStateValue] = ['link' => '-', 'label' => $aCounts[$sStateValue]];;
|
||||||
;
|
|
||||||
} else {
|
} else {
|
||||||
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
|
$oSingleGroupByValueFilter = $this->m_oFilter->DeepClone();
|
||||||
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
|
$oSingleGroupByValueFilter->AddCondition($sStateAttrCode, $sStateValue, '=');
|
||||||
@@ -1084,7 +1124,7 @@ JS
|
|||||||
$oSingleGroupByValueFilter->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$oSingleGroupByValueFilter->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot()
|
$sHyperlink = utils::GetAbsoluteUrlAppRoot()
|
||||||
.'pages/UI.php?operation=search'.$oAppContext->GetForLink(true)
|
.'pages/UI.php?operation=search&'.$oAppContext->GetForLink()
|
||||||
.'&filter='.rawurlencode($oSingleGroupByValueFilter->serialize());
|
.'&filter='.rawurlencode($oSingleGroupByValueFilter->serialize());
|
||||||
$aCounts[$sStateValue] = ['link' => $sHyperlink, 'label' => $aCounts[$sStateValue]];
|
$aCounts[$sStateValue] = ['link' => $sHyperlink, 'label' => $aCounts[$sStateValue]];
|
||||||
}
|
}
|
||||||
@@ -1140,8 +1180,7 @@ JS
|
|||||||
$('#".$oBlock->GetId()."').html(data);
|
$('#".$oBlock->GetId()."').html(data);
|
||||||
$('#".$oBlock->GetId()."').unblock();
|
$('#".$oBlock->GetId()."').unblock();
|
||||||
});
|
});
|
||||||
$('#".$oBlock->GetId()."').unblock();"
|
$('#".$oBlock->GetId()."').unblock();");
|
||||||
);
|
|
||||||
|
|
||||||
return $oBlock;
|
return $oBlock;
|
||||||
}
|
}
|
||||||
@@ -1183,17 +1222,17 @@ JS
|
|||||||
$this->AddCondition($sFilterCode, $sContextParamValue);
|
$this->AddCondition($sFilterCode, $sContextParamValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, [], $aQueryParams);
|
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, array(), $aQueryParams);
|
||||||
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
$this->m_oSet->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||||
}
|
}
|
||||||
$iCount = $this->m_oSet->Count();
|
$iCount = $this->m_oSet->Count();
|
||||||
$sClassLabel = MetaModel::GetName($sClass);
|
$sClassLabel = MetaModel::GetName($sClass);
|
||||||
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
|
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
|
||||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize());
|
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize());
|
||||||
|
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
$aRefreshParams = [
|
$aRefreshParams = [
|
||||||
@@ -1202,17 +1241,10 @@ JS
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
||||||
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
|
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.'&'.$oAppContext->GetForLink();
|
||||||
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
||||||
$oBlock = DashletFactory::MakeForDashletBadge(
|
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, $sCreateActionUrl,
|
||||||
$sClassIconUrl,
|
$sCreateActionLabel, $aRefreshParams);
|
||||||
$sHyperlink,
|
|
||||||
$iCount,
|
|
||||||
$sClassLabel,
|
|
||||||
$sCreateActionUrl,
|
|
||||||
$sCreateActionLabel,
|
|
||||||
$aRefreshParams
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
|
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, null, null, $aRefreshParams);
|
||||||
}
|
}
|
||||||
@@ -1242,9 +1274,9 @@ JS
|
|||||||
|
|
||||||
$aRes = CMDBSource::QueryToArray($sSql);
|
$aRes = CMDBSource::QueryToArray($sSql);
|
||||||
|
|
||||||
$aGroupBy = [];
|
$aGroupBy = array();
|
||||||
$aLabels = [];
|
$aLabels = array();
|
||||||
$aValues = [];
|
$aValues = array();
|
||||||
$iTotalCount = 0;
|
$iTotalCount = 0;
|
||||||
foreach ($aRes as $iRow => $aRow) {
|
foreach ($aRes as $iRow => $aRow) {
|
||||||
$sValue = $aRow['grouped_by_1'];
|
$sValue = $aRow['grouped_by_1'];
|
||||||
@@ -1255,9 +1287,9 @@ JS
|
|||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$aData = [];
|
$aData = array();
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sParams = $oAppContext->GetForLink(true);
|
$sParams = $oAppContext->GetForLink();
|
||||||
foreach ($aGroupBy as $iRow => $iCount) {
|
foreach ($aGroupBy as $iRow => $iCount) {
|
||||||
// Build the search for this subset
|
// Build the search for this subset
|
||||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||||
@@ -1266,22 +1298,22 @@ JS
|
|||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
} else {
|
} else {
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
}
|
}
|
||||||
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
$sFilter = rawurlencode($oSubsetSearch->serialize(false, $aQueryParams));
|
||||||
|
|
||||||
$aData[] = [
|
$aData[] = array(
|
||||||
'group' => $aLabels[$iRow],
|
'group' => $aLabels[$iRow],
|
||||||
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>",
|
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1&$sParams&filter=$sFilter\">$iCount</a>"
|
||||||
]; // TO DO: add the context information
|
); // TO DO: add the context information
|
||||||
}
|
}
|
||||||
$aAttribs = [
|
$aAttribs = array(
|
||||||
'group' => ['label' => $sGroupByLabel, 'description' => ''],
|
'group' => array('label' => $sGroupByLabel, 'description' => ''),
|
||||||
'value' => [
|
'value' => array(
|
||||||
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
||||||
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
||||||
],
|
),
|
||||||
];
|
);
|
||||||
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
||||||
|
|
||||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||||
@@ -1379,6 +1411,7 @@ JS
|
|||||||
$oBlock->aExtraParams = $aExtraParams;
|
$oBlock->aExtraParams = $aExtraParams;
|
||||||
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
$oBlock->sFilter = $this->m_oFilter->ToOQL();
|
||||||
|
|
||||||
|
|
||||||
// Check the classes that can be read (i.e authorized) by this user...
|
// Check the classes that can be read (i.e authorized) by this user...
|
||||||
foreach ($aClasses as $sAlias => $sClassName) {
|
foreach ($aClasses as $sAlias => $sClassName) {
|
||||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
||||||
@@ -1400,7 +1433,7 @@ JS
|
|||||||
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
|
||||||
// Limit the size of the URL (N°1585 - request uri too long)
|
// Limit the size of the URL (N°1585 - request uri too long)
|
||||||
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH) {
|
||||||
$oBlock->sEventAttachedData = json_encode([
|
$oBlock->sEventAttachedData = json_encode(array(
|
||||||
'filter' => $sSearchFilter,
|
'filter' => $sSearchFilter,
|
||||||
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
|
||||||
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
||||||
@@ -1408,7 +1441,7 @@ JS
|
|||||||
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
||||||
'breadcrumb_icon' => 'fas fa-search',
|
'breadcrumb_icon' => 'fas fa-search',
|
||||||
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
'breadcrumb_icon_type' => iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES,
|
||||||
]);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1441,25 +1474,25 @@ JS
|
|||||||
$oContentBlock = new UIContentBlock();
|
$oContentBlock = new UIContentBlock();
|
||||||
$oHtml = new Html();
|
$oHtml = new Html();
|
||||||
$oContentBlock->AddSubBlock($oHtml);
|
$oContentBlock->AddSubBlock($oHtml);
|
||||||
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : [];
|
$aDisplayAliases = isset($aExtraParams['display_aliases']) ? explode(',', $aExtraParams['display_aliases']) : array();
|
||||||
if (!isset($aExtraParams['group_by'])) {
|
if (!isset($aExtraParams['group_by'])) {
|
||||||
$oHtml->AddHtml('<p>'.Dict::S('UI:Error:MandatoryTemplateParameter_group_by').'</p>');
|
$oHtml->AddHtml('<p>'.Dict::S('UI:Error:MandatoryTemplateParameter_group_by').'</p>');
|
||||||
} else {
|
} else {
|
||||||
$aGroupByFields = [];
|
$aGroupByFields = array();
|
||||||
$aGroupBy = explode(',', $aExtraParams['group_by']);
|
$aGroupBy = explode(',', $aExtraParams['group_by']);
|
||||||
foreach ($aGroupBy as $sGroupBy) {
|
foreach ($aGroupBy as $sGroupBy) {
|
||||||
$aMatches = [];
|
$aMatches = array();
|
||||||
if (preg_match('/^(.+)\.(.+)$/', $sGroupBy, $aMatches) > 0) {
|
if (preg_match('/^(.+)\.(.+)$/', $sGroupBy, $aMatches) > 0) {
|
||||||
$aGroupByFields[] = ['alias' => $aMatches[1], 'att_code' => $aMatches[2]];
|
$aGroupByFields[] = array('alias' => $aMatches[1], 'att_code' => $aMatches[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($aGroupByFields) == 0) {
|
if (count($aGroupByFields) == 0) {
|
||||||
$oHtml->AddHtml('<p>'.Dict::Format('UI:Error:InvalidGroupByFields', $aExtraParams['group_by']).'</p>');
|
$oHtml->AddHtml('<p>'.Dict::Format('UI:Error:InvalidGroupByFields', $aExtraParams['group_by']).'</p>');
|
||||||
} else {
|
} else {
|
||||||
$aResults = [];
|
$aResults = array();
|
||||||
$aCriteria = [];
|
$aCriteria = array();
|
||||||
while ($aObjects = $this->m_oSet->FetchAssoc()) {
|
while ($aObjects = $this->m_oSet->FetchAssoc()) {
|
||||||
$aKeys = [];
|
$aKeys = array();
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$sAlias = $aField['alias'];
|
$sAlias = $aField['alias'];
|
||||||
if (is_null($aObjects[$sAlias])) {
|
if (is_null($aObjects[$sAlias])) {
|
||||||
@@ -1476,7 +1509,7 @@ JS
|
|||||||
$oHtml->AddHtml("<table>\n");
|
$oHtml->AddHtml("<table>\n");
|
||||||
// Construct a new (parametric) query that will return the content of this block
|
// Construct a new (parametric) query that will return the content of this block
|
||||||
$oBlockFilter = $this->m_oFilter->DeepClone();
|
$oBlockFilter = $this->m_oFilter->DeepClone();
|
||||||
$aExpressions = [];
|
$aExpressions = array();
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$aExpressions[] = '`'.$aField['alias'].'`.`'.$aField['att_code'].'` = :param'.$index++;
|
$aExpressions[] = '`'.$aField['alias'].'`.`'.$aField['att_code'].'` = :param'.$index++;
|
||||||
@@ -1488,7 +1521,7 @@ JS
|
|||||||
foreach ($aResults as $sCategory => $aObjects) {
|
foreach ($aResults as $sCategory => $aObjects) {
|
||||||
$oHtml->AddHtml("<tr><td><h1>$sCategory</h1></td></tr>\n");
|
$oHtml->AddHtml("<tr><td><h1>$sCategory</h1></td></tr>\n");
|
||||||
if (count($aDisplayAliases) == 1) {
|
if (count($aDisplayAliases) == 1) {
|
||||||
$aSimpleArray = [];
|
$aSimpleArray = array();
|
||||||
foreach ($aObjects as $aRow) {
|
foreach ($aObjects as $aRow) {
|
||||||
$oObj = $aRow[$aDisplayAliases[0]];
|
$oObj = $aRow[$aDisplayAliases[0]];
|
||||||
if (!is_null($oObj)) {
|
if (!is_null($oObj)) {
|
||||||
@@ -1504,12 +1537,12 @@ JS
|
|||||||
$oHtml->AddHtml("</td></tr>\n");
|
$oHtml->AddHtml("</td></tr>\n");
|
||||||
} else {
|
} else {
|
||||||
$index = 0;
|
$index = 0;
|
||||||
$aArgs = [];
|
$aArgs = array();
|
||||||
foreach ($aGroupByFields as $aField) {
|
foreach ($aGroupByFields as $aField) {
|
||||||
$aArgs['param'.$index] = $aCriteria[$sCategory][$aField['alias'].'.'.$aField['att_code']];
|
$aArgs['param'.$index] = $aCriteria[$sCategory][$aField['alias'].'.'.$aField['att_code']];
|
||||||
$index++;
|
$index++;
|
||||||
}
|
}
|
||||||
$oSet = new CMDBObjectSet($oBlockFilter, [], $aArgs);
|
$oSet = new CMDBObjectSet($oBlockFilter, array(), $aArgs);
|
||||||
if (empty($aExtraParams['currentId'])) {
|
if (empty($aExtraParams['currentId'])) {
|
||||||
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
$iListId = utils::GetUniqueId(); // Works only if not in an Ajax page !!
|
||||||
} else {
|
} else {
|
||||||
@@ -1570,10 +1603,8 @@ JS
|
|||||||
$sDefaults .= '&'.urlencode($sName).'='.urlencode($sValue);
|
$sDefaults .= '&'.urlencode($sName).'='.urlencode($sValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oBlock->AddHtml("<p><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=modify_links&class=$sClass&sParams&link_attr=".$aExtraParams['link_attr']."&id=".$aExtraParams['object_id']."&target_class=$sTargetClass&addObjects=true$sDefaults\">".Dict::Format(
|
$oBlock->AddHtml("<p><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=modify_links&class=$sClass&sParams&link_attr=".$aExtraParams['link_attr']."&id=".$aExtraParams['object_id']."&target_class=$sTargetClass&addObjects=true$sDefaults\">".Dict::Format('UI:ClickToCreateNew',
|
||||||
'UI:ClickToCreateNew',
|
Metamodel::GetName($sClass))."</a></p>\n");
|
||||||
Metamodel::GetName($sClass)
|
|
||||||
)."</a></p>\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1605,7 +1636,7 @@ JS
|
|||||||
$sGroupByExpr = isset($aExtraParams['group_by_expr']) ? '¶ms[group_by_expr]='.$aExtraParams['group_by_expr'] : '';
|
$sGroupByExpr = isset($aExtraParams['group_by_expr']) ? '¶ms[group_by_expr]='.$aExtraParams['group_by_expr'] : '';
|
||||||
$sFilter = $this->m_oFilter->serialize(false, $aQueryParams);
|
$sFilter = $this->m_oFilter->serialize(false, $aQueryParams);
|
||||||
$oContext = new ApplicationContext();
|
$oContext = new ApplicationContext();
|
||||||
$sContextParam = $oContext->GetForLink(true);
|
$sContextParam = $oContext->GetForLink();
|
||||||
$sAggregationFunction = isset($aExtraParams['aggregation_function']) ? $aExtraParams['aggregation_function'] : '';
|
$sAggregationFunction = isset($aExtraParams['aggregation_function']) ? $aExtraParams['aggregation_function'] : '';
|
||||||
$sAggregationAttr = isset($aExtraParams['aggregation_attribute']) ? $aExtraParams['aggregation_attribute'] : '';
|
$sAggregationAttr = isset($aExtraParams['aggregation_attribute']) ? $aExtraParams['aggregation_attribute'] : '';
|
||||||
$sLimit = isset($aExtraParams['limit']) ? $aExtraParams['limit'] : '';
|
$sLimit = isset($aExtraParams['limit']) ? $aExtraParams['limit'] : '';
|
||||||
@@ -1613,7 +1644,7 @@ JS
|
|||||||
$sOrderDirection = isset($aExtraParams['order_direction']) ? $aExtraParams['order_direction'] : '';
|
$sOrderDirection = isset($aExtraParams['order_direction']) ? $aExtraParams['order_direction'] : '';
|
||||||
|
|
||||||
if (isset($aExtraParams['group_by_label'])) {
|
if (isset($aExtraParams['group_by_label'])) {
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).$sContextParam;
|
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
|
||||||
} else {
|
} else {
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
|
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
|
||||||
}
|
}
|
||||||
@@ -1646,42 +1677,42 @@ JS
|
|||||||
{
|
{
|
||||||
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
$sChartType = isset($aExtraParams['chart_type']) ? $aExtraParams['chart_type'] : 'pie';
|
||||||
$sId = utils::ReadParam('id', '');
|
$sId = utils::ReadParam('id', '');
|
||||||
$aValues = [];
|
$aValues = array();
|
||||||
$oBlock = null;
|
$oBlock = null;
|
||||||
$sJSURLs = '';
|
$sJSURLs = '';
|
||||||
|
|
||||||
$oContext = new ApplicationContext();
|
|
||||||
$sContextParam = $oContext->GetForLink(true);
|
|
||||||
|
|
||||||
if (isset($aExtraParams['group_by'])) {
|
if (isset($aExtraParams['group_by'])) {
|
||||||
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
||||||
$aRes = CMDBSource::QueryToArray($sSql);
|
$aRes = CMDBSource::QueryToArray($sSql);
|
||||||
|
$oContext = new ApplicationContext();
|
||||||
|
$sContextParam = $oContext->GetForLink();
|
||||||
|
|
||||||
$iTotalCount = 0;
|
$iTotalCount = 0;
|
||||||
$aURLs = [];
|
$aURLs = array();
|
||||||
|
|
||||||
foreach ($aRes as $iRow => $aRow) {
|
foreach ($aRes as $iRow => $aRow) {
|
||||||
$sValue = $aRow['grouped_by_1'];
|
$sValue = $aRow['grouped_by_1'];
|
||||||
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
$sHtmlValue = $oGroupByExp->MakeValueLabel($this->m_oFilter, $sValue, $sValue);
|
||||||
$iTotalCount += $aRow['_itop_count_'];
|
$iTotalCount += $aRow['_itop_count_'];
|
||||||
$aValues[] = [
|
$aValues[] = array(
|
||||||
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
'label' => html_entity_decode(strip_tags($sHtmlValue), ENT_QUOTES, 'UTF-8'),
|
||||||
'label_html' => $sHtmlValue,
|
'label_html' => $sHtmlValue,
|
||||||
'value' => (float)$aRow[$sFctVar],
|
'value' => (float)$aRow[$sFctVar],
|
||||||
];
|
);
|
||||||
|
|
||||||
|
|
||||||
// Build the search for this subset
|
// Build the search for this subset
|
||||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||||
$oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($sValue));
|
$oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($sValue));
|
||||||
$oSubsetSearch->AddConditionExpression($oCondition);
|
$oSubsetSearch->AddConditionExpression($oCondition);
|
||||||
$aURLs[] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".rawurlencode($oSubsetSearch->serialize()).$sContextParam;
|
$aURLs[] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".rawurlencode($oSubsetSearch->serialize()).'&'.$sContextParam;
|
||||||
}
|
}
|
||||||
$sJSURLs = json_encode($aURLs);
|
$sJSURLs = json_encode($aURLs);
|
||||||
}
|
}
|
||||||
if (isset($aExtraParams['group_by_label'])) {
|
if (isset($aExtraParams['group_by_label'])) {
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).$sContextParam;
|
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).'&'.$sContextParam;
|
||||||
} else {
|
} else {
|
||||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).$sContextParam;
|
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).'&'.$sContextParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($sChartType) {
|
switch ($sChartType) {
|
||||||
@@ -1707,7 +1738,7 @@ JS
|
|||||||
$aColumns = [];
|
$aColumns = [];
|
||||||
$aNames = [];
|
$aNames = [];
|
||||||
foreach ($aValues as $idx => $aValue) {
|
foreach ($aValues as $idx => $aValue) {
|
||||||
$aColumns[] = ['series_'.$idx, (float)$aValue['value']];
|
$aColumns[] = array('series_'.$idx, (float)$aValue['value']);
|
||||||
$aNames['series_'.$idx] = $aValue['label'];
|
$aNames['series_'.$idx] = $aValue['label'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1754,14 +1785,14 @@ JS
|
|||||||
|
|
||||||
$oBlock->sCsvFile = strtolower($this->m_oFilter->GetClass()).'.csv';
|
$oBlock->sCsvFile = strtolower($this->m_oFilter->GetClass()).'.csv';
|
||||||
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
||||||
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
||||||
// Pass the parameters via POST, since expression may be very long
|
// Pass the parameters via POST, since expression may be very long
|
||||||
$aParamsToPost = [
|
$aParamsToPost = array(
|
||||||
'expression' => $this->m_oFilter->ToOQL(true),
|
'expression' => $this->m_oFilter->ToOQL(true),
|
||||||
'format' => 'csv',
|
'format' => 'csv',
|
||||||
'filename' => $oBlock->sCsvFile,
|
'filename' => $oBlock->sCsvFile,
|
||||||
'charset' => 'UTF-8',
|
'charset' => 'UTF-8',
|
||||||
];
|
);
|
||||||
if ($oBlock->bAdvancedMode) {
|
if ($oBlock->bAdvancedMode) {
|
||||||
$oBlock->sDownloadLink .= '&fields_advanced=1';
|
$oBlock->sDownloadLink .= '&fields_advanced=1';
|
||||||
$aParamsToPost['fields_advanced'] = 1;
|
$aParamsToPost['fields_advanced'] = 1;
|
||||||
@@ -1820,7 +1851,8 @@ class MenuBlock extends DisplayBlock
|
|||||||
$oRouter = Router::GetInstance();
|
$oRouter = Router::GetInstance();
|
||||||
$oRenderBlock = new UIContentBlock();
|
$oRenderBlock = new UIContentBlock();
|
||||||
|
|
||||||
if ($this->m_sStyle == 'popup') { // popup is a synonym of 'list' for backward compatibility
|
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
||||||
|
{
|
||||||
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
$this->m_sStyle = static::ENUM_STYLE_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1853,7 +1885,11 @@ class MenuBlock extends DisplayBlock
|
|||||||
&& (!isset($aExtraParams['menu']) || $aExtraParams['menu'] === "1" || $aExtraParams['menu'] === true)
|
&& (!isset($aExtraParams['menu']) || $aExtraParams['menu'] === "1" || $aExtraParams['menu'] === true)
|
||||||
) {
|
) {
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink(true);
|
$sContext = $oAppContext->GetForLink();
|
||||||
|
if (utils::IsNotNullOrEmptyString($sContext)) {
|
||||||
|
$sContext = '&'.$sContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$sFilter = $this->GetFilter()->serialize();
|
$sFilter = $this->GetFilter()->serialize();
|
||||||
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
|
||||||
@@ -1932,8 +1968,8 @@ class MenuBlock extends DisplayBlock
|
|||||||
// Life cycle actions may be available... if all objects are in the same state
|
// Life cycle actions may be available... if all objects are in the same state
|
||||||
// Group by <state>
|
// Group by <state>
|
||||||
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
$oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
|
||||||
$aGroupBy = ['__state__' => $oGroupByExp];
|
$aGroupBy = array('__state__' => $oGroupByExp);
|
||||||
$aQueryParams = [];
|
$aQueryParams = array();
|
||||||
if (isset($aExtraParams['query_params'])) {
|
if (isset($aExtraParams['query_params'])) {
|
||||||
$aQueryParams = $aExtraParams['query_params'];
|
$aQueryParams = $aExtraParams['query_params'];
|
||||||
}
|
}
|
||||||
@@ -1965,10 +2001,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
switch ($iActionAllowed) {
|
switch ($iActionAllowed) {
|
||||||
case UR_ALLOWED_YES:
|
case UR_ALLOWED_YES:
|
||||||
case UR_ALLOWED_DEPENDS:
|
case UR_ALLOWED_DEPENDS:
|
||||||
$aTransitionActions[$sStimulusCode] = [
|
$aTransitionActions[$sStimulusCode] = array(
|
||||||
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
'label' => $aStimuli[$sStimulusCode]->GetLabel(),
|
||||||
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
'url' => "{$sRootUrl}pages/UI.php?stimulus=$sStimulusCode&class=$sLifecycleClass&{$sUrlQueryString}",
|
||||||
] + $aActionParams;
|
) + $aActionParams;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1988,8 +2024,8 @@ class MenuBlock extends DisplayBlock
|
|||||||
$sSelectedClassName = MetaModel::GetName($sSelectedClass);
|
$sSelectedClassName = MetaModel::GetName($sSelectedClass);
|
||||||
|
|
||||||
// Check rights on class
|
// Check rights on class
|
||||||
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||||
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE);
|
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE, $sSelectedClass);
|
||||||
|
|
||||||
// Refine filter on selected class so bullk actions occur on the right class
|
// Refine filter on selected class so bullk actions occur on the right class
|
||||||
$oSelectedClassFilter = $this->GetFilter()->DeepClone();
|
$oSelectedClassFilter = $this->GetFilter()->DeepClone();
|
||||||
@@ -2030,16 +2066,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
// Just one object in the set, possible actions are "new / clone / modify and delete"
|
||||||
if (!isset($aExtraParams['link_attr'])) {
|
if (!isset($aExtraParams['link_attr'])) {
|
||||||
if ($bIsModifyAllowed) {
|
if ($bIsModifyAllowed) {
|
||||||
$aRegularActions['UI:Menu:Modify'] = [
|
$aRegularActions['UI:Menu:Modify'] = array(
|
||||||
'label' => Dict::S('UI:Menu:Modify'),
|
'label' => Dict::S('UI:Menu:Modify'),
|
||||||
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id]) . "{$sContext}#",
|
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id]) . "{$sContext}#",
|
||||||
] + $aActionParams;
|
) + $aActionParams;
|
||||||
}
|
}
|
||||||
if ($bIsDeleteAllowed) {
|
if ($bIsDeleteAllowed) {
|
||||||
$aRegularActions['UI:Menu:Delete'] = [
|
$aRegularActions['UI:Menu:Delete'] = array(
|
||||||
'label' => Dict::S('UI:Menu:Delete'),
|
'label' => Dict::S('UI:Menu:Delete'),
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}",
|
||||||
] + $aActionParams;
|
) + $aActionParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relations...
|
// Relations...
|
||||||
@@ -2048,16 +2084,16 @@ class MenuBlock extends DisplayBlock
|
|||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
foreach ($aRelations as $sRelationCode => $aRelationInfo) {
|
foreach ($aRelations as $sRelationCode => $aRelationInfo) {
|
||||||
if (array_key_exists('down', $aRelationInfo)) {
|
if (array_key_exists('down', $aRelationInfo)) {
|
||||||
$aRegularActions[$sRelationCode.'_down'] = [
|
$aRegularActions[$sRelationCode.'_down'] = array(
|
||||||
'label' => $aRelationInfo['down'],
|
'label' => $aRelationInfo['down'],
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}",
|
||||||
] + $aActionParams;
|
) + $aActionParams;
|
||||||
}
|
}
|
||||||
if (array_key_exists('up', $aRelationInfo)) {
|
if (array_key_exists('up', $aRelationInfo)) {
|
||||||
$aRegularActions[$sRelationCode.'_up'] = [
|
$aRegularActions[$sRelationCode.'_up'] = array(
|
||||||
'label' => $aRelationInfo['up'],
|
'label' => $aRelationInfo['up'],
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}",
|
||||||
] + $aActionParams;
|
) + $aActionParams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2069,7 +2105,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$bCanKill = false;
|
$bCanKill = false;
|
||||||
|
|
||||||
$oUser = UserRights::GetUserObject();
|
$oUser = UserRights::GetUserObject();
|
||||||
$aUserProfiles = [];
|
$aUserProfiles = array();
|
||||||
if (!is_null($oUser)) {
|
if (!is_null($oUser)) {
|
||||||
$oProfileSet = $oUser->Get('profile_list');
|
$oProfileSet = $oUser->Get('profile_list');
|
||||||
while ($oProfile = $oProfileSet->Fetch()) {
|
while ($oProfile = $oProfileSet->Fetch()) {
|
||||||
@@ -2091,10 +2127,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
|
|
||||||
if ($bCanKill) {
|
if ($bCanKill) {
|
||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
$aRegularActions['concurrent_lock_unlock'] = [
|
$aRegularActions['concurrent_lock_unlock'] = array(
|
||||||
'label' => Dict::S('UI:Menu:KillConcurrentLock'),
|
'label' => Dict::S('UI:Menu:KillConcurrentLock'),
|
||||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}",
|
'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}",
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2102,7 +2138,7 @@ class MenuBlock extends DisplayBlock
|
|||||||
$this->AddMenuSeparator($aRegularActions);
|
$this->AddMenuSeparator($aRegularActions);
|
||||||
|
|
||||||
$this->GetEnumAllowedActions($oSet, function ($sLabel, $data) use (&$aRegularActions, $aActionParams) {
|
$this->GetEnumAllowedActions($oSet, function ($sLabel, $data) use (&$aRegularActions, $aActionParams) {
|
||||||
$aRegularActions[$sLabel] = ['label' => $sLabel, 'url' => $data] + $aActionParams;
|
$aRegularActions[$sLabel] = array('label' => $sLabel, 'url' => $data) + $aActionParams;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2438,11 +2474,13 @@ class MenuBlock extends DisplayBlock
|
|||||||
protected function AddMenuSeparator(&$aActions)
|
protected function AddMenuSeparator(&$aActions)
|
||||||
{
|
{
|
||||||
$sSeparator = '<hr class="menu-separator"/>';
|
$sSeparator = '<hr class="menu-separator"/>';
|
||||||
if (count($aActions) > 0) { // Make sure that the separator is not the first item in the menu
|
if (count($aActions) > 0) // Make sure that the separator is not the first item in the menu
|
||||||
|
{
|
||||||
$aKeys = array_keys($aActions);
|
$aKeys = array_keys($aActions);
|
||||||
$sLastKey = array_pop($aKeys);
|
$sLastKey = array_pop($aKeys);
|
||||||
if ($aActions[$sLastKey]['label'] != $sSeparator) { // Make sure there are no 2 consecutive separators
|
if ($aActions[$sLastKey]['label'] != $sSeparator) // Make sure there are no 2 consecutive separators
|
||||||
$aActions['sep_'.(count($aActions) - 1)] = ['label' => $sSeparator, 'url' => ''];
|
{
|
||||||
|
$aActions['sep_'.(count($aActions)-1)] = array('label' => $sSeparator, 'url' => '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2502,10 +2540,10 @@ class MenuBlock extends DisplayBlock
|
|||||||
*/
|
*/
|
||||||
protected function AddBulkDeleteObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:BulkDelete', $sActionLabel = 'UI:Menu:BulkDelete')
|
protected function AddBulkDeleteObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:BulkDelete', $sActionLabel = 'UI:Menu:BulkDelete')
|
||||||
{
|
{
|
||||||
$aActions[$sActionIdentifier] = [
|
$aActions[$sActionIdentifier] = array(
|
||||||
'label' => Dict::S($sActionLabel),
|
'label' => Dict::S($sActionLabel),
|
||||||
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_deletion&filter=".urlencode($sFilter)),
|
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_deletion&filter=".urlencode($sFilter)),
|
||||||
] + $this->GetDefaultParamsForMenuAction();
|
) + $this->GetDefaultParamsForMenuAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2540,8 +2578,11 @@ class MenuBlock extends DisplayBlock
|
|||||||
$sUrl = "{$sRootUrl}pages/{$sUIPage}?{$sUrlParams}";
|
$sUrl = "{$sRootUrl}pages/{$sUIPage}?{$sUrlParams}";
|
||||||
|
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$sContext = $oAppContext->GetForLink(true);
|
$sContext = $oAppContext->GetForLink();
|
||||||
|
if (utils::IsNotNullOrEmptyString($sContext)) {
|
||||||
|
$sUrl .= '&'.$sContext;
|
||||||
|
}
|
||||||
|
|
||||||
return $sUrl.$sContext;
|
return $sUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -22,28 +22,31 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function __construct($sToken = null)
|
public function __construct($sToken = null)
|
||||||
{
|
{
|
||||||
$this->aStatistics = [
|
$this->aStatistics = array(
|
||||||
'objects_count' => 0,
|
'objects_count' => 0,
|
||||||
'total_duration' => 0,
|
'total_duration' => 0,
|
||||||
'data_retrieval_duration' => 0,
|
'data_retrieval_duration' => 0,
|
||||||
'excel_build_duration' => 0,
|
'excel_build_duration' => 0,
|
||||||
'excel_write_duration' => 0,
|
'excel_write_duration' => 0,
|
||||||
'peak_memory_usage' => 0,
|
'peak_memory_usage' => 0,
|
||||||
];
|
);
|
||||||
$this->fStartTime = microtime(true);
|
$this->fStartTime = microtime(true);
|
||||||
$this->oSearch = null;
|
$this->oSearch = null;
|
||||||
|
|
||||||
$this->sState = 'new';
|
$this->sState = 'new';
|
||||||
$this->aObjectsIDs = [];
|
$this->aObjectsIDs = array();
|
||||||
$this->iPosition = 0;
|
$this->iPosition = 0;
|
||||||
$this->aAuthorizedClasses = null;
|
$this->aAuthorizedClasses = null;
|
||||||
$this->aTableHeaders = null;
|
$this->aTableHeaders = null;
|
||||||
$this->sOutputFilePath = null;
|
$this->sOutputFilePath = null;
|
||||||
$this->bAdvancedMode = false;
|
$this->bAdvancedMode = false;
|
||||||
$this->CheckDataDir();
|
$this->CheckDataDir();
|
||||||
if ($sToken == null) {
|
if ($sToken == null)
|
||||||
|
{
|
||||||
$this->sToken = $this->GetNewToken();
|
$this->sToken = $this->GetNewToken();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$this->sToken = $sToken;
|
$this->sToken = $sToken;
|
||||||
$this->ReloadState();
|
$this->ReloadState();
|
||||||
}
|
}
|
||||||
@@ -51,10 +54,13 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function __destruct()
|
public function __destruct()
|
||||||
{
|
{
|
||||||
if (($this->sState != 'done') && ($this->sState != 'error') && ($this->sToken != null)) {
|
if (($this->sState != 'done') && ($this->sState != 'error') && ($this->sToken != null))
|
||||||
|
{
|
||||||
// Operation in progress, save the state
|
// Operation in progress, save the state
|
||||||
$this->SaveState();
|
$this->SaveState();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Operation completed, cleanup the temp files
|
// Operation completed, cleanup the temp files
|
||||||
@unlink($this->GetStateFile());
|
@unlink($this->GetStateFile());
|
||||||
@unlink($this->GetDataFile());
|
@unlink($this->GetDataFile());
|
||||||
@@ -79,7 +85,7 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function SaveState()
|
public function SaveState()
|
||||||
{
|
{
|
||||||
$aState = [
|
$aState = array(
|
||||||
'state' => $this->sState,
|
'state' => $this->sState,
|
||||||
'statistics' => $this->aStatistics,
|
'statistics' => $this->aStatistics,
|
||||||
'filter' => $this->oSearch->serialize(),
|
'filter' => $this->oSearch->serialize(),
|
||||||
@@ -88,7 +94,7 @@ class ExcelExporter
|
|||||||
'object_ids' => $this->aObjectsIDs,
|
'object_ids' => $this->aObjectsIDs,
|
||||||
'output_file_path' => $this->sOutputFilePath,
|
'output_file_path' => $this->sOutputFilePath,
|
||||||
'advanced_mode' => $this->bAdvancedMode,
|
'advanced_mode' => $this->bAdvancedMode,
|
||||||
];
|
);
|
||||||
|
|
||||||
file_put_contents($this->GetStateFile(), json_encode($aState));
|
file_put_contents($this->GetStateFile(), json_encode($aState));
|
||||||
|
|
||||||
@@ -97,16 +103,19 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function ReloadState()
|
public function ReloadState()
|
||||||
{
|
{
|
||||||
if ($this->sToken == null) {
|
if ($this->sToken == null)
|
||||||
|
{
|
||||||
throw new Exception('ExcelExporter not initialized with a token, cannot reload state');
|
throw new Exception('ExcelExporter not initialized with a token, cannot reload state');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($this->GetStateFile())) {
|
if (!file_exists($this->GetStateFile()))
|
||||||
|
{
|
||||||
throw new Exception("ExcelExporter: missing status file '".$this->GetStateFile()."', cannot reload state.");
|
throw new Exception("ExcelExporter: missing status file '".$this->GetStateFile()."', cannot reload state.");
|
||||||
}
|
}
|
||||||
$sJson = file_get_contents($this->GetStateFile());
|
$sJson = file_get_contents($this->GetStateFile());
|
||||||
$aState = json_decode($sJson, true);
|
$aState = json_decode($sJson, true);
|
||||||
if ($aState === null) {
|
if ($aState === null)
|
||||||
|
{
|
||||||
throw new Exception("ExcelExporter:corrupted status file '".$this->GetStateFile()."', not a JSON, cannot reload state.");
|
throw new Exception("ExcelExporter:corrupted status file '".$this->GetStateFile()."', not a JSON, cannot reload state.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,13 +141,16 @@ class ExcelExporter
|
|||||||
$sMessage = Dict::Format('ExcelExporter:ErrorUnexpected_State', $this->sState);
|
$sMessage = Dict::Format('ExcelExporter:ErrorUnexpected_State', $this->sState);
|
||||||
$fTime = microtime(true);
|
$fTime = microtime(true);
|
||||||
|
|
||||||
try {
|
try
|
||||||
switch ($this->sState) {
|
{
|
||||||
|
switch($this->sState)
|
||||||
|
{
|
||||||
case 'new':
|
case 'new':
|
||||||
$oIDSet = new DBObjectSet($this->oSearch);
|
$oIDSet = new DBObjectSet($this->oSearch);
|
||||||
$oIDSet->OptimizeColumnLoad(['id']);
|
$oIDSet->OptimizeColumnLoad(array('id'));
|
||||||
$this->aObjectsIDs = [];
|
$this->aObjectsIDs = array();
|
||||||
while ($oObj = $oIDSet->Fetch()) {
|
while($oObj = $oIDSet->Fetch())
|
||||||
|
{
|
||||||
$this->aObjectsIDs[] = $oObj->GetKey();
|
$this->aObjectsIDs[] = $oObj->GetKey();
|
||||||
}
|
}
|
||||||
$sCode = 'retrieving-data';
|
$sCode = 'retrieving-data';
|
||||||
@@ -152,7 +164,8 @@ class ExcelExporter
|
|||||||
$this->GetFieldsList($oIDSet, $this->bAdvancedMode);
|
$this->GetFieldsList($oIDSet, $this->bAdvancedMode);
|
||||||
$sRow = json_encode($this->aTableHeaders);
|
$sRow = json_encode($this->aTableHeaders);
|
||||||
$hFile = @fopen($this->GetDataFile(), 'ab');
|
$hFile = @fopen($this->GetDataFile(), 'ab');
|
||||||
if ($hFile === false) {
|
if ($hFile === false)
|
||||||
|
{
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
||||||
}
|
}
|
||||||
fwrite($hFile, $sRow."\n");
|
fwrite($hFile, $sRow."\n");
|
||||||
@@ -168,24 +181,32 @@ class ExcelExporter
|
|||||||
|
|
||||||
$oCurrentSearch->AddCondition('id', $aIDs, 'IN');
|
$oCurrentSearch->AddCondition('id', $aIDs, 'IN');
|
||||||
$hFile = @fopen($this->GetDataFile(), 'ab');
|
$hFile = @fopen($this->GetDataFile(), 'ab');
|
||||||
if ($hFile === false) {
|
if ($hFile === false)
|
||||||
|
{
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for writing.');
|
||||||
}
|
}
|
||||||
$oSet = new DBObjectSet($oCurrentSearch);
|
$oSet = new DBObjectSet($oCurrentSearch);
|
||||||
$this->GetFieldsList($oSet, $this->bAdvancedMode);
|
$this->GetFieldsList($oSet, $this->bAdvancedMode);
|
||||||
while ($aObjects = $oSet->FetchAssoc()) {
|
while($aObjects = $oSet->FetchAssoc())
|
||||||
$aRow = [];
|
{
|
||||||
foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) {
|
$aRow = array();
|
||||||
|
foreach($this->aAuthorizedClasses as $sAlias => $sClassName)
|
||||||
|
{
|
||||||
$oObj = $aObjects[$sAlias];
|
$oObj = $aObjects[$sAlias];
|
||||||
if ($this->bAdvancedMode) {
|
if ($this->bAdvancedMode)
|
||||||
|
{
|
||||||
$aRow[] = $oObj->GetKey();
|
$aRow[] = $oObj->GetKey();
|
||||||
}
|
}
|
||||||
foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
foreach($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef)
|
||||||
|
{
|
||||||
$value = $oObj->Get($sAttCodeEx);
|
$value = $oObj->Get($sAttCodeEx);
|
||||||
if ($value instanceof ormCaseLog) {
|
if ($value instanceOf ormCaseLog)
|
||||||
|
{
|
||||||
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
|
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
|
||||||
$sExcelVal = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $value->GetText()));
|
$sExcelVal = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $value->GetText()));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sExcelVal = $oAttDef->GetEditValue($value, $oObj);
|
$sExcelVal = $oAttDef->GetEditValue($value, $oObj);
|
||||||
}
|
}
|
||||||
$aRow[] = $sExcelVal;
|
$aRow[] = $sExcelVal;
|
||||||
@@ -196,13 +217,16 @@ class ExcelExporter
|
|||||||
}
|
}
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
|
|
||||||
if (($this->iPosition + $this->iChunkSize) > count($this->aObjectsIDs)) {
|
if (($this->iPosition + $this->iChunkSize) > count($this->aObjectsIDs))
|
||||||
|
{
|
||||||
// Next state
|
// Next state
|
||||||
$this->sState = 'building-excel';
|
$this->sState = 'building-excel';
|
||||||
$sCode = 'building-excel';
|
$sCode = 'building-excel';
|
||||||
$iPercentage = 80;
|
$iPercentage = 80;
|
||||||
$sMessage = Dict::S('ExcelExporter:BuildingExcelFile');
|
$sMessage = Dict::S('ExcelExporter:BuildingExcelFile');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sCode = 'retrieving-data';
|
$sCode = 'retrieving-data';
|
||||||
$this->iPosition += $this->iChunkSize;
|
$this->iPosition += $this->iChunkSize;
|
||||||
$iPercentage = 5 + round(75 * ($this->iPosition / count($this->aObjectsIDs)));
|
$iPercentage = 5 + round(75 * ($this->iPosition / count($this->aObjectsIDs)));
|
||||||
@@ -212,14 +236,16 @@ class ExcelExporter
|
|||||||
|
|
||||||
case 'building-excel':
|
case 'building-excel':
|
||||||
$hFile = @fopen($this->GetDataFile(), 'rb');
|
$hFile = @fopen($this->GetDataFile(), 'rb');
|
||||||
if ($hFile === false) {
|
if ($hFile === false)
|
||||||
|
{
|
||||||
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for reading.');
|
throw new Exception('ExcelExporter: Failed to open temporary data file: "'.$this->GetDataFile().'" for reading.');
|
||||||
}
|
}
|
||||||
$sHeaders = fgets($hFile);
|
$sHeaders = fgets($hFile);
|
||||||
$aHeaders = json_decode($sHeaders, true);
|
$aHeaders = json_decode($sHeaders, true);
|
||||||
|
|
||||||
$aData = [];
|
$aData = array();
|
||||||
while ($sLine = fgets($hFile)) {
|
while($sLine = fgets($hFile))
|
||||||
|
{
|
||||||
$aRow = json_decode($sLine);
|
$aRow = json_decode($sLine);
|
||||||
$aData[] = $aRow;
|
$aData[] = $aRow;
|
||||||
}
|
}
|
||||||
@@ -252,29 +278,35 @@ class ExcelExporter
|
|||||||
$sMessage = Dict::S('ExcelExporter:Done');
|
$sMessage = Dict::S('ExcelExporter:Done');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
$sCode = 'error';
|
$sCode = 'error';
|
||||||
$sMessage = $e->getMessage();
|
$sMessage = $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->aStatistics['total_duration'] += microtime(true) - $fTime;
|
$this->aStatistics['total_duration'] += microtime(true) - $fTime;
|
||||||
$peak_memory = memory_get_peak_usage(true);
|
$peak_memory = memory_get_peak_usage(true);
|
||||||
if ($peak_memory > $this->aStatistics['peak_memory_usage']) {
|
if ($peak_memory > $this->aStatistics['peak_memory_usage'])
|
||||||
|
{
|
||||||
$this->aStatistics['peak_memory_usage'] = $peak_memory;
|
$this->aStatistics['peak_memory_usage'] = $peak_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return array(
|
||||||
'code' => $sCode,
|
'code' => $sCode,
|
||||||
'message' => $sMessage,
|
'message' => $sMessage,
|
||||||
'percentage' => $iPercentage,
|
'percentage' => $iPercentage,
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetExcelFilePath()
|
public function GetExcelFilePath()
|
||||||
{
|
{
|
||||||
if ($this->sOutputFilePath == null) {
|
if ($this->sOutputFilePath == null)
|
||||||
|
{
|
||||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx';
|
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return $this->sOutputFilePath;
|
return $this->sOutputFilePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,11 +337,14 @@ class ExcelExporter
|
|||||||
$aFiles = glob(APPROOT.'data/bulk_export/*.*');
|
$aFiles = glob(APPROOT.'data/bulk_export/*.*');
|
||||||
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
||||||
|
|
||||||
if ($iDelay > 0) {
|
if($iDelay > 0)
|
||||||
foreach ($aFiles as $sFile) {
|
{
|
||||||
|
foreach($aFiles as $sFile)
|
||||||
|
{
|
||||||
$iModificationTime = filemtime($sFile);
|
$iModificationTime = filemtime($sFile);
|
||||||
|
|
||||||
if ($iModificationTime < (time() - $iDelay)) {
|
if($iModificationTime < (time() - $iDelay))
|
||||||
|
{
|
||||||
// Temporary files older than one day are deleted
|
// Temporary files older than one day are deleted
|
||||||
//echo "Supposed to delete: '".$sFile." (Unix Modification Time: $iModificationTime)'\n";
|
//echo "Supposed to delete: '".$sFile." (Unix Modification Time: $iModificationTime)'\n";
|
||||||
@unlink($sFile);
|
@unlink($sFile);
|
||||||
@@ -320,18 +355,21 @@ class ExcelExporter
|
|||||||
|
|
||||||
public function DisplayStatistics(Page $oPage)
|
public function DisplayStatistics(Page $oPage)
|
||||||
{
|
{
|
||||||
$aStats = [
|
$aStats = array(
|
||||||
'Number of objects exported' => $this->aStatistics['objects_count'],
|
'Number of objects exported' => $this->aStatistics['objects_count'],
|
||||||
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
||||||
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
||||||
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
||||||
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
||||||
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
||||||
];
|
);
|
||||||
|
|
||||||
if ($oPage instanceof CLIPage) {
|
if ($oPage instanceof CLIPage)
|
||||||
|
{
|
||||||
$oPage->add($this->GetStatistics('text'));
|
$oPage->add($this->GetStatistics('text'));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$oPage->add($this->GetStatistics('html'));
|
$oPage->add($this->GetStatistics('html'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,24 +377,29 @@ class ExcelExporter
|
|||||||
public function GetStatistics($sFormat = 'html')
|
public function GetStatistics($sFormat = 'html')
|
||||||
{
|
{
|
||||||
$sStats = '';
|
$sStats = '';
|
||||||
$aStats = [
|
$aStats = array(
|
||||||
'Number of objects exported' => $this->aStatistics['objects_count'],
|
'Number of objects exported' => $this->aStatistics['objects_count'],
|
||||||
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
'Total export duration' => sprintf('%.3f s', $this->aStatistics['total_duration']),
|
||||||
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
'Data retrieval duration' => sprintf('%.3f s', $this->aStatistics['data_retrieval_duration']),
|
||||||
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
'Excel build duration' => sprintf('%.3f s', $this->aStatistics['excel_build_duration']),
|
||||||
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
'Excel write duration' => sprintf('%.3f s', $this->aStatistics['excel_write_duration']),
|
||||||
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
'Peak memory usage' => self::HumanDisplay($this->aStatistics['peak_memory_usage']),
|
||||||
];
|
);
|
||||||
|
|
||||||
if ($sFormat == 'text') {
|
if ($sFormat == 'text')
|
||||||
foreach ($aStats as $sLabel => $sValue) {
|
{
|
||||||
|
foreach($aStats as $sLabel => $sValue)
|
||||||
|
{
|
||||||
$sStats .= "+------------------------------+----------+\n";
|
$sStats .= "+------------------------------+----------+\n";
|
||||||
$sStats .= sprintf("|%-30s|%10s|\n", $sLabel, $sValue);
|
$sStats .= sprintf("|%-30s|%10s|\n", $sLabel, $sValue);
|
||||||
}
|
}
|
||||||
$sStats .= "+------------------------------+----------+";
|
$sStats .= "+------------------------------+----------+";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$sStats .= '<table><tbody>';
|
$sStats .= '<table><tbody>';
|
||||||
foreach ($aStats as $sLabel => $sValue) {
|
foreach($aStats as $sLabel => $sValue)
|
||||||
|
{
|
||||||
$sStats .= "<tr><td>$sLabel</td><td>$sValue</td></tr>";
|
$sStats .= "<tr><td>$sLabel</td><td>$sValue</td></tr>";
|
||||||
}
|
}
|
||||||
$sStats .= '</tbody></table>';
|
$sStats .= '</tbody></table>';
|
||||||
@@ -367,24 +410,27 @@ class ExcelExporter
|
|||||||
|
|
||||||
public static function HumanDisplay($iSize)
|
public static function HumanDisplay($iSize)
|
||||||
{
|
{
|
||||||
$aUnits = ['B','KB','MB','GB','TB','PB'];
|
$aUnits = array('B','KB','MB','GB','TB','PB');
|
||||||
return @round($iSize/pow(1024,($i=floor(log($iSize,1024)))),2).' '.$aUnits[$i];
|
return @round($iSize/pow(1024,($i=floor(log($iSize,1024)))),2).' '.$aUnits[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function CheckDataDir()
|
protected function CheckDataDir()
|
||||||
{
|
{
|
||||||
if (!is_dir(APPROOT."data/bulk_export")) {
|
if(!is_dir(APPROOT."data/bulk_export"))
|
||||||
|
{
|
||||||
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
}
|
}
|
||||||
if (!is_writable(APPROOT."data/bulk_export")) {
|
if (!is_writable(APPROOT."data/bulk_export"))
|
||||||
|
{
|
||||||
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetStateFile($sToken = null)
|
protected function GetStateFile($sToken = null)
|
||||||
{
|
{
|
||||||
if ($sToken == null) {
|
if ($sToken == null)
|
||||||
|
{
|
||||||
$sToken = $this->sToken;
|
$sToken = $this->sToken;
|
||||||
}
|
}
|
||||||
return APPROOT."data/bulk_export/$sToken.status";
|
return APPROOT."data/bulk_export/$sToken.status";
|
||||||
@@ -398,12 +444,14 @@ class ExcelExporter
|
|||||||
protected function GetNewToken()
|
protected function GetNewToken()
|
||||||
{
|
{
|
||||||
$iNum = rand();
|
$iNum = rand();
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
$iNum++;
|
$iNum++;
|
||||||
$sToken = sprintf("%08x", $iNum);
|
$sToken = sprintf("%08x", $iNum);
|
||||||
$sFileName = $this->GetStateFile($sToken);
|
$sFileName = $this->GetStateFile($sToken);
|
||||||
$hFile = @fopen($sFileName, 'x');
|
$hFile = @fopen($sFileName, 'x');
|
||||||
} while ($hFile === false);
|
}
|
||||||
|
while($hFile === false);
|
||||||
|
|
||||||
fclose($hFile);
|
fclose($hFile);
|
||||||
return $sToken;
|
return $sToken;
|
||||||
@@ -411,61 +459,82 @@ class ExcelExporter
|
|||||||
|
|
||||||
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null)
|
protected function GetFieldsList($oSet, $bFieldsAdvanced = false, $bLocalize = true, $aFields = null)
|
||||||
{
|
{
|
||||||
$this->aFieldsList = [];
|
$this->aFieldsList = array();
|
||||||
|
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
$aClasses = $oSet->GetFilter()->GetSelectedClasses();
|
||||||
$this->aAuthorizedClasses = [];
|
$this->aAuthorizedClasses = array();
|
||||||
foreach ($aClasses as $sAlias => $sClassName) {
|
foreach($aClasses as $sAlias => $sClassName)
|
||||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO) {
|
{
|
||||||
|
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO)
|
||||||
|
{
|
||||||
$this->aAuthorizedClasses[$sAlias] = $sClassName;
|
$this->aAuthorizedClasses[$sAlias] = $sClassName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$aAttribs = [];
|
$aAttribs = array();
|
||||||
$this->aTableHeaders = [];
|
$this->aTableHeaders = array();
|
||||||
foreach ($this->aAuthorizedClasses as $sAlias => $sClassName) {
|
foreach($this->aAuthorizedClasses as $sAlias => $sClassName)
|
||||||
$aList[$sAlias] = [];
|
{
|
||||||
|
$aList[$sAlias] = array();
|
||||||
|
|
||||||
foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
|
foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef)
|
||||||
if (is_null($aFields) || (count($aFields) == 0)) {
|
{
|
||||||
|
if (is_null($aFields) || (count($aFields) == 0))
|
||||||
|
{
|
||||||
// Standard list of attributes (no link sets)
|
// Standard list of attributes (no link sets)
|
||||||
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField())) {
|
if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField()))
|
||||||
|
{
|
||||||
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
$sAttCodeEx = $oAttDef->IsExternalField() ? $oAttDef->GetKeyAttCode().'->'.$oAttDef->GetExtAttCode() : $sAttCode;
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
|
if ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE))
|
||||||
if ($bFieldsAdvanced) {
|
{
|
||||||
|
if ($bFieldsAdvanced)
|
||||||
|
{
|
||||||
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
$aList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||||
|
|
||||||
if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE)) {
|
if ($oAttDef->IsExternalKey(EXTKEY_RELATIVE))
|
||||||
|
{
|
||||||
$sRemoteClass = $oAttDef->GetTargetClass();
|
$sRemoteClass = $oAttDef->GetTargetClass();
|
||||||
foreach (MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode) {
|
foreach(MetaModel::GetReconcKeys($sRemoteClass) as $sRemoteAttCode)
|
||||||
|
{
|
||||||
$this->aFieldsList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
|
$this->aFieldsList[$sAlias][$sAttCode.'->'.$sRemoteAttCode] = MetaModel::GetAttributeDef($sRemoteClass, $sRemoteAttCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Any other attribute
|
// Any other attribute
|
||||||
$this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef;
|
$this->aFieldsList[$sAlias][$sAttCodeEx] = $oAttDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// User defined list of attributes
|
// User defined list of attributes
|
||||||
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields)) {
|
if (in_array($sAttCode, $aFields) || in_array($sAlias.'.'.$sAttCode, $aFields))
|
||||||
|
{
|
||||||
$this->aFieldsList[$sAlias][$sAttCode] = $oAttDef;
|
$this->aFieldsList[$sAlias][$sAttCode] = $oAttDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($bFieldsAdvanced) {
|
if ($bFieldsAdvanced)
|
||||||
|
{
|
||||||
$this->aTableHeaders['id'] = '0';
|
$this->aTableHeaders['id'] = '0';
|
||||||
}
|
}
|
||||||
foreach ($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef) {
|
foreach($this->aFieldsList[$sAlias] as $sAttCodeEx => $oAttDef)
|
||||||
|
{
|
||||||
$sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx;
|
$sLabel = $bLocalize ? MetaModel::GetLabel($sClassName, $sAttCodeEx, isset($aParams['showMandatoryFields'])) : $sAttCodeEx;
|
||||||
if ($oAttDef instanceof AttributeDateTime) {
|
if($oAttDef instanceof AttributeDateTime)
|
||||||
|
{
|
||||||
$this->aTableHeaders[$sLabel] = 'datetime';
|
$this->aTableHeaders[$sLabel] = 'datetime';
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$this->aTableHeaders[$sLabel] = 'string';
|
$this->aTableHeaders[$sLabel] = 'string';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -64,20 +63,21 @@ class CoreCannotSaveObjectException extends CoreException
|
|||||||
public function getTextMessage()
|
public function getTextMessage()
|
||||||
{
|
{
|
||||||
$sTitle = Dict::S('UI:Error:SaveFailed');
|
$sTitle = Dict::S('UI:Error:SaveFailed');
|
||||||
$sContent = $sTitle;
|
$sContent = utils::HtmlEntities($sTitle);
|
||||||
|
|
||||||
if (count($this->aIssues) == 1) {
|
if (count($this->aIssues) == 1) {
|
||||||
$sIssue = reset($this->aIssues);
|
$sIssue = reset($this->aIssues);
|
||||||
$sContent .= $sIssue;
|
$sContent .= utils::HtmlEntities($sIssue);
|
||||||
} else {
|
} else {
|
||||||
foreach ($this->aIssues as $sError) {
|
foreach ($this->aIssues as $sError) {
|
||||||
$sContent .= " ".$sError.", ";
|
$sContent .= " ".utils::HtmlEntities($sError).", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sContent;
|
return $sContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getIssues()
|
public function getIssues()
|
||||||
{
|
{
|
||||||
return $this->aIssues;
|
return $this->aIssues;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -36,10 +35,10 @@ class CoreException extends Exception
|
|||||||
}
|
}
|
||||||
if (count($this->m_aContextData) > 0) {
|
if (count($this->m_aContextData) > 0) {
|
||||||
$sMessage .= ": ";
|
$sMessage .= ": ";
|
||||||
$aContextItems = [];
|
$aContextItems = array();
|
||||||
foreach ($this->m_aContextData as $sKey => $value) {
|
foreach ($this->m_aContextData as $sKey => $value) {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$aPairs = [];
|
$aPairs = array();
|
||||||
foreach ($value as $key => $val) {
|
foreach ($value as $key => $val) {
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
$aPairs[] = $key.'=>('.implode(', ', $val).')';
|
||||||
@@ -68,7 +67,7 @@ class CoreException extends Exception
|
|||||||
|
|
||||||
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
|
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
|
||||||
{
|
{
|
||||||
return utils::EscapeHtml($this->getMessage());
|
return $this->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -10,4 +9,5 @@
|
|||||||
*/
|
*/
|
||||||
class CorePortalInvalidActionRuleException extends CoreException
|
class CorePortalInvalidActionRuleException extends CoreException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,7 +8,7 @@ class DictExceptionMissingString extends DictException
|
|||||||
{
|
{
|
||||||
public function __construct($sLanguageCode, $sStringCode)
|
public function __construct($sLanguageCode, $sStringCode)
|
||||||
{
|
{
|
||||||
$aContext = [];
|
$aContext = array();
|
||||||
$aContext['language_code'] = $sLanguageCode;
|
$aContext['language_code'] = $sLanguageCode;
|
||||||
$aContext['string_code'] = $sStringCode;
|
$aContext['string_code'] = $sStringCode;
|
||||||
parent::__construct('Missing localized string', $aContext);
|
parent::__construct('Missing localized string', $aContext);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -9,7 +8,7 @@ class DictExceptionUnknownLanguage extends DictException
|
|||||||
{
|
{
|
||||||
public function __construct($sLanguageCode)
|
public function __construct($sLanguageCode)
|
||||||
{
|
{
|
||||||
$aContext = [];
|
$aContext = array();
|
||||||
$aContext['language_code'] = $sLanguageCode;
|
$aContext['language_code'] = $sLanguageCode;
|
||||||
parent::__construct('Unknown localization language', $aContext);
|
parent::__construct('Unknown localization language', $aContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -7,4 +6,5 @@
|
|||||||
|
|
||||||
class iTopXmlException extends CoreException
|
class iTopXmlException extends CoreException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -20,10 +19,10 @@ class MySQLHasGoneAwayException extends MySQLException
|
|||||||
*/
|
*/
|
||||||
public static function getErrorCodes()
|
public static function getErrorCodes()
|
||||||
{
|
{
|
||||||
return [
|
return array(
|
||||||
2006,
|
2006,
|
||||||
2013,
|
2013,
|
||||||
];
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($sIssue, $aContext)
|
public function __construct($sIssue, $aContext)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -10,4 +9,5 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLNoTransactionException extends MySQLException
|
class MySQLNoTransactionException extends MySQLException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -12,4 +11,5 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLQueryHasNoResultException extends MySQLException
|
class MySQLQueryHasNoResultException extends MySQLException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
@@ -10,4 +9,5 @@
|
|||||||
*/
|
*/
|
||||||
class MySQLTransactionNotClosedException extends MySQLException
|
class MySQLTransactionNotClosedException extends MySQLException
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (C) 2013-2024 Combodo SAS
|
* Copyright (C) 2013-2024 Combodo SAS
|
||||||
*
|
*
|
||||||
@@ -23,8 +22,8 @@
|
|||||||
* @author Olivier DAIN <olivier.dain@combodo.com>
|
* @author Olivier DAIN <olivier.dain@combodo.com>
|
||||||
* @since 3.0.0 N°3588
|
* @since 3.0.0 N°3588
|
||||||
*/
|
*/
|
||||||
class FindStylesheetObject
|
class FindStylesheetObject{
|
||||||
{
|
|
||||||
//file URIs
|
//file URIs
|
||||||
private $aStylesheetFileURIs;
|
private $aStylesheetFileURIs;
|
||||||
|
|
||||||
@@ -93,8 +92,7 @@ class FindStylesheetObject
|
|||||||
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
$this->sLastStyleSheetPath = $sStylesheetFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AlreadyFetched(string $sStylesheetFilePath): bool
|
public function AlreadyFetched(string $sStylesheetFilePath) : bool {
|
||||||
{
|
|
||||||
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
return in_array($sStylesheetFilePath, $this->aAllStylesheetFilePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Copyright (C) 2010-2024 Combodo SAS
|
// Copyright (C) 2010-2024 Combodo SAS
|
||||||
//
|
//
|
||||||
// This file is part of iTop.
|
// This file is part of iTop.
|
||||||
@@ -17,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent class InputOutputTask
|
* Persistent class InputOutputTask
|
||||||
*
|
*
|
||||||
@@ -34,34 +34,35 @@ class InputOutputTask extends cmdbAbstractObject
|
|||||||
{
|
{
|
||||||
public static function Init()
|
public static function Init()
|
||||||
{
|
{
|
||||||
$aParams =
|
$aParams = array
|
||||||
[
|
(
|
||||||
"category" => "application",
|
"category" => "application",
|
||||||
"key_type" => "autoincrement",
|
"key_type" => "autoincrement",
|
||||||
"name_attcode" => "name",
|
"name_attcode" => "name",
|
||||||
"state_attcode" => "",
|
"state_attcode" => "",
|
||||||
"reconc_keys" => [],
|
"reconc_keys" => array(),
|
||||||
"db_table" => "priv_iotask",
|
"db_table" => "priv_iotask",
|
||||||
"db_key_field" => "id",
|
"db_key_field" => "id",
|
||||||
"db_finalclass_field" => "",
|
"db_finalclass_field" => "",
|
||||||
];
|
);
|
||||||
MetaModel::Init_Params($aParams);
|
MetaModel::Init_Params($aParams);
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("name", ["allowed_values" => null, "sql" => "name", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("name", array("allowed_values"=>null, "sql"=>"name", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => "", "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("category", ["allowed_values" => new ValueSetEnum('Input, Ouput'), "sql" => "category", "default_value" => "Input", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("category", array("allowed_values"=>new ValueSetEnum('Input, Ouput'), "sql"=>"category", "default_value"=>"Input", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", ["allowed_values" => new ValueSetEnum('File, Database, Web Service'), "sql" => "source_type", "default_value" => "File", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("source_type", array("allowed_values"=>new ValueSetEnum('File, Database, Web Service'), "sql"=>"source_type", "default_value"=>"File", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", ["allowed_values" => new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql" => "source_subtype", "default_value" => "CSV", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("source_subtype", array("allowed_values"=>new ValueSetEnum('Oracle, MySQL, Postgress, MSSQL, SOAP, HTTP-Get, HTTP-Post, XML/RPC, CSV, XML, Excel'), "sql"=>"source_subtype", "default_value"=>"CSV", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeString("source_path", ["allowed_values" => null, "sql" => "source_path", "default_value" => "", "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeString("source_path", array("allowed_values"=>null, "sql"=>"source_path", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", ["class_category" => "", "more_values" => "", "sql" => "objects_class", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeClass("objects_class", array("class_category"=>"", "more_values"=>"", "sql"=>"objects_class", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", ["allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "test_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("test_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"test_mode", "default_value"=>'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", ["allowed_values" => new ValueSetEnum('Yes,No'), "sql" => "verbose_mode", "default_value" => 'No', "is_null_allowed" => false, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("verbose_mode", array("allowed_values"=>new ValueSetEnum('Yes,No'), "sql"=>"verbose_mode", "default_value" => 'No', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||||
MetaModel::Init_AddAttribute(new AttributeEnum("options", ["allowed_values" => new ValueSetEnum('Full, Update Only, Creation Only'), "sql" => "options", "default_value" => 'Full', "is_null_allowed" => true, "depends_on" => []]));
|
MetaModel::Init_AddAttribute(new AttributeEnum("options", array("allowed_values"=>new ValueSetEnum('Full, Update Only, Creation Only'), "sql"=>"options", "default_value"=> 'Full', "is_null_allowed"=>true, "depends_on"=>array())));
|
||||||
|
|
||||||
// Display lists
|
// Display lists
|
||||||
MetaModel::Init_SetZListItems('details', ['name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path' , 'options', 'test_mode', 'verbose_mode']); // Attributes to be displayed for the complete details
|
MetaModel::Init_SetZListItems('details', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype', 'source_path' , 'options', 'test_mode', 'verbose_mode')); // Attributes to be displayed for the complete details
|
||||||
MetaModel::Init_SetZListItems('list', ['description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options']); // Attributes to be displayed for a list
|
MetaModel::Init_SetZListItems('list', array('description', 'category', 'objects_class', 'source_type', 'source_subtype', 'options')); // Attributes to be displayed for a list
|
||||||
// Search criteria
|
// Search criteria
|
||||||
MetaModel::Init_SetZListItems('standard_search', ['name', 'category', 'objects_class', 'source_type', 'source_subtype']); // Criteria of the std search form
|
MetaModel::Init_SetZListItems('standard_search', array('name', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the std search form
|
||||||
MetaModel::Init_SetZListItems('advanced_search', ['name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype']); // Criteria of the advanced search form
|
MetaModel::Init_SetZListItems('advanced_search', array('name', 'description', 'category', 'objects_class', 'source_type', 'source_subtype')); // Criteria of the advanced search form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
?>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
|
||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user