mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 23:44:11 +01:00
Compare commits
247 Commits
2.6.0-prod
...
2.6.2-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4d538ef6c | ||
|
|
33903f570b | ||
|
|
127809a836 | ||
|
|
6c948873ff | ||
|
|
a93be39aeb | ||
|
|
7c93d116ec | ||
|
|
f948d6e026 | ||
|
|
a222ead43c | ||
|
|
d6bfbbcd30 | ||
|
|
17df9d0f9d | ||
|
|
93099ea3c7 | ||
|
|
2f9e050e2b | ||
|
|
5c341138e1 | ||
|
|
56b9eb6cf3 | ||
|
|
db20244212 | ||
|
|
6f9f74e72f | ||
|
|
8070d5b9b7 | ||
|
|
6197ecbaf4 | ||
|
|
ca585d3f42 | ||
|
|
02c78d4044 | ||
|
|
9e5d668c02 | ||
|
|
051656f295 | ||
|
|
9a51a44549 | ||
|
|
5102b113ed | ||
|
|
f1e4d94499 | ||
|
|
d04102bab3 | ||
|
|
c723d19e01 | ||
|
|
dac77e0606 | ||
|
|
02b98543d9 | ||
|
|
519aaadd9a | ||
|
|
fe27fef530 | ||
|
|
72dbb6f937 | ||
|
|
ccb29d10ae | ||
|
|
e479775833 | ||
|
|
86a7192f5a | ||
|
|
4a1be13904 | ||
|
|
0f3347f64d | ||
|
|
6564d84a2f | ||
|
|
f4747c5cef | ||
|
|
1e92c2f28a | ||
|
|
e4b097b196 | ||
|
|
85653c9ffc | ||
|
|
da5d8b20fa | ||
|
|
9a5a5f858f | ||
|
|
a0cd281c42 | ||
|
|
6bb5606c00 | ||
|
|
a6ceb88fca | ||
|
|
7bb7a94fbc | ||
|
|
e4324cedb4 | ||
|
|
07781c7c9d | ||
|
|
ea58a807fc | ||
|
|
fb6806a1c1 | ||
|
|
166451c4e9 | ||
|
|
7c1290f684 | ||
|
|
179c774ba8 | ||
|
|
e886d80de6 | ||
|
|
3791b2dd24 | ||
|
|
12c916f4e5 | ||
|
|
ba7e00e130 | ||
|
|
bada955725 | ||
|
|
f9e18675f3 | ||
|
|
22416cc0be | ||
|
|
ec086ad94a | ||
|
|
17d4b570e8 | ||
|
|
2dfad12553 | ||
|
|
26dcaa0ded | ||
|
|
b5d3ddb7e3 | ||
|
|
8b178914b3 | ||
|
|
ce6fd4d775 | ||
|
|
9c75cb4537 | ||
|
|
633fa343a5 | ||
|
|
a1d01e252b | ||
|
|
b157fad0b6 | ||
|
|
70d2bb163c | ||
|
|
fae6c89e9a | ||
|
|
89d310258b | ||
|
|
a58529f46c | ||
|
|
12a2035791 | ||
|
|
b1ff7f0e9b | ||
|
|
23cf2b91f4 | ||
|
|
3c4fe338b6 | ||
|
|
6159ab33b7 | ||
|
|
77f757995e | ||
|
|
2858d13fd5 | ||
|
|
99f398a87e | ||
|
|
87ee731dbe | ||
|
|
f2380ae354 | ||
|
|
2d039af278 | ||
|
|
831879fe37 | ||
|
|
ea1dfd8933 | ||
|
|
24519c69a4 | ||
|
|
b5c4801beb | ||
|
|
3eff8f62b1 | ||
|
|
16c8466841 | ||
|
|
b83e5e2b72 | ||
|
|
764b0f8e31 | ||
|
|
cac0da4e3d | ||
|
|
7e064365eb | ||
|
|
7c7382f372 | ||
|
|
4918b9c83a | ||
|
|
ed95f4e05f | ||
|
|
9f0e8dc49b | ||
|
|
693fdfdc5b | ||
|
|
b8d5c01382 | ||
|
|
01108ca83d | ||
|
|
3d5b7197f6 | ||
|
|
d3db77c675 | ||
|
|
54c027823b | ||
|
|
f63aceeabe | ||
|
|
533e65fcd1 | ||
|
|
3fb0c768e6 | ||
|
|
243aab1030 | ||
|
|
22dba9ae07 | ||
|
|
02857a86fd | ||
|
|
d663d01798 | ||
|
|
3602163b38 | ||
|
|
3322074ce7 | ||
|
|
83bb3b6d72 | ||
|
|
229f800266 | ||
|
|
75737b4ffe | ||
|
|
a5340917a7 | ||
|
|
914d19e7e4 | ||
|
|
eb49dbbdc8 | ||
|
|
912bab5a43 | ||
|
|
94092f445f | ||
|
|
856c037bb0 | ||
|
|
388896b963 | ||
|
|
1d8addf675 | ||
|
|
c8c3d32b18 | ||
|
|
75a0979eee | ||
|
|
d6a0a279a5 | ||
|
|
44f5d71e1b | ||
|
|
9c71d32964 | ||
|
|
d199d84b27 | ||
|
|
24aca83de4 | ||
|
|
3de7aa1ada | ||
|
|
5a0edb5c39 | ||
|
|
d4fec14123 | ||
|
|
38951fab1a | ||
|
|
e2c8237beb | ||
|
|
1224570fa5 | ||
|
|
afb99c0f4b | ||
|
|
733c908e34 | ||
|
|
377b4b038c | ||
|
|
3f7fd6f9f9 | ||
|
|
1cb36621a1 | ||
|
|
ddd9188eb7 | ||
|
|
02254eac67 | ||
|
|
ebe026b2e9 | ||
|
|
efc7c5b0f4 | ||
|
|
f68a77450d | ||
|
|
c5943c6c28 | ||
|
|
bc3b50ad23 | ||
|
|
1f7923beae | ||
|
|
2f15bbdaf3 | ||
|
|
a2d34d1779 | ||
|
|
cdba1e0d36 | ||
|
|
48f15d7781 | ||
|
|
d0a766d424 | ||
|
|
a89bca4626 | ||
|
|
23ec21e494 | ||
|
|
63a36fd0f6 | ||
|
|
02617e8976 | ||
|
|
7cf7e55454 | ||
|
|
5067c867b8 | ||
|
|
6b5cc7ca4b | ||
|
|
7bb49893ee | ||
|
|
bf62b63173 | ||
|
|
b8fb1fa78a | ||
|
|
818b4d08da | ||
|
|
f438fbd06f | ||
|
|
297a45d477 | ||
|
|
17fe9dfd5f | ||
|
|
9d0cbca497 | ||
|
|
a613b4b101 | ||
|
|
c989e2eda5 | ||
|
|
c6fd381b01 | ||
|
|
a784661025 | ||
|
|
1f9a638bc1 | ||
|
|
545504c0de | ||
|
|
32f1e97bcd | ||
|
|
43b0747b83 | ||
|
|
9637e75f97 | ||
|
|
84767692b0 | ||
|
|
d484614c0f | ||
|
|
b403bace6c | ||
|
|
0b751a9dd6 | ||
|
|
8f434cad08 | ||
|
|
f83292fccc | ||
|
|
90e128f951 | ||
|
|
8efc372a68 | ||
|
|
257fb4d036 | ||
|
|
97261820f6 | ||
|
|
2f83a2168c | ||
|
|
c0275eec21 | ||
|
|
2bd7a7b5f8 | ||
|
|
0aab80917a | ||
|
|
31a2b634cc | ||
|
|
dc7bafa41c | ||
|
|
505aad1e89 | ||
|
|
4508b9d7d5 | ||
|
|
888aa5f958 | ||
|
|
4051524b5c | ||
|
|
c8c4b072b1 | ||
|
|
08543287e8 | ||
|
|
21e5eee31f | ||
|
|
ed3fd851f1 | ||
|
|
dfe81f6272 | ||
|
|
00c59b7f2c | ||
|
|
dbcde14f5e | ||
|
|
a6f4adfed8 | ||
|
|
effaba42d0 | ||
|
|
340cacc691 | ||
|
|
0bce9c78ea | ||
|
|
48c920f848 | ||
|
|
a85bedd31c | ||
|
|
23269eab77 | ||
|
|
05bcfbe4c3 | ||
|
|
27ad2e2169 | ||
|
|
5d09841cd5 | ||
|
|
11ec46c18b | ||
|
|
da76fc70bb | ||
|
|
2b563d4fc8 | ||
|
|
2773a8bf2f | ||
|
|
ad36011fc8 | ||
|
|
b82b095f58 | ||
|
|
2f5c810276 | ||
|
|
d90e094d4d | ||
|
|
4eb416d407 | ||
|
|
636a3940cd | ||
|
|
352f8cee10 | ||
|
|
523e19528e | ||
|
|
9f3332b2f2 | ||
|
|
2b71621628 | ||
|
|
5349fc6f4b | ||
|
|
1665b12b86 | ||
|
|
1bbed99636 | ||
|
|
778db225a8 | ||
|
|
ca48e8ff92 | ||
|
|
75d5630164 | ||
|
|
bb6bd61c37 | ||
|
|
b51b5582a0 | ||
|
|
bc5643707e | ||
|
|
27b1b1f8a8 | ||
|
|
a45e543eac | ||
|
|
50235bbb04 | ||
|
|
d31a4047f6 |
103
.doc/README.md
Normal file
103
.doc/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Phpdoc dokuwiki template
|
||||
This directory contains a template rendering iTop phpdoc as wiki pages.
|
||||
|
||||
|
||||
conventional tag 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 tags where 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 with `ClassName::`
|
||||
* 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 ans 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 enclose 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
|
||||
```
|
||||
composer require phpdocumentor/phpdocumentor:~2 --dev
|
||||
```
|
||||
|
||||
## Generation
|
||||
`.doc/bin/build-doc-object-manipulation` and `.doc/bin/build-doc-extensions` contains examples of doc. generation, beware: they have to be called from iTop root directory:
|
||||
```shell
|
||||
cd /path/to/itop/
|
||||
./.doc/bin/build-doc-object-manipulation
|
||||
```
|
||||
|
||||
the resulting documentation is written into `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
|
||||
|
||||
7
.doc/bin/build-doc-extensions
Executable file
7
.doc/bin/build-doc-extensions
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/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 .doc/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
|
||||
8
.doc/bin/build-doc-object-manipulation
Executable file
8
.doc/bin/build-doc-object-manipulation
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/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 .doc/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
|
||||
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 informations]]
|
||||
|
||||
</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>
|
||||
40
.gitignore
vendored
40
.gitignore
vendored
@@ -1,38 +1,40 @@
|
||||
|
||||
# no slash at the end to handle also symlinks
|
||||
/toolkit
|
||||
/conf/*
|
||||
/env-*/*
|
||||
/conf
|
||||
/env-*
|
||||
|
||||
# composer reserver directory, from sources, populate/update using "composer install"
|
||||
vendor/*
|
||||
test/vendor/*
|
||||
|
||||
# all datas but listing prevention
|
||||
data/*
|
||||
!data/.htaccess
|
||||
!data/index.php
|
||||
!data/web.config
|
||||
/data/**
|
||||
!/data/.htaccess
|
||||
!/data/index.php
|
||||
!/data/web.config
|
||||
|
||||
# iTop extensions
|
||||
extensions/*
|
||||
!extensions/readme.txt
|
||||
/extensions/**
|
||||
!/extensions/readme.txt
|
||||
|
||||
# all logs but listing prevention
|
||||
log/*
|
||||
!log/.htaccess
|
||||
!log/index.php
|
||||
!log/web.config
|
||||
/log/**
|
||||
!/log/.htaccess
|
||||
!/log/index.php
|
||||
!/log/web.config
|
||||
|
||||
|
||||
# Jetbrains
|
||||
.idea/**
|
||||
!.idea/encodings.xml
|
||||
!.idea/codeStyles
|
||||
!.idea/codeStyles/*
|
||||
!.idea/inspectionProfiles
|
||||
!.idea/inspectionProfiles/*
|
||||
|
||||
/.idea/**
|
||||
!/.idea/encodings.xml
|
||||
!/.idea/codeStyles
|
||||
!/.idea/codeStyles/*
|
||||
!/.idea/inspectionProfiles
|
||||
!/.idea/inspectionProfiles/*
|
||||
|
||||
#phpdocumentor temp file
|
||||
ast.dump
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
1
.idea/inspectionProfiles/profiles_settings.xml
generated
1
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +1,5 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="projectProfile" value="Combodo" />
|
||||
<option name="PROJECT_PROFILE" value="Combodo" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
|
||||
12
README.md
12
README.md
@@ -35,14 +35,14 @@ iTop also offers mass import tools and web services to integrate with your IT
|
||||
- [Changes since the previous version][58]
|
||||
- [New features][59]
|
||||
- [Migration notes][60]
|
||||
- [Download iTop 2.6.0-beta][61]
|
||||
- [Download iTop 2.6.1][61]
|
||||
|
||||
|
||||
### Version 2.5
|
||||
- [Changes since the previous version][54]
|
||||
- [New features][55]
|
||||
- [Migration notes][56]
|
||||
- [Download iTop 2.5.0][57]
|
||||
- [Download iTop 2.5.1][57]
|
||||
|
||||
|
||||
### Version 2.4
|
||||
@@ -74,6 +74,7 @@ We would like to give a special thank you to the people from the community who c
|
||||
- Gumble, David
|
||||
- Hippler, Lars
|
||||
- Khamit, Shamil
|
||||
- Kincel, Martin
|
||||
- Konečný, Kamil
|
||||
- Kunin, Vladimir
|
||||
- Lassiter, Dennis
|
||||
@@ -88,7 +89,6 @@ We would like to give a special thank you to the people from the community who c
|
||||
#### Aliases
|
||||
- chifu1234
|
||||
- cprobst
|
||||
- jbostoen
|
||||
- Karkoff1212
|
||||
- larhip
|
||||
- Laura
|
||||
@@ -128,14 +128,14 @@ We would like to give a special thank you to the people from the community who c
|
||||
[50]: https://www.itophub.io/wiki/page?id=2_4_0:release:change_log
|
||||
[51]: https://www.itophub.io/wiki/page?id=2_4_0:release:2_4_whats_new
|
||||
[52]: https://www.itophub.io/wiki/page?id=2_4_0:install:230_to_240_migration_notes
|
||||
[53]: https://sourceforge.net/projects/itop/files/itop/2.4.1/iTop-2.4.1-3714.zip/download
|
||||
[53]: https://sourceforge.net/projects/itop/files/itop/2.4.1
|
||||
|
||||
[54]: https://www.itophub.io/wiki/page?id=2_5_0:release:change_log
|
||||
[55]: https://www.itophub.io/wiki/page?id=2_5_0:release:2_5_whats_new
|
||||
[56]: https://www.itophub.io/wiki/page?id=2_5_0:install:240_to_250_migration_notes
|
||||
[57]: https://sourceforge.net/projects/itop/files/itop/2.5.0/iTop-2.5.0-3935.zip/download
|
||||
[57]: https://sourceforge.net/projects/itop/files/itop/2.5.1
|
||||
|
||||
[58]: https://www.itophub.io/wiki/page?id=2_6_0:release:change_log
|
||||
[59]: https://www.itophub.io/wiki/page?id=2_6_0:release:2_6_whats_new
|
||||
[60]: https://www.itophub.io/wiki/page?id=2_6_0:install:250_to_260_migration_notes
|
||||
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.0-beta/iTop-2.6-beta-4146.zip/download
|
||||
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.1
|
||||
|
||||
@@ -365,7 +365,7 @@ interface iPopupMenuExtension
|
||||
* Base class for the various types of custom menus
|
||||
*
|
||||
* @package Extensibility
|
||||
* @internal
|
||||
* @api
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class ApplicationPopupMenuItem
|
||||
@@ -378,8 +378,10 @@ abstract class ApplicationPopupMenuItem
|
||||
protected $aCssClasses;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Constructor
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param array $aCssClasses The CSS classes to add to the menu
|
||||
@@ -509,6 +511,9 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||
|
||||
/**
|
||||
* Class for adding an item that triggers some Javascript code
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sJSCode In case the menu consists in executing some havascript code inside the page, pass it here. If supplied $sURL ans $sTarget will be ignored
|
||||
@@ -825,6 +830,10 @@ class RestResult
|
||||
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
||||
*/
|
||||
const UNSAFE = 12;
|
||||
/**
|
||||
* Result: the request page number is not valid. It must be an integer greater than 0
|
||||
*/
|
||||
const INVALID_PAGE = 13;
|
||||
/**
|
||||
* Result: the operation could not be performed, see the message for troubleshooting
|
||||
*/
|
||||
@@ -1091,10 +1100,13 @@ class RestUtils
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
||||
* @param int $iLimit The limit of results to return
|
||||
* @param int $iOffset The offset of results to return
|
||||
*
|
||||
* @return DBObjectSet The search result set
|
||||
* @throws Exception If the input structure is not valid
|
||||
*/
|
||||
public static function GetObjectSetFromKey($sClass, $key)
|
||||
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
||||
{
|
||||
if (is_object($key))
|
||||
{
|
||||
@@ -1128,7 +1140,7 @@ class RestUtils
|
||||
{
|
||||
throw new Exception("Wrong format for key");
|
||||
}
|
||||
$oObjectSet = new DBObjectSet($oSearch);
|
||||
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
|
||||
return $oObjectSet;
|
||||
}
|
||||
|
||||
|
||||
@@ -385,6 +385,7 @@ EOF
|
||||
|
||||
if (!isset($aExtraParams['disable_plugins']) || !$aExtraParams['disable_plugins'])
|
||||
{
|
||||
/** @var iApplicationUIExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oExtensionInstance->OnDisplayProperties($this, $oPage, $bEditMode);
|
||||
@@ -648,6 +649,7 @@ EOF
|
||||
}
|
||||
$oPage->SetCurrentTab('');
|
||||
|
||||
/** @var \iApplicationUIExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oExtensionInstance->OnDisplayRelations($this, $oPage, $bEditMode);
|
||||
@@ -908,7 +910,7 @@ EOF
|
||||
|
||||
|
||||
/**
|
||||
* @param \iTopWebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param bool $bEditMode
|
||||
*
|
||||
* @throws \CoreException
|
||||
@@ -918,8 +920,9 @@ EOF
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \Exception
|
||||
*/
|
||||
function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
||||
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
$sTemplate = Utils::ReadFromFile(MetaModel::GetDisplayTemplate(get_class($this)));
|
||||
if (!empty($sTemplate))
|
||||
@@ -941,6 +944,7 @@ EOF
|
||||
// template not found display the object using the *old style*
|
||||
$oPage->add('<div id="search-widget-results-outer">');
|
||||
$this->DisplayBareHeader($oPage, $bEditMode);
|
||||
/** @var \iTopWebPage $oPage */
|
||||
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
|
||||
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
|
||||
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
|
||||
@@ -2101,7 +2105,7 @@ EOF
|
||||
$('#{$iId}_console_form').console_form_handler('alignColumns');
|
||||
$('#{$iId}_console_form').console_form_handler('option', 'field_set', $('#{$iId}_field_set'));
|
||||
// field_change must be processed to refresh the hidden value at anytime
|
||||
$('#{$iId}_console_form').bind('value_change', function() { $('#{$iId}').val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); console.error($('#{$iId}').val()); });
|
||||
$('#{$iId}_console_form').bind('value_change', function() { $('#{$iId}').val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); });
|
||||
// Initialize the hidden value with current state
|
||||
// update_value is triggered when preparing the wizard helper object for ajax calls
|
||||
$('#{$iId}').bind('update_value', function() { $(this).val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); });
|
||||
@@ -2174,6 +2178,11 @@ EOF
|
||||
if ((count($aAllowedValues) == 1) && ($bMandatory == 'true'))
|
||||
{
|
||||
// When there is only once choice, select it by default
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$iId').attr('data-validate','dependencies');
|
||||
EOF
|
||||
);
|
||||
$sSelected = ' selected';
|
||||
}
|
||||
else
|
||||
@@ -3032,6 +3041,7 @@ EOF
|
||||
$current = parent::GetHilightClass(); // Default computation
|
||||
|
||||
// Invoke extensions before the deletion (the deletion will do some cleanup and we might loose some information
|
||||
/** @var \iApplicationUIExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
$new = $oExtensionInstance->GetHilightClass($this);
|
||||
@@ -3288,7 +3298,7 @@ EOF
|
||||
$aDurationData = $value;
|
||||
if (!is_array($aDurationData))
|
||||
{
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
$iValue = (((24 * $aDurationData['d']) + $aDurationData['h']) * 60 + $aDurationData['m']) * 60 + $aDurationData['s'];
|
||||
@@ -3453,6 +3463,7 @@ EOF
|
||||
}
|
||||
|
||||
// Invoke extensions after the update of the object from the form
|
||||
/** @var \iApplicationUIExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oExtensionInstance->OnFormSubmit($this, $sFormPrefix);
|
||||
@@ -3524,21 +3535,13 @@ EOF
|
||||
{
|
||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
||||
{
|
||||
$sLinkClass = $oAttDef->GetLinkedClass();
|
||||
if ($oAttDef->IsIndirect())
|
||||
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
||||
// Recursing over n:n link datetime attributes
|
||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
||||
{
|
||||
$oLinkAttDef = MetaModel::GetAttributeDef($sLinkClass, $aMatches[1]);
|
||||
// Recursing over n:n link datetime attributes
|
||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
||||
{
|
||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
||||
$aMatches[1], $sLinkClass, $aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aObjData[$aMatches[1]] = $value;
|
||||
}
|
||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
||||
$aMatches[1], $sObjClass, $aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3555,26 +3558,19 @@ EOF
|
||||
foreach($aRawToBeModified as $iObjKey => $aData)
|
||||
{
|
||||
$sSubFormPrefix = $aData['formPrefix'];
|
||||
$sObjClass = isset($aData['class']) ? $aData['class'] : $oAttDef->GetLinkedClass();
|
||||
$aObjData = array();
|
||||
foreach($aData as $sKey => $value)
|
||||
{
|
||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
||||
{
|
||||
$sLinkClass = $oAttDef->GetLinkedClass();
|
||||
if ($oAttDef->IsIndirect())
|
||||
$oLinkAttDef = MetaModel::GetAttributeDef($sObjClass, $aMatches[1]);
|
||||
// Recursing over n:n link datetime attributes
|
||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
||||
{
|
||||
$oLinkAttDef = MetaModel::GetAttributeDef($sLinkClass, $aMatches[1]);
|
||||
// Recursing over n:n link datetime attributes
|
||||
// Note: We might need to do it with other attribute types, like Document or redundancy setting.
|
||||
if ($oLinkAttDef instanceof AttributeDateTime)
|
||||
{
|
||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
||||
$aMatches[1], $sLinkClass, $aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aObjData[$aMatches[1]] = $value;
|
||||
}
|
||||
$aObjData[$aMatches[1]] = $this->PrepareValueFromPostedForm($sSubFormPrefix,
|
||||
$aMatches[1], $sObjClass, $aData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3690,6 +3686,9 @@ EOF
|
||||
return $aErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function DBInsertNoReload()
|
||||
{
|
||||
$res = parent::DBInsertNoReload();
|
||||
@@ -3707,6 +3706,7 @@ EOF
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Attaches InlineImages to the current object
|
||||
*/
|
||||
protected function OnObjectKeyReady()
|
||||
@@ -3831,6 +3831,12 @@ EOF
|
||||
$this->bAllowWrite = $bAllow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function DoCheckToWrite()
|
||||
{
|
||||
parent::DoCheckToWrite();
|
||||
@@ -4211,6 +4217,7 @@ EOF
|
||||
$oDummyObj->Set($sAttCode, $currValue);
|
||||
/** @var ormTagSet $oTagSet */
|
||||
$oTagSet = $oDummyObj->Get($sAttCode);
|
||||
$oTagSet->SetDisplayPartial(true);
|
||||
foreach($aKeys as $iIndex => $sValues)
|
||||
{
|
||||
if ($iIndex == 0)
|
||||
|
||||
@@ -444,44 +444,41 @@ EOF
|
||||
$sClass = $oQuery->GetClass();
|
||||
foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
|
||||
{
|
||||
if ($sAttType == 'AttributeLinkedSet')
|
||||
// For external fields, find the real type of the target
|
||||
$sTargetClass = $sClass;
|
||||
while (is_a($sAttType, 'AttributeExternalField', true))
|
||||
{
|
||||
$sExtKeyAttCode = $this->oModelReflection->GetAttributeProperty($sTargetClass, $sAttCode, 'extkey_attcode');
|
||||
$sTargetAttCode = $this->oModelReflection->GetAttributeProperty($sTargetClass, $sAttCode, 'target_attcode');
|
||||
$sTargetClass = $this->oModelReflection->GetAttributeProperty($sTargetClass, $sExtKeyAttCode, 'targetclass');
|
||||
$aTargetAttCodes = $this->oModelReflection->ListAttributes($sTargetClass);
|
||||
$sAttType = $aTargetAttCodes[$sTargetAttCode];
|
||||
}
|
||||
if (is_a($sAttType, 'AttributeLinkedSet', true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (is_subclass_of($sAttType, 'AttributeLinkedSet'))
|
||||
if (is_a($sAttType, 'AttributeFriendlyName', true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($sAttType == 'AttributeFriendlyName')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (is_subclass_of($sAttType, 'AttributeFriendlyName'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($sAttType == 'AttributeExternalField')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (is_subclass_of($sAttType, 'AttributeExternalField'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ($sAttType == 'AttributeOneWayPassword')
|
||||
if (is_a($sAttType, 'AttributeOneWayPassword', true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
|
||||
$aGroupBy[$sAttCode] = $sLabel;
|
||||
|
||||
if (is_subclass_of($sAttType, 'AttributeDateTime') || $sAttType == 'AttributeDateTime')
|
||||
if (!in_array($sLabel, $aGroupBy))
|
||||
{
|
||||
$aGroupBy[$sAttCode.':hour'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Hour', $sLabel);
|
||||
$aGroupBy[$sAttCode.':month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Month', $sLabel);
|
||||
$aGroupBy[$sAttCode.':day_of_week'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek', $sLabel);
|
||||
$aGroupBy[$sAttCode.':day_of_month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth', $sLabel);
|
||||
$aGroupBy[$sAttCode] = $sLabel;
|
||||
|
||||
if (is_a($sAttType, 'AttributeDateTime', true))
|
||||
{
|
||||
$aGroupBy[$sAttCode.':hour'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Hour', $sLabel);
|
||||
$aGroupBy[$sAttCode.':month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Month', $sLabel);
|
||||
$aGroupBy[$sAttCode.':day_of_week'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek', $sLabel);
|
||||
$aGroupBy[$sAttCode.':day_of_month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth', $sLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
asort($aGroupBy);
|
||||
@@ -619,7 +616,7 @@ class DashletUnknown extends Dashlet
|
||||
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
|
||||
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
||||
$oPage->add('<div class="dashlet-ukn-image"><img src="'.utils::HtmlEntities($sIconUrl).'" /></div>');
|
||||
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
||||
|
||||
$oPage->add('</div>');
|
||||
@@ -639,7 +636,7 @@ class DashletUnknown extends Dashlet
|
||||
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
|
||||
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
|
||||
$oPage->add('<div class="dashlet-ukn-image"><img src="'.utils::HtmlEntities($sIconUrl).'" /></div>');
|
||||
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
|
||||
|
||||
$oPage->add('</div>');
|
||||
@@ -780,7 +777,7 @@ class DashletProxy extends DashletUnknown
|
||||
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
|
||||
$oPage->add('<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>');
|
||||
$oPage->add('<div class="dashlet-pxy-image"><img src="'.utils::HtmlEntities($sIconUrl).'" /></div>');
|
||||
$oPage->add('<div class="dashlet-pxy-text">'.$sExplainText.'</div>');
|
||||
|
||||
$oPage->add('</div>');
|
||||
@@ -1272,6 +1269,10 @@ abstract class DashletGroupBy extends Dashlet
|
||||
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||
$oBlock = new DisplayBlock($oFilter, $sType);
|
||||
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
|
||||
if($bEditMode)
|
||||
{
|
||||
$oPage->add('<div class="dashlet-blocker"></div>');
|
||||
}
|
||||
$oPage->add('</div>');
|
||||
}
|
||||
}
|
||||
@@ -1913,7 +1914,7 @@ class DashletHeaderStatic extends Dashlet
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
$oPage->add('<div class="main_header">');
|
||||
|
||||
$oPage->add('<img src="'.$sIconPath.'">');
|
||||
$oPage->add('<img src="'.utils::HtmlEntities($sIconPath).'">');
|
||||
$oPage->add('<h1>'.$this->oModelReflection->DictString($sTitle).'</h1>');
|
||||
|
||||
$oPage->add('</div>');
|
||||
@@ -2069,7 +2070,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
$oPage->add('<div class="main_header">');
|
||||
|
||||
$oPage->add('<img src="'.$sIconPath.'">');
|
||||
$oPage->add('<img src="'.utils::HtmlEntities($sIconPath).'">');
|
||||
|
||||
if (isset($aExtraParams['query_params']))
|
||||
{
|
||||
@@ -2113,7 +2114,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$oPage->add('<div class="dashlet-content">');
|
||||
$oPage->add('<div class="main_header">');
|
||||
|
||||
$oPage->add('<img src="'.$sIconPath.'">');
|
||||
$oPage->add('<img src="'.utils::HtmlEntities($sIconPath).'">');
|
||||
|
||||
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
|
||||
|
||||
@@ -2332,7 +2333,7 @@ class DashletBadge extends Dashlet
|
||||
|
||||
$oPage->add('<div id="block_fake_'.$this->sId.'" class="display_block">');
|
||||
$oPage->add('<p>');
|
||||
$oPage->add(' <a class="actions"><img src="'.$sIconUrl.'" style="vertical-align:middle;float;left;margin-right:10px;border:0;">'.$sClassLabel.': 947</a>');
|
||||
$oPage->add(' <a class="actions"><img src="'.utils::HtmlEntities($sIconUrl).'" style="vertical-align:middle;float;left;margin-right:10px;border:0;">'.$sClassLabel.': 947</a>');
|
||||
$oPage->add('</p>');
|
||||
$oPage->add('<p>');
|
||||
$oPage->add(' <a>'.Dict::Format('UI:ClickToCreateNew', $sClassLabel).'</a>');
|
||||
|
||||
@@ -184,6 +184,10 @@ class DataTable
|
||||
*/
|
||||
public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams)
|
||||
{
|
||||
if ($iPageSize < 1)
|
||||
{
|
||||
$iPageSize = -1; // convention: no pagination
|
||||
}
|
||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
|
||||
@@ -222,14 +226,21 @@ class DataTable
|
||||
}
|
||||
|
||||
$sCombo = '<select class="pagesize">';
|
||||
for($iPage = 1; $iPage < 5; $iPage++)
|
||||
if($iPageSize < 1)
|
||||
{
|
||||
$iNbItems = $iPage * $iDefaultPageSize;
|
||||
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
||||
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
||||
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||
}
|
||||
$sSelected = ($iPageSize < 1) ? 'selected="selected"' : '';
|
||||
$sCombo .= "<option $sSelected value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||
else
|
||||
{
|
||||
for($iPage = 1; $iPage < 5; $iPage++)
|
||||
{
|
||||
$iNbItems = $iPage * $iDefaultPageSize;
|
||||
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
||||
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
||||
}
|
||||
$sCombo .= "<option value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||
}
|
||||
|
||||
$sCombo .= '</select>';
|
||||
|
||||
$sPages = Dict::S('UI:Pagination:PagesLabel');
|
||||
@@ -431,7 +442,7 @@ EOF;
|
||||
}
|
||||
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)
|
||||
@@ -565,7 +576,7 @@ EOF;
|
||||
<<<EOF
|
||||
var oTable = $('#{$this->iListId} table.listResults');
|
||||
oTable.tableHover();
|
||||
oTable.tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager{$this->iListId}'), totalRows:$iCount, size: $iPageSize, filter: '$sOQL', extra_params: '$sExtraParams', select_mode: '$sSelectModeJS', displayKey: $sDisplayKey, columns: $sJSColumns, class_aliases: $sJSClassAliases $sCssCount});
|
||||
oTable.tablesorter( { $sHeaders widgets: ['myZebra', 'truncatedList']} ).tablesorterPager({container: $('#pager{$this->iListId}'), totalRows:$iCount, size: $iPageSize, filter: '$sOQL', extra_params: '$sExtraParams', select_mode: '$sSelectModeJS', displayKey: $sDisplayKey, table_id: '{$this->iListId}', columns: $sJSColumns, class_aliases: $sJSClassAliases $sCssCount});
|
||||
EOF
|
||||
);
|
||||
if ($sFakeSortList != '')
|
||||
@@ -577,8 +588,8 @@ EOF
|
||||
|
||||
public function UpdatePager(WebPage $oPage, $iDefaultPageSize, $iStart)
|
||||
{
|
||||
$iPageSize = ($iDefaultPageSize < 1) ? 1 : $iDefaultPageSize;
|
||||
$iPageIndex = 1 + floor($iStart / $iPageSize);
|
||||
$iPageSize = $iDefaultPageSize;
|
||||
$iPageIndex = 0;
|
||||
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
|
||||
if ($iDefaultPageSize < 1)
|
||||
@@ -936,4 +947,4 @@ class DataTableSettings implements Serializable
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,7 +500,10 @@ class DisplayBlock
|
||||
}
|
||||
$aAttribs =array(
|
||||
'group' => array('label' => $sGroupByLabel, 'description' => ''),
|
||||
'value' => array('label'=> Dict::S('UI:GroupBy:'.$sAggregationFunction), 'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr))
|
||||
'value' => array(
|
||||
'label' => Dict::S('UI:GroupBy:'.$sAggregationFunction),
|
||||
'description' => Dict::Format('UI:GroupBy:'.$sAggregationFunction.'+', $sAggregationAttr),
|
||||
),
|
||||
);
|
||||
$sFormat = isset($aExtraParams['format']) ? $aExtraParams['format'] : 'UI:Pagination:HeaderNoSelection';
|
||||
$sHtml .= $oPage->GetP(Dict::Format($sFormat, $iTotalCount));
|
||||
@@ -699,7 +702,7 @@ class DisplayBlock
|
||||
'breadcrumb_label' => MetaModel::GetName($this->m_oSet->GetClass()),
|
||||
'breadcrumb_max_count' => utils::GetConfig()->Get('breadcrumb.max_count'),
|
||||
'breadcrumb_instance_id' => MetaModel::GetConfig()->GetItopInstanceid(),
|
||||
'breadcrumb_icon' => utils::GetAbsoluteUrlAppRoot().'images/breadcrumb-search.png'
|
||||
'breadcrumb_icon' => utils::GetAbsoluteUrlAppRoot().'images/breadcrumb-search.png',
|
||||
));
|
||||
|
||||
$oPage->add_ready_script("$('body').trigger('update_history.itop', [$seventAttachedData])");
|
||||
@@ -1172,16 +1175,26 @@ EOF
|
||||
}
|
||||
if (($bAutoReload) && ($this->m_sStyle != 'search')) // Search form do NOT auto-reload
|
||||
{
|
||||
$sFilter = addslashes(str_replace('"', "'", $this->m_oFilter->serialize())); // Used either for asynchronous or auto_reload
|
||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode($aExtraParams))); // JSON encode, change the style of the quotes and escape them
|
||||
// Used either for asynchronous or auto_reload
|
||||
// does a json_encode twice to get a string usable as function parameter
|
||||
$sFilterBefore = $this->m_oFilter->serialize();
|
||||
$sFilter = json_encode($sFilterBefore);
|
||||
$sExtraParams = json_encode(json_encode($aExtraParams));
|
||||
|
||||
$oPage->add_script('if (typeof window.oAutoReloadBlock == "undefined") {
|
||||
window.oAutoReloadBlock = {};
|
||||
}
|
||||
if (typeof window.oAutoReloadBlock[\''.$sId.'\'] != "undefined") {
|
||||
clearInterval(window.oAutoReloadBlock[\''.$sId.'\']);
|
||||
}
|
||||
window.oAutoReloadBlock[\''.$sId.'\'] = setInterval("ReloadBlock(\''.$sId.'\', \''.$this->m_sStyle.'\', \"'.$sFilter.'\", \"'.$sExtraParams.'\")", '.$iReloadInterval.');');
|
||||
$oPage->add_script(
|
||||
<<<JS
|
||||
if (typeof window.oAutoReloadBlock == "undefined") {
|
||||
window.oAutoReloadBlock = {};
|
||||
}
|
||||
if (typeof window.oAutoReloadBlock['$sId'] != "undefined") {
|
||||
clearInterval(window.oAutoReloadBlock['$sId']);
|
||||
}
|
||||
|
||||
window.oAutoReloadBlock['$sId'] = setInterval(function() {
|
||||
ReloadBlock('$sId', '{$this->m_sStyle}', $sFilter, $sExtraParams);
|
||||
}, '$iReloadInterval');
|
||||
JS
|
||||
);
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
@@ -1719,6 +1732,7 @@ class MenuBlock extends DisplayBlock
|
||||
*/
|
||||
}
|
||||
$this->AddMenuSeparator($aActions);
|
||||
/** @var \iApplicationUIExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oSet->Rewind();
|
||||
@@ -1814,6 +1828,7 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
|
||||
$this->AddMenuSeparator($aActions);
|
||||
/** @var \iApplicationUIExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oSet->Rewind();
|
||||
|
||||
@@ -846,8 +846,8 @@ EOF
|
||||
{
|
||||
$sAuthUser = $_SESSION['auth_user'];
|
||||
UserRights::Login($sAuthUser); // Set the user's language
|
||||
$sOldPwd = utils::ReadPostedParam('old_pwd', '', false, 'raw_data');
|
||||
$sNewPwd = utils::ReadPostedParam('new_pwd', '', false, 'raw_data');
|
||||
$sOldPwd = utils::ReadPostedParam('old_pwd', '', 'raw_data');
|
||||
$sNewPwd = utils::ReadPostedParam('new_pwd', '', 'raw_data');
|
||||
if (UserRights::CanChangePassword() && ((!UserRights::CheckCredentials($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd))))
|
||||
{
|
||||
$oPage = self::NewLoginWebPage();
|
||||
|
||||
@@ -399,6 +399,7 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
||||
$aPlugInProperties = $aMatches[1];
|
||||
foreach($aPlugInProperties as $sPlugInClass)
|
||||
{
|
||||
/** @var \iApplicationUIExtension $oInstance */
|
||||
$oInstance = MetaModel::GetPlugins('iApplicationUIExtension', $sPlugInClass);
|
||||
if ($oInstance != null) // Safety check...
|
||||
{
|
||||
|
||||
@@ -208,6 +208,11 @@ class UIExtKeyWidget
|
||||
{
|
||||
// When there is only once choice, select it by default
|
||||
$sSelected = 'selected';
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$this->iId').attr('data-validate','dependencies');
|
||||
EOF
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -286,11 +286,13 @@ class UILinksWidgetDirect
|
||||
* @param DBObject $oCurrentObj
|
||||
* @param $aAlreadyLinked
|
||||
*
|
||||
* @param array $aPrefillFormParam
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked)
|
||||
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
|
||||
{
|
||||
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
|
||||
|
||||
@@ -333,6 +335,8 @@ class UILinksWidgetDirect
|
||||
|
||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||
$oFilter->SetInternalParams($aArgs);
|
||||
$aPrefillFormParam['filter'] = $oFilter;
|
||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||
}
|
||||
$oBlock = new DisplayBlock($oFilter, 'search', false);
|
||||
$sHtml .= $oBlock->GetDisplay($oPage, "SearchFormToAdd_{$this->sInputid}",
|
||||
@@ -359,13 +363,17 @@ class UILinksWidgetDirect
|
||||
|
||||
/**
|
||||
* Search for objects to be linked to the current object (i.e "remote" objects)
|
||||
*
|
||||
* @param WebPage $oP The page used for the output (usually an AjaxWebPage)
|
||||
* @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of $this->sLinkedClass
|
||||
* @param array $aAlreadyLinked Array of indentifiers of objects which are already linke to the current object (or about to be linked)
|
||||
* @param DBObject $oCurrentObj The object currently being edited... if known...
|
||||
* @throws Exception
|
||||
* @param array $aPrefillFormParam
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null)
|
||||
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null, $aPrefillFormParam = array())
|
||||
{
|
||||
if ($sRemoteClass == '')
|
||||
{
|
||||
@@ -395,16 +403,19 @@ class UILinksWidgetDirect
|
||||
$oFilter->AddCondition('id', $oCurrentObj->GetKey(), '!=');
|
||||
}
|
||||
}
|
||||
if (count($aAlreadyLinked) > 0)
|
||||
{
|
||||
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||
}
|
||||
if ($oCurrentObj != null)
|
||||
{
|
||||
$this->SetSearchDefaultFromContext($oCurrentObj, $oFilter);
|
||||
|
||||
$aArgs = array_merge($oCurrentObj->ToArgs('this'), $oFilter->GetInternalParams());
|
||||
$oFilter->SetInternalParams($aArgs);
|
||||
|
||||
$aPrefillFormParam['filter'] = $oFilter;
|
||||
$oCurrentObj->PrefillForm('search', $aPrefillFormParam);
|
||||
}
|
||||
if (count($aAlreadyLinked) > 0)
|
||||
{
|
||||
$oFilter->AddCondition('id', $aAlreadyLinked, 'NOTIN');
|
||||
}
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, "ResultsToAdd_{$this->sInputid}", array('menu' => false, 'cssCount'=> '#count_'.$this->sInputid , 'selection_mode' => true, 'table_id' => 'add_'.$this->sInputid)); // Don't display the 'Actions' menu on the results
|
||||
|
||||
@@ -133,14 +133,15 @@ class UILinksWidget
|
||||
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
||||
$aRow = array();
|
||||
$aFieldsMap = array();
|
||||
$iKey = 0;
|
||||
if(is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
||||
{
|
||||
$key = $linkObjOrId->GetKey();
|
||||
$iKey = $linkObjOrId->GetKey();
|
||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||
$sPrefix .= "[$key][";
|
||||
$sPrefix .= "[$iKey][";
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$key}";
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
|
||||
$aArgs['this'] = $linkObjOrId;
|
||||
|
||||
if($bReadOnly)
|
||||
@@ -154,7 +155,7 @@ class UILinksWidget
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$key\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$key\">";
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']';
|
||||
@@ -195,7 +196,30 @@ class UILinksWidget
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".($iUniqueId < 0 ? -$iUniqueId : $iUniqueId);
|
||||
$aArgs['this'] = $oNewLinkObj;
|
||||
$sInputValue = $iUniqueId > 0 ? "-$iUniqueId" : "$iUniqueId";
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">";
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"0\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">";
|
||||
|
||||
if ($iUniqueId > 0)
|
||||
{
|
||||
// Rows created with ajax call need OnLinkAdded call.
|
||||
//
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
PrepareWidgets();
|
||||
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rows added before loading the form don't have to call OnLinkAdded.
|
||||
// Listeners are already present and DOM is not recreated
|
||||
$iPositiveUniqueId = -$iUniqueId;
|
||||
$oP->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId}.AddLink($iPositiveUniqueId, $iRemoteObjKey);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.-$iUniqueId.']';
|
||||
@@ -207,20 +231,12 @@ class UILinksWidget
|
||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId /* id */, $sNameSuffix, 0, $aArgs).
|
||||
'</div></div></div>';
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
$oP->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue');
|
||||
EOF
|
||||
);
|
||||
}
|
||||
$sState = '';
|
||||
|
||||
// Rows created with ajax call need OnLinkAdded call.
|
||||
// Rows added before loading the form cannot call OnLinkAdded.
|
||||
if ($iUniqueId > 0)
|
||||
{
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
PrepareWidgets();
|
||||
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(!$bReadOnly)
|
||||
@@ -337,8 +353,19 @@ EOF
|
||||
$sHtmlValue .= "<input type=\"hidden\" id=\"{$sFormPrefix}{$this->m_iInputId}\">\n";
|
||||
$oValue->Rewind();
|
||||
$aForm = array();
|
||||
$iAddedId = 1; // Unique id for new links
|
||||
$aAddedLinks = array();
|
||||
$iAddedId = -1; // Unique id for new links
|
||||
|
||||
$sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
// Don't automatically launch the search if the table is huge
|
||||
$bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass);
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}', $sJSDoSearch);
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
EOF
|
||||
);
|
||||
|
||||
while($oCurrentLink = $oValue->Fetch())
|
||||
{
|
||||
// We try to retrieve the remote object as usual
|
||||
@@ -357,9 +384,7 @@ EOF
|
||||
|
||||
if ($oCurrentLink->IsNew())
|
||||
{
|
||||
$key = -($iAddedId++);
|
||||
$iUniqueId = -$key;
|
||||
$aAddedLinks[] = array('iAddedId' => $iUniqueId, 'iRemote' => $oCurrentLink->Get($this->m_sExtKeyToRemote));
|
||||
$key = $iAddedId--;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -368,24 +393,6 @@ EOF
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly);
|
||||
}
|
||||
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
||||
$sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
// Don't automatically launch the search if the table is huge
|
||||
$bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass);
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}', $sJSDoSearch);
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
EOF
|
||||
);
|
||||
|
||||
foreach ($aAddedLinks as $aAddedLink)
|
||||
{
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId}.AddLink({$aAddedLink['iAddedId']}, {$aAddedLink['iRemote']});
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
||||
$sHtmlValue .= " <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sRemoteClass))."\" onClick=\"oWidget{$this->m_iInputId}.AddObjects();\"><span id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_indicatorAdd\"></span></span>\n";
|
||||
|
||||
@@ -62,11 +62,11 @@ class utils
|
||||
{
|
||||
if (!file_exists($sParamFile))
|
||||
{
|
||||
throw new Exception("Could not find the parameter file: '$sParamFile'");
|
||||
throw new Exception("Could not find the parameter file: '".utils::HtmlEntities($sParamFile)."'");
|
||||
}
|
||||
if (!is_readable($sParamFile))
|
||||
{
|
||||
throw new Exception("Could not load parameter file: '$sParamFile'");
|
||||
throw new Exception("Could not load parameter file: '".utils::HtmlEntities($sParamFile)."'");
|
||||
}
|
||||
$sParams = file_get_contents($sParamFile);
|
||||
|
||||
@@ -273,79 +273,93 @@ class utils
|
||||
}
|
||||
return $retValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|string[] $value
|
||||
* @param string $sSanitizationFilter one of : integer, class, string, context_param, parameter, field_name,
|
||||
* transaction_id, parameter, raw_data
|
||||
*
|
||||
* @return string|string[]|bool boolean for :
|
||||
* * the 'class' filter (true if valid, false otherwise)
|
||||
* * if the filter fails (@see \filter_var())
|
||||
*
|
||||
* @since 2.5.2 2.6.0 new 'transaction_id' filter
|
||||
*/
|
||||
protected static function Sanitize_Internal($value, $sSanitizationFilter)
|
||||
{
|
||||
switch($sSanitizationFilter)
|
||||
switch ($sSanitizationFilter)
|
||||
{
|
||||
case 'integer':
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT);
|
||||
break;
|
||||
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT);
|
||||
break;
|
||||
|
||||
case 'class':
|
||||
$retValue = $value;
|
||||
if (!MetaModel::IsValidClass($value))
|
||||
{
|
||||
$retValue = false;
|
||||
}
|
||||
break;
|
||||
$retValue = $value;
|
||||
if (!MetaModel::IsValidClass($value))
|
||||
{
|
||||
$retValue = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
break;
|
||||
|
||||
$retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
|
||||
break;
|
||||
|
||||
case 'context_param':
|
||||
case 'parameter':
|
||||
case 'field_name':
|
||||
if (is_array($value))
|
||||
{
|
||||
$retValue = array();
|
||||
foreach($value as $key => $val)
|
||||
if (is_array($value))
|
||||
{
|
||||
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays
|
||||
if ($retValue[$key] === false)
|
||||
$retValue = array();
|
||||
foreach ($value as $key => $val)
|
||||
{
|
||||
$retValue = false;
|
||||
break;
|
||||
$retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays
|
||||
if ($retValue[$key] === false)
|
||||
{
|
||||
$retValue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch($sSanitizationFilter)
|
||||
else
|
||||
{
|
||||
case 'transaction_id':
|
||||
// same as parameter type but keep the dot character
|
||||
// see N°1835 : when using file transaction_id on Windows you get *.tmp tokens
|
||||
// it must be included at the regexp beginning otherwise you'll get an invalid character error
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
|
||||
break;
|
||||
switch ($sSanitizationFilter)
|
||||
{
|
||||
case 'transaction_id':
|
||||
// same as parameter type but keep the dot character
|
||||
// see N°1835 : when using file transaction_id on Windows you get *.tmp tokens
|
||||
// it must be included at the regexp beginning otherwise you'll get an invalid character error
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
array("options" => array("regexp" => '/^[\. A-Za-z0-9_=-]*$/')));
|
||||
break;
|
||||
|
||||
case 'parameter':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
|
||||
// characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
|
||||
break;
|
||||
case 'parameter':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=', '%3D, '%2B', '%2F'
|
||||
// characters are used in serialized filters (starting 2.5, only the url encoded versions are presents, but the "=" is kept for BC)
|
||||
break;
|
||||
|
||||
case 'field_name':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
|
||||
break;
|
||||
|
||||
case 'context_param':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options"=>array("regexp"=>'/^[ A-Za-z0-9_=%:+-]*$/')));
|
||||
break;
|
||||
|
||||
case 'field_name':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name
|
||||
break;
|
||||
|
||||
case 'context_param':
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/')));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'raw_data':
|
||||
$retValue = $value;
|
||||
$retValue = $value;
|
||||
// Do nothing
|
||||
}
|
||||
return $retValue;
|
||||
|
||||
return $retValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1171,7 +1185,7 @@ class utils
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get target configuration file name (including full path)
|
||||
* @return string target configuration file name (including full path)
|
||||
*/
|
||||
public static function GetConfigFilePath($sEnvironment = null)
|
||||
{
|
||||
@@ -1181,6 +1195,17 @@ class utils
|
||||
}
|
||||
return APPCONF.$sEnvironment.'/'.ITOP_CONFIG_FILE;
|
||||
}
|
||||
/**
|
||||
* @return string target configuration file name (including relative path)
|
||||
*/
|
||||
public static function GetConfigFilePathRelative($sEnvironment = null)
|
||||
{
|
||||
if (is_null($sEnvironment))
|
||||
{
|
||||
$sEnvironment = self::GetCurrentEnvironment();
|
||||
}
|
||||
return "conf/".$sEnvironment.'/'.ITOP_CONFIG_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the absolute URL to the modules root path
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
{
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"ext-mysql": "*",
|
||||
"ext-ldap": "*",
|
||||
"ext-mcrypt": "*",
|
||||
"ext-cli": "*",
|
||||
"ext-soap": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
@@ -13,6 +9,14 @@
|
||||
"ext-iconv": "*",
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Required to use the AttributeEncryptedString.",
|
||||
"ext-openssl": "Can be used as a polyfill if libsodium is not installed",
|
||||
"ext-mcrypt": "Can be used as a polyfill if either libsodium and openssl are not installed (libsodium and openssl are more secure)",
|
||||
"ext-ldap": "Required to use LDAP as an identity provider",
|
||||
"ext-posix": "Not required by the core, but some extensions uses it.",
|
||||
"ext-imap": "Required by the extension \"Mail to ticket automation\""
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "5.6.0"
|
||||
|
||||
3054
composer.lock
generated
Normal file
3054
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,13 +12,13 @@ You are welcome to create pull requests on any of those subjects:
|
||||
|
||||
* 🐛 `:bug:` bug fix
|
||||
* 🔒 `:lock:` security
|
||||
* 🌐 `:globe_with_meridians:` translation
|
||||
* 🌐 `:globe_with_meridians:` translation / i18n / l10n
|
||||
|
||||
If you want to implement a **new feature**, please [create a corresponding ticket](https://sourceforge.net/p/itop/tickets/new/) for review.
|
||||
If you ever want to begin implementation, do so in a fork, and add a link to the corresponding commits in the ticket.
|
||||
If you ever want to begin implementation, do so in a fork, and add a link to the corresponding commits in the ticket.
|
||||
|
||||
### License
|
||||
iTop is distributed under the AGPL-3.0 license (see the [license.txt] file),
|
||||
iTop is distributed under the AGPL-3.0 license (see the [license.txt] file),
|
||||
your code must comply with this license.
|
||||
|
||||
If you want to use another license, you may [create an extension][wiki new ext].
|
||||
@@ -33,28 +33,29 @@ TL;DR:
|
||||
> **create a fork from iTop main repository,
|
||||
> create a branch based on either release branch if present, or develop otherwise**
|
||||
|
||||
We are using the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branch model. That means we have in our repo those
|
||||
We are using the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branch model. That means we have in our repo those
|
||||
main branches:
|
||||
|
||||
- develop: ongoing development version
|
||||
- release/*: if present, that means we are working on a beta version
|
||||
- release/\*: if present, that means we are working on a beta version
|
||||
- master: previous stable version
|
||||
|
||||
For example, if no beta version is currently ongoing we could have:
|
||||
|
||||
- develop containing 2.8 version
|
||||
- master containing 2.7 version
|
||||
- develop containing future 2.8.0 version
|
||||
- master containing 2.7.x maintenance version
|
||||
|
||||
In this example, when 2.8 beta is shipped that will become:
|
||||
In this example, when 2.8.0-beta is shipped that will become:
|
||||
|
||||
- develop: 2.9 version
|
||||
- release/2.8: 2.8 beta
|
||||
- master: 2.7 version
|
||||
- develop: future 2.9.0 version
|
||||
- release/2.8: 2.8.0-beta
|
||||
- master: 2.7.x maintenance version
|
||||
|
||||
And when 2.8 final will be out:
|
||||
And when 2.8.0 final will be out:
|
||||
|
||||
- develop: 2.9 version
|
||||
- master: 2.8 version
|
||||
- develop: future 2.9.0 version
|
||||
- master: 2.8.x maintenance version
|
||||
- support/2.7 : 2.7.x maintenance version
|
||||
|
||||
|
||||
## Coding
|
||||
@@ -63,6 +64,10 @@ And when 2.8 final will be out:
|
||||
|
||||
Please follow [our guidelines](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Acoding_standards).
|
||||
|
||||
### 🌐 Translations
|
||||
|
||||
A [dedicated page](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Atranslation) is available in the official wiki.
|
||||
|
||||
### Tests
|
||||
|
||||
Please create tests that covers as much as possible the code you're submitting.
|
||||
@@ -75,7 +80,7 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
|
||||
* Use the present tense ("Add feature" not "Added feature")
|
||||
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
* Limit the first line to 72 characters or less
|
||||
* Please start the commit message with an applicable emoji (following the [Gitmoji guide](https://gitmoji.carloscuesta.me/).). For example :
|
||||
* Please start the commit message with an applicable emoji code (following the [Gitmoji guide](https://gitmoji.carloscuesta.me/)). For example :
|
||||
* 🌐 `:globe_with_meridians:` for translations
|
||||
* 🎨 `:art:` when improving the format/structure of the code
|
||||
* ⚡️ `:zap:` when improving performance
|
||||
@@ -150,7 +150,7 @@ abstract class AsyncTask extends DBObject
|
||||
public function GetRetryDelay($iErrorCode = null)
|
||||
{
|
||||
$iRetryDelay = 600;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries', array());
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries');
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
@@ -162,12 +162,13 @@ abstract class AsyncTask extends DBObject
|
||||
public function GetMaxRetries($iErrorCode = null)
|
||||
{
|
||||
$iMaxRetries = 0;
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries', array());
|
||||
$aRetries = MetaModel::GetConfig()->Get('async_task_retries');
|
||||
if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries))
|
||||
{
|
||||
$aConfig = $aRetries[get_class($this)];
|
||||
$iMaxRetries = $aConfig['max_retries'];
|
||||
}
|
||||
return $iMaxRetries;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -380,6 +381,6 @@ class AsyncSendEmail extends AsyncTask
|
||||
case EMAIL_SEND_ERROR:
|
||||
return "Failed: ".implode(', ', $aIssues);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -512,7 +512,7 @@ abstract class AttributeDefinition
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sDefault
|
||||
* @param string|null $sDefault if null, will return the attribute code replacing "_" by " "
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
@@ -1374,6 +1374,11 @@ class AttributeLinkedSet extends AttributeDefinition
|
||||
*/
|
||||
public function GetDefaultValue(DBObject $oHostObject = null)
|
||||
{
|
||||
if ($oHostObject === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$sLinkClass = $this->GetLinkedClass();
|
||||
$sExtKeyToMe = $this->GetExtKeyToMe();
|
||||
|
||||
@@ -3264,10 +3269,13 @@ class AttributeClassState extends AttributeString
|
||||
$sClass = $oHostObj->Get($sTargetClass);
|
||||
|
||||
$aAllowedStates = array();
|
||||
$aValues = MetaModel::EnumStates($sClass);
|
||||
foreach(array_keys($aValues) as $sState)
|
||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass)
|
||||
{
|
||||
$aAllowedStates[$sState] = $sState.' ('.MetaModel::GetStateLabel($sClass, $sState).')';
|
||||
$aValues = MetaModel::EnumStates($sChildClass);
|
||||
foreach (array_keys($aValues) as $sState)
|
||||
{
|
||||
$aAllowedStates[$sState] = $sState.' ('.MetaModel::GetStateLabel($sChildClass, $sState).')';
|
||||
}
|
||||
}
|
||||
return $aAllowedStates;
|
||||
}
|
||||
@@ -3286,9 +3294,15 @@ class AttributeClassState extends AttributeString
|
||||
{
|
||||
$sTargetClass = $this->Get('class_field');
|
||||
$sClass = $oHostObject->Get($sTargetClass);
|
||||
|
||||
$sHTML = '<span class="attribute-set-item" data-code="'.$sValue.'" data-label="'.$sValue.' ('.MetaModel::GetStateLabel($sClass, $sValue).')'.'" data-description="">'.$sValue.'</span>';
|
||||
return $sHTML;
|
||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass)
|
||||
{
|
||||
$aValues = MetaModel::EnumStates($sChildClass);
|
||||
if (in_array($sValue, $aValues))
|
||||
{
|
||||
$sHTML = '<span class="attribute-set-item" data-code="'.$sValue.'" data-label="'.$sValue.' ('.MetaModel::GetStateLabel($sChildClass, $sValue).')'.'" data-description="">'.$sValue.'</span>';
|
||||
return $sHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sValue;
|
||||
@@ -6242,6 +6256,15 @@ class AttributeExternalKey extends AttributeDBFieldVoid
|
||||
return $oFormField;
|
||||
}
|
||||
|
||||
public function GetAsHTML($sValue, $oHostObject = null, $bLocalize = true)
|
||||
{
|
||||
if (!is_null($oHostObject))
|
||||
{
|
||||
return $oHostObject->GetAsHTML($this->GetCode(), $oHostObject);
|
||||
}
|
||||
|
||||
return DBObject::MakeHyperLink($this->GetTargetClass(), $sValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6502,26 +6525,60 @@ class AttributeExternalField extends AttributeDefinition
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDefault
|
||||
*
|
||||
* @return string dict entry if defined, otherwise :
|
||||
* <ul>
|
||||
* <li>if field is a friendlyname then display the label of the ExternalKey
|
||||
* <li>the class hierarchy -> field name
|
||||
*
|
||||
* <p>For example, having this :
|
||||
*
|
||||
* <pre>
|
||||
* +---------------------+ +--------------------+ +--------------+
|
||||
* | Class A | | Class B | | Class C |
|
||||
* +---------------------+ +--------------------+ +--------------+
|
||||
* | foo <ExternalField>-------->c_id_friendly_name--------->friendlyname |
|
||||
* +---------------------+ +--------------------+ +--------------+
|
||||
* </pre>
|
||||
*
|
||||
* <p>The ExternalField foo points to a magical field that is brought by c_id ExternalKey in class B.
|
||||
*
|
||||
* <p>In the normal case the foo label would be : B -> C -> friendlyname<br>
|
||||
* But as foo is a friendlyname its label will be the same as the one on A.b_id field
|
||||
* This can be overrided with dict key Class:ClassA/Attribute:foo
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetLabel($sDefault = null)
|
||||
{
|
||||
$sLabelDefaultValue = '';
|
||||
$sLabel = parent::GetLabel($sLabelDefaultValue);
|
||||
if ($sLabelDefaultValue !== $sLabel)
|
||||
{
|
||||
return $sLabel;
|
||||
}
|
||||
|
||||
if ($this->IsFriendlyName())
|
||||
{
|
||||
// This will be used even if we are pointing to a friendlyname in a distance > 1
|
||||
// For example we can link to a magic friendlyname (like org_id_friendlyname)
|
||||
// If a specific label is needed, use a Dict key !
|
||||
// See N°2174
|
||||
$sKeyAttCode = $this->Get("extkey_attcode");
|
||||
$oExtKeyAttDef = MetaModel::GetAttributeDef($this->GetHostClass(), $sKeyAttCode);
|
||||
$sLabel = $oExtKeyAttDef->GetLabel($this->m_sCode);
|
||||
|
||||
return $sLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sLabel = parent::GetLabel('');
|
||||
if (strlen($sLabel) == 0)
|
||||
{
|
||||
$oRemoteAtt = $this->GetExtAttDef();
|
||||
$sLabel = $oRemoteAtt->GetLabel($this->m_sCode);
|
||||
$oKeyAtt = $this->GetKeyAttDef();
|
||||
$sKeyLabel = $oKeyAtt->GetLabel($this->GetKeyAttCode());
|
||||
$sLabel = "{$sKeyLabel}->{$sLabel}";
|
||||
}
|
||||
}
|
||||
|
||||
$oRemoteAtt = $this->GetExtAttDef();
|
||||
$sLabel = $oRemoteAtt->GetLabel($this->m_sCode);
|
||||
$oKeyAtt = $this->GetKeyAttDef();
|
||||
$sKeyLabel = $oKeyAtt->GetLabel($this->GetKeyAttCode());
|
||||
$sLabel = "{$sKeyLabel}->{$sLabel}";
|
||||
|
||||
return $sLabel;
|
||||
}
|
||||
@@ -7813,6 +7870,87 @@ class AttributeStopWatch extends AttributeDefinition
|
||||
throw new CoreException("Unknown item code '$sItemCode' for attribute ".$this->GetHostClass().'::'.$this->GetCode());
|
||||
}
|
||||
|
||||
|
||||
public function GetSubItemSearchType($sItemCode)
|
||||
{
|
||||
switch ($sItemCode)
|
||||
{
|
||||
case 'timespent':
|
||||
return static::SEARCH_WIDGET_TYPE_NUMERIC; //seconds
|
||||
case 'started':
|
||||
case 'laststart':
|
||||
case 'stopped':
|
||||
return static::SEARCH_WIDGET_TYPE_DATE_TIME; //timestamp
|
||||
}
|
||||
|
||||
foreach($this->ListThresholds() as $iThreshold => $aFoo)
|
||||
{
|
||||
$sThPrefix = $iThreshold.'_';
|
||||
if (substr($sItemCode, 0, strlen($sThPrefix)) == $sThPrefix)
|
||||
{
|
||||
// The current threshold is concerned
|
||||
$sThresholdCode = substr($sItemCode, strlen($sThPrefix));
|
||||
switch ($sThresholdCode)
|
||||
{
|
||||
case 'deadline':
|
||||
return static::SEARCH_WIDGET_TYPE_DATE_TIME; //timestamp
|
||||
case 'passed':
|
||||
case 'triggered':
|
||||
return static::SEARCH_WIDGET_TYPE_ENUM; //booleans, used in conjuction with GetSubItemAllowedValues and IsSubItemNullAllowed
|
||||
case 'overrun':
|
||||
return static::SEARCH_WIDGET_TYPE_NUMERIC; //seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static::SEARCH_WIDGET_TYPE_RAW;
|
||||
}
|
||||
|
||||
public function GetSubItemAllowedValues($sItemCode, $aArgs = array(), $sContains = '')
|
||||
{
|
||||
foreach($this->ListThresholds() as $iThreshold => $aFoo)
|
||||
{
|
||||
$sThPrefix = $iThreshold.'_';
|
||||
if (substr($sItemCode, 0, strlen($sThPrefix)) == $sThPrefix)
|
||||
{
|
||||
// The current threshold is concerned
|
||||
$sThresholdCode = substr($sItemCode, strlen($sThPrefix));
|
||||
switch ($sThresholdCode)
|
||||
{
|
||||
case 'passed':
|
||||
case 'triggered':
|
||||
return array(
|
||||
0 => $this->GetBooleanLabel(0),
|
||||
1 => $this->GetBooleanLabel(1),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function IsSubItemNullAllowed($sItemCode, $bDefaultValue)
|
||||
{
|
||||
foreach($this->ListThresholds() as $iThreshold => $aFoo)
|
||||
{
|
||||
$sThPrefix = $iThreshold.'_';
|
||||
if (substr($sItemCode, 0, strlen($sThPrefix)) == $sThPrefix)
|
||||
{
|
||||
// The current threshold is concerned
|
||||
$sThresholdCode = substr($sItemCode, strlen($sThPrefix));
|
||||
switch ($sThresholdCode)
|
||||
{
|
||||
case 'passed':
|
||||
case 'triggered':
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bDefaultValue;
|
||||
}
|
||||
|
||||
protected function GetBooleanLabel($bValue)
|
||||
{
|
||||
$sDictKey = $bValue ? 'yes' : 'no';
|
||||
@@ -8162,9 +8300,39 @@ class AttributeStopWatch extends AttributeDefinition
|
||||
*/
|
||||
class AttributeSubItem extends AttributeDefinition
|
||||
{
|
||||
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
|
||||
/**
|
||||
* Return the search widget type corresponding to this attribute
|
||||
* the computation is made by AttributeStopWatch::GetSubItemSearchType
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetSearchType()
|
||||
{
|
||||
/** @var AttributeStopWatch $oParent */
|
||||
$oParent = $this->GetTargetAttDef();
|
||||
|
||||
static public function ListExpectedParams()
|
||||
return $oParent->GetSubItemSearchType($this->Get('item_code'));
|
||||
}
|
||||
|
||||
public function GetAllowedValues($aArgs = array(), $sContains = '')
|
||||
{
|
||||
/** @var AttributeStopWatch $oParent */
|
||||
$oParent = $this->GetTargetAttDef();
|
||||
|
||||
return $oParent->GetSubItemAllowedValues($this->Get('item_code'), $aArgs, $sContains);
|
||||
}
|
||||
|
||||
public function IsNullAllowed()
|
||||
{
|
||||
/** @var AttributeStopWatch $oParent */
|
||||
$oParent = $this->GetTargetAttDef();
|
||||
|
||||
$bDefaultValue = parent::IsNullAllowed();
|
||||
|
||||
return $oParent->IsSubItemNullAllowed($this->Get('item_code'), $bDefaultValue);
|
||||
}
|
||||
|
||||
static public function ListExpectedParams()
|
||||
{
|
||||
return array_merge(parent::ListExpectedParams(), array('target_attcode', 'item_code'));
|
||||
}
|
||||
@@ -9655,14 +9823,27 @@ class AttributeTagSet extends AttributeSet
|
||||
{
|
||||
$aJson['partial_values'] = array();
|
||||
$aJson['orig_value'] = array();
|
||||
$aJson['added'] = array();
|
||||
$aJson['removed'] = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aJson['partial_values'] = $oValue->GetModified();
|
||||
$aJson['orig_value'] = array_merge($oValue->GetValues(), $oValue->GetModified());
|
||||
$aJson['added'] = $oValue->GetAdded();
|
||||
$aJson['removed'] = $oValue->GetRemoved();
|
||||
|
||||
if ($oValue->DisplayPartial())
|
||||
{
|
||||
// For bulk updates
|
||||
$aJson['partial_values'] = $oValue->GetModified();
|
||||
}
|
||||
else
|
||||
{
|
||||
// For simple updates
|
||||
$aJson['partial_values'] = array();
|
||||
}
|
||||
}
|
||||
$aJson['added'] = array();
|
||||
$aJson['removed'] = array();
|
||||
|
||||
|
||||
$iMaxTags = $this->GetMaxItems();
|
||||
$aJson['max_items_allowed'] = $iMaxTags;
|
||||
|
||||
@@ -332,6 +332,18 @@ class BulkChange
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DBObject $oTargetObj
|
||||
* @param array $aRowData
|
||||
* @param array $aErrors
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
protected function PrepareObject(&$oTargetObj, $aRowData, &$aErrors)
|
||||
{
|
||||
$aResults = array();
|
||||
@@ -477,7 +489,9 @@ class BulkChange
|
||||
if (!$oAttDef->IsWritable() && in_array($sAttCode, $this->m_aReconcilKeys)){ continue; }
|
||||
|
||||
$aReasons = array();
|
||||
$iFlags = $oTargetObj->GetAttributeFlags($sAttCode, $aReasons);
|
||||
$iFlags = ($oTargetObj->IsNew())
|
||||
? $oTargetObj->GetInitialStateAttributeFlags($sAttCode, $aReasons)
|
||||
: $oTargetObj->GetAttributeFlags($sAttCode, $aReasons);
|
||||
if ( (($iFlags & OPT_ATT_READONLY) == OPT_ATT_READONLY) && ( $oTargetObj->Get($sAttCode) != $aRowData[$iCol]) )
|
||||
{
|
||||
$aErrors[$sAttCode] = Dict::Format('UI:CSVReport-Value-Issue-Readonly', $sAttCode, $oTargetObj->Get($sAttCode), $aRowData[$iCol]);
|
||||
|
||||
@@ -188,6 +188,16 @@ abstract class CMDBObject extends DBObject
|
||||
self::$m_oCurrChange->DBInsert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function RecordObjCreation()
|
||||
{
|
||||
// Delete any existing change tracking about the current object (IDs can be reused due to InnoDb bug; see TRAC #886)
|
||||
@@ -206,6 +216,7 @@ abstract class CMDBObject extends DBObject
|
||||
MetaModel::PurgeData($oFilter);
|
||||
|
||||
parent::RecordObjCreation();
|
||||
|
||||
$oMyChangeOp = MetaModel::NewObject("CMDBChangeOpCreate");
|
||||
$oMyChangeOp->Set("objclass", get_class($this));
|
||||
$oMyChangeOp->Set("objkey", $this->GetKey());
|
||||
@@ -232,9 +243,17 @@ abstract class CMDBObject extends DBObject
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sAttCode
|
||||
* @param string $sAttCode
|
||||
* @param $original Original value
|
||||
* @param $value Current value
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function RecordAttChange($sAttCode, $original, $value)
|
||||
{
|
||||
@@ -438,6 +457,14 @@ abstract class CMDBObject extends DBObject
|
||||
/**
|
||||
* @param array $aValues
|
||||
* @param array $aOrigValues
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function RecordAttChanges(array $aValues, array $aOrigValues)
|
||||
{
|
||||
@@ -669,6 +696,8 @@ abstract class CMDBObject extends DBObject
|
||||
* TODO: investigate how to get rid of this class that was made to workaround some language limitation... or a poor design!
|
||||
*
|
||||
* @package iTopORM
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CMDBObjectSet extends DBObjectSet
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
define('ITOP_APPLICATION', 'iTop');
|
||||
define('ITOP_APPLICATION_SHORT', 'iTop');
|
||||
define('ITOP_VERSION', '2.6.0');
|
||||
define('ITOP_VERSION', '2.6.2');
|
||||
define('ITOP_REVISION', 'svn');
|
||||
define('ITOP_BUILD_DATE', '$WCNOW$');
|
||||
|
||||
@@ -72,6 +72,9 @@ define('DEFAULT_ENCRYPTION_LIB', 'Mcrypt'); // We'll define the best encryption
|
||||
* configuration data (this class cannot not be localized, because it is responsible for loading the dictionaries)
|
||||
*
|
||||
* @package iTopORM
|
||||
*
|
||||
* @see \MetaModel::GetConfig() to get the config, if the metamodel was already loaded
|
||||
* @see utils::GetConfig() to load config from the current env, if metamodel is not loaded
|
||||
*/
|
||||
class Config
|
||||
{
|
||||
|
||||
@@ -151,7 +151,8 @@ class CoreCannotSaveObjectException extends CoreException
|
||||
|
||||
if (count($this->aIssues) == 1)
|
||||
{
|
||||
$sContent .= " <span>{$this->aIssues[0]}</span>";
|
||||
$sIssue = reset($this->aIssues);
|
||||
$sContent .= " <span>{$sIssue}</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,22 @@
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
//
|
||||
|
||||
// Dev hack for disabling the some query build optimizations (Folding/Merging)
|
||||
/** @internal Dev hack for disabling some query build optimizations (Folding/Merging) */
|
||||
define('ENABLE_OPT', true);
|
||||
|
||||
/**
|
||||
* A search over a DBObject
|
||||
*
|
||||
* This is the most common search cases, the other class representing a search is DBUnionSearch.
|
||||
* For clarity purpose, since only the constructor vary between DBObjectSearch and DBUnionSearch, all the API is documented on the common ancestor: DBSearch
|
||||
* Please refer to DBSearch's documentation
|
||||
*
|
||||
* @package iTopORM
|
||||
* @phpdoc-tuning-exclude-inherited this tag prevent PHPdoc from displaying inherited methods. This is done in order to force the API doc. location into DBSearch only.
|
||||
* @api
|
||||
* @see DBSearch
|
||||
* @see DBUnionSearch
|
||||
*/
|
||||
class DBObjectSearch extends DBSearch
|
||||
{
|
||||
private $m_aClasses; // queried classes (alias => class name), the first item is the class corresponding to this filter (the rest is coming from subfilters)
|
||||
@@ -29,11 +42,23 @@ class DBObjectSearch extends DBSearch
|
||||
private $m_aPointingTo;
|
||||
private $m_aReferencedBy;
|
||||
|
||||
// By default, some information may be hidden to the current user
|
||||
// But it may happen that we need to disable that feature
|
||||
/**
|
||||
* @var bool whether or not some information should be hidden to the current user. Default to false == hide information.
|
||||
* @see AllowAllData()
|
||||
*/
|
||||
protected $m_bAllowAllData = false;
|
||||
protected $m_bDataFiltered = false;
|
||||
|
||||
/**
|
||||
* DBObjectSearch constructor.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param string|null $sClassAlias
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($sClass, $sClassAlias = null)
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -524,7 +549,7 @@ class DBObjectSearch extends DBSearch
|
||||
/**
|
||||
* Specify a condition on external keys or link sets
|
||||
* @param string $sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively
|
||||
* Example: infra_list->ci_id->location_id->country
|
||||
* Example: infra_list->ci_id->location_id->country
|
||||
* @param $value
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
@@ -1642,7 +1667,7 @@ class DBObjectSearch extends DBSearch
|
||||
// Query caching
|
||||
//
|
||||
$sOqlAPCCacheId = null;
|
||||
if (self::$m_bQueryCacheEnabled)
|
||||
if (self::$m_bQueryCacheEnabled && $bCanCache)
|
||||
{
|
||||
// Warning: using directly the query string as the key to the hash array can FAIL if the string
|
||||
// is long and the differences are only near the end... so it's safer (but not bullet proof?)
|
||||
@@ -2344,8 +2369,8 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the expression for the class and its subclasses (if finalclass = 'subclass' ...)
|
||||
* Simplifies the final expression by grouping classes having the same expression
|
||||
* Get the expression for the class and its subclasses (if finalclass = 'subclass' ...)
|
||||
* Simplifies the final expression by grouping classes having the same expression
|
||||
* @param $sClass
|
||||
* @param $sAttCode
|
||||
* @return \FunctionExpression|mixed|null
|
||||
|
||||
@@ -27,9 +27,13 @@ require_once('dbobjectiterator.php');
|
||||
|
||||
|
||||
/**
|
||||
* A set of persistent objects, could be heterogeneous as long as the objects in the set have a common ancestor class
|
||||
* A set of persistent objects
|
||||
*
|
||||
* Created against a DBObjectSearch with additional information not relevant for the DBObjectSearch (ie: order, limit, ...)
|
||||
* This set could be heterogeneous as long as the objects in the set have a common ancestor class.
|
||||
*
|
||||
* @package iTopORM
|
||||
* @api
|
||||
*/
|
||||
class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
@@ -81,6 +85,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
/**
|
||||
* Create a new set based on a Search definition.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param DBSearch $oFilter The search filter defining the objects which are part of the set (multiple columns/objects per row are supported)
|
||||
* @param array $aOrderBy Array of '[<classalias>.]attcode' => bAscending
|
||||
@@ -110,6 +116,9 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_object($this->m_oSQLResult))
|
||||
@@ -119,6 +128,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Exception
|
||||
@@ -145,6 +156,9 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->m_oFilter = $this->m_oFilter->DeepClone();
|
||||
@@ -158,6 +172,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
/**
|
||||
* Called when unserializing a DBObjectSet
|
||||
* @internal
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
@@ -168,18 +183,30 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param $bShow
|
||||
*/
|
||||
public function SetShowObsoleteData($bShow)
|
||||
{
|
||||
$this->m_oFilter->SetShowObsoleteData($bShow);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return bool
|
||||
*/
|
||||
public function GetShowObsoleteData()
|
||||
{
|
||||
return $this->m_oFilter->GetShowObsoleteData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the subset of attributes to load (for each class of objects) before performing the SQL query for retrieving the rows from the DB
|
||||
* Specify the subset of attributes to load
|
||||
* this subset is specified for each class of objects,
|
||||
* this has to be done before the actual fetch.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param array $aAttToLoad Format: alias => array of attribute_codes
|
||||
*
|
||||
@@ -262,6 +289,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
/**
|
||||
* Create a set (in-memory) containing just the given object
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param \DBobject $oObject
|
||||
*
|
||||
* @return \DBObjectSet The singleton set
|
||||
@@ -278,6 +307,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
/**
|
||||
* Create an empty set (in-memory), for the given class (and its subclasses) of objects
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $sClass The class (or an ancestor) for the objects to be added in this set
|
||||
*
|
||||
* @return \DBObjectSet The empty set
|
||||
@@ -297,6 +328,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
/**
|
||||
* Create a set (in-memory) with just one column (i.e. one object per row) and filled with the given array of objects
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $sClass The class of the objects (must be a common ancestor to all objects in the set)
|
||||
* @param array $aObjects The list of objects to add into the set
|
||||
*
|
||||
@@ -314,9 +347,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
/**
|
||||
* Create a set in-memory with several classes of objects per row (with one alias per "column")
|
||||
*
|
||||
* Limitation:
|
||||
* **Limitation:**
|
||||
* The filter/OQL query representing such a set can not be rebuilt (only the first column will be taken into account)
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array $aClasses Format: array of (alias => class)
|
||||
* @param array $aObjects Format: array of (array of (classalias => object))
|
||||
*
|
||||
@@ -345,6 +380,9 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param $oObject
|
||||
* @param string $sLinkSetAttCode
|
||||
* @param string $sExtKeyToRemote
|
||||
@@ -371,11 +409,15 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all as array of DBObject
|
||||
*
|
||||
* Note: After calling this method, the set cursor will be at the end of the set. You might want to rewind it.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param bool $bWithId
|
||||
*
|
||||
* @return array
|
||||
* @return DBObject[]
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
@@ -401,7 +443,14 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* Fetch all as a structured array
|
||||
*
|
||||
* Unlike ToArray, ToArrayOfValues return the objects as an array.
|
||||
* Only the scalar values will be presents (see AttributeDefinition::IsScalar())
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @return array[]
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
@@ -773,6 +822,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
* May actually perform the SQL query SELECT COUNT... if the set was not previously loaded, or loaded with a
|
||||
* SetLimit
|
||||
*
|
||||
* @api
|
||||
* @return int The total number of rows for this set.
|
||||
*
|
||||
* @throws \CoreException
|
||||
@@ -796,11 +846,13 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
||||
}
|
||||
|
||||
/** Check if the count exceeds a given limit
|
||||
/**
|
||||
* Check if the count exceeds a given limit
|
||||
*
|
||||
* @param $iLimit
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
@@ -831,11 +883,13 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
return ($iCount > $iLimit);
|
||||
}
|
||||
|
||||
/** Count only up to the given limit
|
||||
/**
|
||||
* Count only up to the given limit
|
||||
*
|
||||
* @param $iLimit
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
@@ -877,9 +931,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the object (with the given class alias) at the current position in the set and move the cursor to the next position.
|
||||
* Fetch an object (with the given class alias) at the current position in the set and move the cursor to the next position.
|
||||
*
|
||||
* @param string $sRequestedClassAlias The class alias to fetch (if there are several objects/classes per row)
|
||||
* @api
|
||||
*
|
||||
* @param string $sRequestedClassAlias The class alias to fetch (defaults to the first selected class)
|
||||
*
|
||||
* @return \DBObject The fetched object or null when at the end
|
||||
*
|
||||
@@ -933,6 +989,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
/**
|
||||
* Fetch the whole row of objects (if several classes have been specified in the query) and move the cursor to the next position
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @return array An associative with the format 'classAlias' => $oObj representing the current row of the set. Returns null when at the end.
|
||||
*
|
||||
* @throws \CoreException
|
||||
@@ -981,8 +1039,10 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
/**
|
||||
* Position the cursor (for iterating in the set) to the first position (equivalent to Seek(0))
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function Rewind()
|
||||
{
|
||||
@@ -1200,9 +1260,9 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
* @param \DBObjectSet $oObjectSet
|
||||
*
|
||||
* @return \DBObjectSet The "delta" set.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function CreateDelta(DBObjectSet $oObjectSet)
|
||||
{
|
||||
@@ -1445,6 +1505,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
/**
|
||||
* Helper function to perform a custom sort of a hash array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function HashCountComparison($a, $b) // Sort descending on 'count'
|
||||
{
|
||||
@@ -1464,6 +1526,11 @@ function HashCountComparison($a, $b) // Sort descending on 'count'
|
||||
* LIMITATIONS:
|
||||
* - only DBObjectSets with one column (i.e. one class of object selected) are supported
|
||||
* - the first set must be the one loaded from the database
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @package iTopORM
|
||||
*
|
||||
*/
|
||||
class DBObjectSetComparator
|
||||
{
|
||||
@@ -1508,6 +1575,8 @@ class DBObjectSetComparator
|
||||
/**
|
||||
* Builds the lists of fingerprints and initializes internal structures, if it was not already done
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @throws \CoreException
|
||||
*/
|
||||
protected function ComputeFingerprints()
|
||||
@@ -1557,6 +1626,9 @@ class DBObjectSetComparator
|
||||
|
||||
/**
|
||||
* Tells if the sets are equivalent or not. Returns as soon as the first difference is found.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return boolean true if the set have an equivalent content, false otherwise
|
||||
*
|
||||
* @throws \CoreException
|
||||
@@ -1603,8 +1675,10 @@ class DBObjectSetComparator
|
||||
/**
|
||||
* Get the list of differences between the two sets. In ordeer to write back into the database only the minimum changes
|
||||
* THE FIRST SET MUST BE THE ONE LOADED FROM THE DATABASE
|
||||
* Returns a hash: 'added' => DBObject(s), 'removed' => DBObject(s), 'modified' => DBObjects(s)
|
||||
* @return array
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return array 'added' => DBObject(s), 'removed' => DBObject(s), 'modified' => DBObjects(s)
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \CoreException
|
||||
@@ -1659,7 +1733,9 @@ class DBObjectSetComparator
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpr to clone (in memory) an object and to apply to it the values taken from a second object
|
||||
* Helper to clone (in memory) an object and to apply to it the values taken from a second object
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param \DBObject $oObjToClone
|
||||
* @param \DBObject $oObjWithValues
|
||||
@@ -1682,4 +1758,4 @@ class DBObjectSetComparator
|
||||
}
|
||||
return $oObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,24 +22,35 @@ require_once('dbunionsearch.class.php');
|
||||
|
||||
/**
|
||||
* An object search
|
||||
*
|
||||
*
|
||||
* DBSearch provides an API that leverage the possibility to construct a search against iTop's persisted objects.
|
||||
* In order to do so, it let you declare the classes you want to fetch, the conditions you want to apply, ...
|
||||
*
|
||||
* Note: in the ancient times of iTop, a search was named after DBObjectSearch.
|
||||
* When the UNION has been introduced, it has been decided to:
|
||||
* - declare a hierarchy of search classes, with two leafs :
|
||||
* - one class to cope with a single query (A JOIN B... WHERE...)
|
||||
* - and the other to cope with several queries (query1 UNION query2)
|
||||
* - in order to preserve forward/backward compatibility of the existing modules
|
||||
* - keep the name of DBObjectSearch even if it a little bit confusing
|
||||
* - do not provide a type-hint for function parameters defined in the modules
|
||||
* - leave the statements DBObjectSearch::FromOQL in the modules, though DBSearch is more relevant
|
||||
* When the UNION has been introduced, it has been decided to:
|
||||
* * declare a hierarchy of search classes : `DBObjectSearch` & `DBUnionSearch`
|
||||
* * DBObjectSearch cope with single query (A JOIN B... WHERE...)
|
||||
* * DBUnionSearch cope with several queries (query1 UNION query2)
|
||||
* * in order to preserve forward/backward compatibility of the existing modules
|
||||
* * keep the name of DBObjectSearch even if it a little bit confusing
|
||||
* * do not provide a type-hint for function parameters defined in the modules
|
||||
* * leave the statements DBObjectSearch::FromOQL in the modules, though DBSearch is more relevant
|
||||
*
|
||||
* @copyright Copyright (C) 2015-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* @package iTopORM
|
||||
* @api
|
||||
* @see DBObjectSearch::__construct()
|
||||
* @see DBUnionSearch::__construct()
|
||||
*/
|
||||
|
||||
abstract class DBSearch
|
||||
{
|
||||
/** @internal */
|
||||
const JOIN_POINTING_TO = 0;
|
||||
/** @internal */
|
||||
const JOIN_REFERENCED_BY = 1;
|
||||
|
||||
protected $m_bNoContextParameters = false;
|
||||
@@ -47,14 +58,23 @@ abstract class DBSearch
|
||||
protected $m_bArchiveMode = false;
|
||||
protected $m_bShowObsoleteData = true;
|
||||
|
||||
/**
|
||||
* DBSearch constructor.
|
||||
*
|
||||
* @api
|
||||
* @see DBSearch::FromOQL()
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->Init();
|
||||
}
|
||||
|
||||
/**
|
||||
* called by the constructor
|
||||
* @internal Set the obsolete and archive modes to the default ones
|
||||
*/
|
||||
protected function Init()
|
||||
{
|
||||
// Set the obsolete and archive modes to the default ones
|
||||
$this->m_bArchiveMode = utils::IsArchiveMode();
|
||||
$this->m_bShowObsoleteData = true;
|
||||
}
|
||||
@@ -62,6 +82,8 @@ abstract class DBSearch
|
||||
/**
|
||||
* Perform a deep clone (as opposed to "clone" which does copy a reference to the underlying objects)
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return \DBSearch
|
||||
**/
|
||||
public function DeepClone()
|
||||
@@ -69,22 +91,62 @@ abstract class DBSearch
|
||||
return unserialize(serialize($this)); // Beware this serializes/unserializes the search and its parameters as well
|
||||
}
|
||||
|
||||
/**
|
||||
* whether or not some information should be hidden to the current user.
|
||||
*
|
||||
* @api
|
||||
* @see IsAllDataAllowed()
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function AllowAllData();
|
||||
|
||||
/**
|
||||
* Current state of AllowAllData
|
||||
*
|
||||
* @internal
|
||||
* @see AllowAllData()
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function IsAllDataAllowed();
|
||||
|
||||
/**
|
||||
* Should the archives be fetched
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param $bEnable
|
||||
*/
|
||||
public function SetArchiveMode($bEnable)
|
||||
{
|
||||
$this->m_bArchiveMode = $bEnable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return bool
|
||||
*/
|
||||
public function GetArchiveMode()
|
||||
{
|
||||
return $this->m_bArchiveMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the obsolete data be fetched
|
||||
*
|
||||
* @internal
|
||||
* @param $bShow
|
||||
*/
|
||||
public function SetShowObsoleteData($bShow)
|
||||
{
|
||||
$this->m_bShowObsoleteData = $bShow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return bool
|
||||
*/
|
||||
public function GetShowObsoleteData()
|
||||
{
|
||||
if ($this->m_bArchiveMode || $this->IsAllDataAllowed())
|
||||
@@ -99,14 +161,36 @@ abstract class DBSearch
|
||||
return $bRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function NoContextParameters() {$this->m_bNoContextParameters = true;}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return bool
|
||||
*/
|
||||
public function HasContextParameters() {return $this->m_bNoContextParameters;}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $sPluginClass
|
||||
* @param $sProperty
|
||||
* @param $value
|
||||
*/
|
||||
public function SetModifierProperty($sPluginClass, $sProperty, $value)
|
||||
{
|
||||
$this->m_aModifierProperties[$sPluginClass][$sProperty] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $sPluginClass
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function GetModifierProperties($sPluginClass)
|
||||
{
|
||||
if (array_key_exists($sPluginClass, $this->m_aModifierProperties))
|
||||
@@ -119,18 +203,44 @@ abstract class DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param $sAlias
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GetClassName($sAlias);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GetClass();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GetClassAlias();
|
||||
|
||||
/**
|
||||
* Change the class (only subclasses are supported as of now, because the conditions must fit the new class)
|
||||
* Defaults to the first selected class (most of the time it is also the first joined class
|
||||
*/
|
||||
* Change the class
|
||||
*
|
||||
* Defaults to the first selected class (most of the time it is also the first joined class
|
||||
* only subclasses are supported as of now, because the conditions must fit the new class
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract public function ChangeClass($sNewClass, $sAlias = null);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GetSelectedClasses();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param array $aSelectedClasses array of aliases
|
||||
* @throws CoreException
|
||||
*/
|
||||
@@ -139,64 +249,207 @@ abstract class DBSearch
|
||||
/**
|
||||
* Change any alias of the query tree
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param $sOldName
|
||||
* @param $sNewName
|
||||
* @return bool True if the alias has been found and changed
|
||||
*/
|
||||
abstract public function RenameAlias($sOldName, $sNewName);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function IsAny();
|
||||
|
||||
/**
|
||||
* @deprecated use ToOQL() instead
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function Describe(){return 'deprecated - use ToOQL() instead';}
|
||||
/**
|
||||
* @deprecated use ToOQL() instead
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function DescribeConditionPointTo($sExtKeyAttCode, $aPointingTo){return 'deprecated - use ToOQL() instead';}
|
||||
/**
|
||||
* @deprecated use ToOQL() instead
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function DescribeConditionRefBy($sForeignClass, $sForeignExtKeyAttCode){return 'deprecated - use ToOQL() instead';}
|
||||
/**
|
||||
* @deprecated use ToOQL() instead
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function DescribeConditionRelTo($aRelInfo){return 'deprecated - use ToOQL() instead';}
|
||||
/**
|
||||
* @deprecated use ToOQL() instead
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function DescribeConditions(){return 'deprecated - use ToOQL() instead';}
|
||||
/**
|
||||
* @deprecated use ToOQL() instead
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function __DescribeHTML(){return 'deprecated - use ToOQL() instead';}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function ResetCondition();
|
||||
|
||||
/**
|
||||
* add $oExpression as a OR
|
||||
*
|
||||
* @api
|
||||
* @see DBSearch::AddConditionExpression()
|
||||
*
|
||||
* @param Expression $oExpression
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function MergeConditionExpression($oExpression);
|
||||
|
||||
/**
|
||||
* add $oExpression as a AND
|
||||
*
|
||||
* @api
|
||||
* @see DBSearch::MergeConditionExpression()
|
||||
*
|
||||
* @param Expression $oExpression
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function AddConditionExpression($oExpression);
|
||||
|
||||
/**
|
||||
* Condition on the friendlyname
|
||||
*
|
||||
* Restrict the query to only the corresponding selected class' friendlyname
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $sName the desired friendlyname
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function AddNameCondition($sName);
|
||||
|
||||
/**
|
||||
* Add a condition
|
||||
*
|
||||
* This is the simplest way to express a AND condition. For complex use cases, use MergeConditionExpression or AddConditionExpression instead
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sFilterCode
|
||||
* @param mixed $value
|
||||
* @param string $sOpCode operator to use : '=' (default), '!=', 'IN', 'NOT IN'
|
||||
*
|
||||
* @throws \CoreException
|
||||
*
|
||||
*/
|
||||
abstract public function AddCondition($sFilterCode, $value, $sOpCode = null);
|
||||
/**
|
||||
* Specify a condition on external keys or link sets
|
||||
* @param sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively
|
||||
* Example: infra_list->ci_id->location_id->country
|
||||
* @param value The value to match (can be an array => IN(val1, val2...)
|
||||
* @param mixed $value The value to match (can be an array => IN(val1, val2...)
|
||||
* @return void
|
||||
*/
|
||||
abstract public function AddConditionAdvanced($sAttSpec, $value);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param string $sFullText
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function AddCondition_FullText($sFullText);
|
||||
|
||||
/**
|
||||
* Perform a join, the remote class being matched by the mean of its primary key
|
||||
*
|
||||
* The join is performed
|
||||
* * from the searched class, based on the $sExtKeyAttCode attribute
|
||||
* * against the oFilter searched class, based on its primary key
|
||||
* Note : if several classes have already being joined (SELECT a join b ON...), the first joined class (a in the example) is considered as being the searched class.
|
||||
*
|
||||
* @api
|
||||
* @see AddCondition_ReferencedBy()
|
||||
*
|
||||
* @param DBObjectSearch $oFilter
|
||||
* @param $sExtKeyAttCode
|
||||
* @param int $iOperatorCode
|
||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
||||
* @param string $sExtKeyAttCode
|
||||
* @param int $iOperatorCode the comparison operator to use. For the list of all possible values, see the constant defined in core/oql/oqlquery.class.inc.php
|
||||
* @param array|null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed in the newly attached oFilter (in case of collisions between the two filters)
|
||||
*
|
||||
* @throws CoreException
|
||||
* @throws CoreWarning
|
||||
*/
|
||||
abstract public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null);
|
||||
|
||||
/**
|
||||
* Inverse operation of AddCondition_PointingTo
|
||||
*
|
||||
* The join is performed
|
||||
* * from the olFilter searched class, based on the $sExtKeyAttCode attribute
|
||||
* * against the searched class, based on its primary key
|
||||
* Note : if several classes have already being joined (SELECT a join b ON...), the first joined class (a in the example) is considered as being the searched class.
|
||||
*
|
||||
*
|
||||
* @api
|
||||
* @see AddCondition_PointingTo()
|
||||
*
|
||||
* @param DBObjectSearch $oFilter
|
||||
* @param $sForeignExtKeyAttCode
|
||||
* @param int $iOperatorCode
|
||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
||||
* @param array|null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed in the newly attached oFilter (in case of collisions between the two filters)
|
||||
*/
|
||||
abstract public function AddCondition_ReferencedBy(DBObjectSearch $oFilter, $sForeignExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null);
|
||||
|
||||
/**
|
||||
* Filter the result
|
||||
*
|
||||
* The filter is performed by returning only the values in common with the given $oFilter
|
||||
* The impact on the resulting query performance/viability can be significant.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param DBSearch $oFilter
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function Intersect(DBSearch $oFilter);
|
||||
|
||||
/**
|
||||
* @param DBSearch $oFilter
|
||||
* @param integer $iDirection
|
||||
* @param string $sExtKeyAttCode
|
||||
* @param integer $iOperatorCode
|
||||
* @param array &$RealisasingMap Map of aliases from the attached query, that could have been renamed by the optimization process
|
||||
* @return DBSearch
|
||||
*/
|
||||
/**
|
||||
* Perform a join
|
||||
*
|
||||
* The join is performed against $oFilter selected class using $sExtKeyAttCode of the current selected class
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param DBSearch $oFilter The join is performed against $oFilter selected class
|
||||
* @param integer $iDirection can be either DBSearch::JOIN_POINTING_TO or DBSearch::JOIN_REFERENCED_BY
|
||||
* @param string $sExtKeyAttCode The join is performed against $sExtKeyAttCode wetheir it is compared aginst the current DBSearch or $oFilter depend of $iDirection
|
||||
* @param integer $iOperatorCode See DBSearch::AddCondition_PointingTo()
|
||||
* @param array|null $aRealiasingMap Map of aliases from the attached query, that could have been renamed by the optimization process
|
||||
*
|
||||
* @return DBSearch
|
||||
* @throws CoreException
|
||||
* @throws CoreWarning
|
||||
*/
|
||||
public function Join(DBSearch $oFilter, $iDirection, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
||||
{
|
||||
$oSourceFilter = $this->DeepClone();
|
||||
@@ -231,21 +484,68 @@ abstract class DBSearch
|
||||
return $oRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the internal params.
|
||||
*
|
||||
* If any params pre-existed, they are lost.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param mixed[string] $aParams array of mixed params index by string name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function SetInternalParams($aParams);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GetInternalParams();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param bool $bExcludeMagicParams
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function GetQueryParams($bExcludeMagicParams = true);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function ListConstantFields();
|
||||
|
||||
/**
|
||||
* Turn the parameters (:xxx) into scalar values in order to easily
|
||||
* serialize a search
|
||||
* Turn the parameters (:xxx) into scalar values
|
||||
*
|
||||
* The goal is to easily serialize a search
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array $aArgs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function ApplyParameters($aArgs);
|
||||
|
||||
/**
|
||||
* Convert a query to a string representation
|
||||
*
|
||||
* This operation can be revert back to a DBSearch using DBSearch::unserialize()
|
||||
*
|
||||
* @api
|
||||
* @see DBSearch::unserialize()
|
||||
*
|
||||
* @param bool $bDevelopParams
|
||||
* @param array $aContextParams
|
||||
*
|
||||
* @return false|string
|
||||
* @throws ArchivedObjectException
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function serialize($bDevelopParams = false, $aContextParams = array())
|
||||
{
|
||||
$aQueryParams = $this->GetQueryParams();
|
||||
@@ -293,6 +593,10 @@ abstract class DBSearch
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a serialized query back to an instance of DBSearch
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sValue Serialized OQL query
|
||||
*
|
||||
* @return \DBSearch
|
||||
@@ -336,11 +640,13 @@ abstract class DBSearch
|
||||
/**
|
||||
* Create a new DBObjectSearch from $oSearch with a new alias $sAlias
|
||||
*
|
||||
* Note : This has not be tested with UNION queries.
|
||||
* @internal Note : This has not be tested with UNION queries.
|
||||
*
|
||||
* @param DBSearch $oSearch
|
||||
* @param string $sAlias
|
||||
* @param string $sAlias
|
||||
*
|
||||
* @return DBObjectSearch
|
||||
* @throws CoreException
|
||||
*/
|
||||
static public function CloneWithAlias(DBSearch $oSearch, $sAlias)
|
||||
{
|
||||
@@ -349,12 +655,37 @@ abstract class DBSearch
|
||||
return $oSearchWithAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the DBSearch to an OQL representation
|
||||
*
|
||||
* @api
|
||||
* @see DBSearch::FromOQL()
|
||||
*
|
||||
* @param bool $bDevelopParams
|
||||
* @param null $aContextParams
|
||||
* @param bool $bWithAllowAllFlag
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function ToOQL($bDevelopParams = false, $aContextParams = null, $bWithAllowAllFlag = false);
|
||||
|
||||
static protected $m_aOQLQueries = array();
|
||||
|
||||
// Do not filter out depending on user rights
|
||||
// In particular when we are currently in the process of evaluating the user rights...
|
||||
/**
|
||||
* FromOQL with AllowAllData enabled
|
||||
*
|
||||
* The goal is to not filter out depending on user rights.
|
||||
* In particular when we are currently in the process of evaluating the user rights...
|
||||
*
|
||||
* @internal
|
||||
* @see DBSearch::FromOQL()
|
||||
*
|
||||
* @param string $sQuery
|
||||
* @param null $aParams
|
||||
*
|
||||
* @return DBSearch
|
||||
* @throws OQLException
|
||||
*/
|
||||
static public function FromOQL_AllData($sQuery, $aParams = null)
|
||||
{
|
||||
$oRes = self::FromOQL($sQuery, $aParams);
|
||||
@@ -363,9 +694,19 @@ abstract class DBSearch
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sQuery
|
||||
* @param array $aParams
|
||||
* @return self
|
||||
* Create a new DBSearch from the given OQL.
|
||||
*
|
||||
* This is the simplest way to create a DBSearch.
|
||||
* For almost every cases, this is the easiest way.
|
||||
*
|
||||
* @api
|
||||
* @see DBSearch::ToOQL()
|
||||
*
|
||||
* @param string $sQuery The OQL to convert to a DBSearch
|
||||
* @param mixed[string] $aParams array of <mixed> params index by <string> name
|
||||
*
|
||||
* @return DBObjectSearch|DBUnionSearch
|
||||
*
|
||||
* @throws OQLException
|
||||
*/
|
||||
static public function FromOQL($sQuery, $aParams = null)
|
||||
@@ -442,14 +783,20 @@ abstract class DBSearch
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the result has an array structure.
|
||||
*
|
||||
* Alternative to object mapping: the data are transfered directly into an array
|
||||
* This is 10 times faster than creating a set of objects, and makes sense when optimization is required
|
||||
* But this speed comes at the cost of not obtaining the easy to manipulates DBObject instances but simple array structure.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array $aColumns
|
||||
* @param array $aColumns The columns you'd like to fetch.
|
||||
* @param array $aOrderBy Array of '[<classalias>.]attcode' => bAscending
|
||||
* @param array $aArgs
|
||||
*
|
||||
* @return array|void
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
@@ -506,7 +853,11 @@ abstract class DBSearch
|
||||
protected static $m_aQueryStructCache = array();
|
||||
|
||||
|
||||
/** Generate a Group By SQL request from a search
|
||||
/**
|
||||
* Generate a Group By SQL query from the current search
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array $aArgs
|
||||
* @param array $aGroupByExpr array('alias' => Expression)
|
||||
* @param bool $bExcludeNullValues
|
||||
@@ -514,7 +865,9 @@ abstract class DBSearch
|
||||
* @param array $aOrderBy array('alias' => bool) true = ASC false = DESC
|
||||
* @param int $iLimitCount
|
||||
* @param int $iLimitStart
|
||||
*
|
||||
* @return string SQL query generated
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function MakeGroupByQuery($aArgs, $aGroupByExpr, $bExcludeNullValues = false, $aSelectExpr = array(), $aOrderBy = array(), $iLimitCount = 0, $iLimitStart = 0)
|
||||
@@ -590,6 +943,10 @@ abstract class DBSearch
|
||||
|
||||
|
||||
/**
|
||||
* Generate a SQL query from the current search
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param array|hash $aOrderBy Array of '[<classalias>.]attcode' => bAscending
|
||||
* @param array $aArgs
|
||||
* @param null $aAttToLoad
|
||||
@@ -684,9 +1041,33 @@ abstract class DBSearch
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
protected abstract function IsDataFiltered();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return mixed
|
||||
*/
|
||||
protected abstract function SetDataFiltered();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $aOrderBy
|
||||
* @param $aArgs
|
||||
* @param $aAttToLoad
|
||||
* @param $aExtendedDataSpec
|
||||
* @param $iLimitCount
|
||||
* @param $iLimitStart
|
||||
* @param $bGetCount
|
||||
* @param null $aGroupByExpr
|
||||
* @param null $aSelectExpr
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr = null, $aSelectExpr = null)
|
||||
{
|
||||
$oSearch = $this;
|
||||
@@ -727,18 +1108,46 @@ abstract class DBSearch
|
||||
return $oSQLQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $aAttToLoad
|
||||
* @param $bGetCount
|
||||
* @param null $aGroupByExpr
|
||||
* @param null $aSelectedClasses
|
||||
* @param null $aSelectExpr
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public abstract function GetSQLQueryStructure(
|
||||
$aAttToLoad, $bGetCount, $aGroupByExpr = null, $aSelectedClasses = null, $aSelectExpr = null
|
||||
);
|
||||
|
||||
/**
|
||||
* Get the current search conditions
|
||||
*
|
||||
* @internal
|
||||
* @see DBSearch $m_oSearchCondition
|
||||
*
|
||||
* @return \Expression
|
||||
*/
|
||||
public abstract function GetCriteria();
|
||||
|
||||
/**
|
||||
* Shortcut to add efficient IN condition
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param $sFilterCode
|
||||
* @param $aValues
|
||||
* @param bool $bPositiveMatch if true a `IN` is performed, if false, a `NOT IN` is performed
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public abstract function AddConditionForInOperatorUsingParam($sFilterCode, $aValues, $bPositiveMatch = true);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return string a unique param name
|
||||
*/
|
||||
protected function GenerateUniqueParamName() {
|
||||
@@ -759,36 +1168,78 @@ abstract class DBSearch
|
||||
protected static $m_bIndentQueries = false;
|
||||
protected static $m_bOptimizeQueries = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function StartDebugQuery()
|
||||
{
|
||||
$aBacktrace = debug_backtrace();
|
||||
self::$m_bDebugQuery = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function StopDebugQuery()
|
||||
{
|
||||
self::$m_bDebugQuery = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param bool $bEnabled
|
||||
* @param bool $bUseAPC
|
||||
* @param int $iTimeToLive
|
||||
*/
|
||||
public static function EnableQueryCache($bEnabled, $bUseAPC, $iTimeToLive = 3600)
|
||||
{
|
||||
self::$m_bQueryCacheEnabled = $bEnabled;
|
||||
self::$m_bUseAPCCache = $bUseAPC;
|
||||
self::$m_iQueryCacheTTL = $iTimeToLive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param $bEnabled
|
||||
*/
|
||||
public static function EnableQueryTrace($bEnabled)
|
||||
{
|
||||
self::$m_bTraceQueries = $bEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param $bEnabled
|
||||
*/
|
||||
public static function EnableQueryIndentation($bEnabled)
|
||||
{
|
||||
self::$m_bIndentQueries = $bEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param $bEnabled
|
||||
*/
|
||||
public static function EnableOptimizeQuery($bEnabled)
|
||||
{
|
||||
self::$m_bOptimizeQueries = $bEnabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $aOrderBy
|
||||
* @param $aArgs
|
||||
* @param $aAttToLoad
|
||||
* @param $aExtendedDataSpec
|
||||
* @param $iLimitCount
|
||||
* @param $iLimitStart
|
||||
* @param $bGetCount
|
||||
* @param $sSql
|
||||
*
|
||||
* @throws MySQLException
|
||||
*/
|
||||
protected function AddQueryTraceSelect($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $sSql)
|
||||
{
|
||||
if (self::$m_bTraceQueries)
|
||||
@@ -808,7 +1259,16 @@ abstract class DBSearch
|
||||
self::AddQueryTrace($aQueryData, $sOql, $sSql);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $aArgs
|
||||
* @param $aGroupByExpr
|
||||
* @param $sSql
|
||||
*
|
||||
* @throws MySQLException
|
||||
*/
|
||||
protected function AddQueryTraceGroupBy($aArgs, $aGroupByExpr, $sSql)
|
||||
{
|
||||
if (self::$m_bTraceQueries)
|
||||
@@ -824,6 +1284,15 @@ abstract class DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @param $aQueryData
|
||||
* @param $sOql
|
||||
* @param $sSql
|
||||
*
|
||||
* @throws MySQLException
|
||||
*/
|
||||
protected static function AddQueryTrace($aQueryData, $sOql, $sSql)
|
||||
{
|
||||
if (self::$m_bTraceQueries)
|
||||
@@ -854,6 +1323,9 @@ abstract class DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function RecordQueryTrace()
|
||||
{
|
||||
if (!self::$m_bTraceQueries)
|
||||
@@ -914,6 +1386,10 @@ abstract class DBSearch
|
||||
file_put_contents($sAllQueries, $sLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param $value
|
||||
*/
|
||||
protected static function DbgTrace($value)
|
||||
{
|
||||
if (!self::$m_bDebugQuery)
|
||||
@@ -949,7 +1425,9 @@ abstract class DBSearch
|
||||
|
||||
/**
|
||||
* Experimental!
|
||||
* todo: implement the change tracking
|
||||
* @todo implement the change tracking
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param $bArchive
|
||||
* @throws Exception
|
||||
@@ -1025,6 +1503,9 @@ abstract class DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function UpdateContextFromUser()
|
||||
{
|
||||
$this->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
|
||||
@@ -18,10 +18,21 @@
|
||||
|
||||
|
||||
/**
|
||||
* A union of DBObjectSearches
|
||||
* A union of DBObjectSearches
|
||||
*
|
||||
* This search class represent an union over a collection of DBObjectSearch.
|
||||
* For clarity purpose, since only the constructor vary between DBObjectSearch and DBUnionSearch, all the API is documented on the common ancestor: DBSearch
|
||||
* Please refer to DBSearch's documentation
|
||||
*
|
||||
* @copyright Copyright (C) 2015-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*
|
||||
* @package iTopORM
|
||||
* @phpdoc-tuning-exclude-inherited this tag prevent PHPdoc from displaying inherited methods. This is done in order to force the API doc. location into DBSearch only.
|
||||
* @api
|
||||
* @see DBSearch
|
||||
* @see DBObjectSearch
|
||||
*/
|
||||
|
||||
class DBUnionSearch extends DBSearch
|
||||
@@ -29,6 +40,15 @@ class DBUnionSearch extends DBSearch
|
||||
protected $aSearches; // source queries
|
||||
protected $aSelectedClasses; // alias => classes (lowest common ancestors) computed at construction
|
||||
|
||||
/**
|
||||
* DBUnionSearch constructor.
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param $aSearches
|
||||
*
|
||||
* @throws CoreException
|
||||
*/
|
||||
public function __construct($aSearches)
|
||||
{
|
||||
if (count ($aSearches) == 0)
|
||||
|
||||
@@ -1270,6 +1270,7 @@ class DisplayableGraph extends SimpleGraph
|
||||
|
||||
$oPdf->SetAutoPageBreak(true, $fBreakMargin);
|
||||
$oPdf->SetAlpha(1);
|
||||
$oPdf->SetTextColor(0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -234,19 +234,28 @@ class EMail
|
||||
$oDOMDoc = new DOMDocument();
|
||||
$oDOMDoc->preserveWhitespace = true;
|
||||
@$oDOMDoc->loadHTML('<?xml encoding="UTF-8"?>'.$this->m_aData['body']['body']); // For loading HTML chunks where the character set is not specified
|
||||
|
||||
|
||||
$oXPath = new DOMXPath($oDOMDoc);
|
||||
$sXPath = "//img[@data-img-id]";
|
||||
$sXPath = '//img[@'.InlineImage::DOM_ATTR_ID.']';
|
||||
$oImagesList = $oXPath->query($sXPath);
|
||||
|
||||
|
||||
if ($oImagesList->length != 0)
|
||||
{
|
||||
foreach($oImagesList as $oImg)
|
||||
{
|
||||
$iAttId = $oImg->getAttribute('data-img-id');
|
||||
$iAttId = $oImg->getAttribute(InlineImage::DOM_ATTR_ID);
|
||||
$oAttachment = MetaModel::GetObject('InlineImage', $iAttId, false, true /* Allow All Data */);
|
||||
if ($oAttachment)
|
||||
{
|
||||
$sImageSecret = $oImg->getAttribute('data-img-secret');
|
||||
$sAttachmentSecret = $oAttachment->Get('secret');
|
||||
if ($sImageSecret !== $sAttachmentSecret)
|
||||
{
|
||||
// @see N°1921
|
||||
// If copying from another iTop we could get an IMG pointing to an InlineImage with wrong secret
|
||||
continue;
|
||||
}
|
||||
|
||||
$oDoc = $oAttachment->Get('contents');
|
||||
$oSwiftImage = new Swift_Image($oDoc->GetData(), $oDoc->GetFileName(), $oDoc->GetMimeType());
|
||||
$sCid = $this->m_oMessage->embed($oSwiftImage);
|
||||
|
||||
@@ -78,6 +78,7 @@ EOF;
|
||||
}
|
||||
EOF;
|
||||
|
||||
SetupUtils::builddir(dirname($sFilePath));
|
||||
file_put_contents($sFilePath, $content);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,10 +243,16 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
{
|
||||
// Regular urls
|
||||
$sUrlPattern = utils::GetConfig()->Get('url_validation_pattern');
|
||||
|
||||
// Mailto urls
|
||||
$sMailtoPattern = '(mailto:(' . utils::GetConfig()->Get('email_validation_pattern') . ')(?:\?(?:subject|body)=([a-zA-Z0-9+\$_.-]*)(?:&(?:subject|body)=([a-zA-Z0-9+\$_.-]*))?)?)';
|
||||
|
||||
$sPattern = $sUrlPattern . '|' . $sMailtoPattern;
|
||||
// Notification placeholders
|
||||
// eg. $this->caller_id$, $this->hyperlink()$, $this->hyperlink(portal)$, $APP_URL$, $MODULES_URL$, ...
|
||||
// Note: Authorize both $xxx$ and %24xxx%24 as the latter one is encoded when used in HTML attributes (eg. a[href])
|
||||
$sPlaceholderPattern = '(\$|%24)[\w-]*(->[\w]*(\([\w-]*?\))?)?(\$|%24)';
|
||||
|
||||
$sPattern = $sUrlPattern . '|' . $sMailtoPattern . '|' . $sPlaceholderPattern;
|
||||
$sPattern = '/'.str_replace('/', '\/', $sPattern).'/i';
|
||||
self::$aAttrsWhiteList['href'] = $sPattern;
|
||||
}
|
||||
@@ -261,7 +267,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
// We have to transform that into <p><br></p> (which is how Thunderbird implements empty lines)
|
||||
// Unfortunately, DOMDocument::loadHTML does not take the tag namespaces into account (once loaded there is no way to know if the tag did have a namespace)
|
||||
// therefore we have to do the transformation upfront
|
||||
$sHTML = preg_replace('@<o:p>\s*</o:p>@', '<br>', $sHTML);
|
||||
$sHTML = preg_replace('@<o:p>(\s| )*</o:p>@', '<br>', $sHTML);
|
||||
|
||||
@$this->oDoc->loadHTML('<?xml encoding="UTF-8"?>'.$sHTML); // For loading HTML chunks where the character set is not specified
|
||||
|
||||
@@ -348,7 +354,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
$this->CleanNode($oNode);
|
||||
if (($oNode instanceof DOMElement) && (strtolower($oNode->tagName) == 'img'))
|
||||
{
|
||||
$this->ProcessImage($oNode);
|
||||
InlineImage::ProcessImageTag($oNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,24 +365,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an extra attribute data-img-id for images which are based on an actual InlineImage
|
||||
* so that we can later reconstruct the full "src" URL when needed
|
||||
* @param DOMNode $oElement
|
||||
*/
|
||||
protected function ProcessImage(DOMNode $oElement)
|
||||
{
|
||||
$sSrc = $oElement->getAttribute('src');
|
||||
$sDownloadUrl = str_replace(array('.', '?'), array('\.', '\?'), INLINEIMAGE_DOWNLOAD_URL); // Escape . and ?
|
||||
$sUrlPattern = '|'.$sDownloadUrl.'([0-9]+)&s=([0-9a-f]+)|';
|
||||
if (preg_match($sUrlPattern, $sSrc, $aMatches))
|
||||
{
|
||||
$oElement->setAttribute('data-img-id', $aMatches[1]);
|
||||
$oElement->setAttribute('data-img-secret', $aMatches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function CleanStyle($sStyle)
|
||||
{
|
||||
$aAllowedStyles = array();
|
||||
|
||||
@@ -27,6 +27,11 @@ define('INLINEIMAGE_DOWNLOAD_URL', 'pages/ajax.document.php?operation=download_i
|
||||
|
||||
class InlineImage extends DBObject
|
||||
{
|
||||
/** @var string attribute to be added to IMG tags to contain ID */
|
||||
const DOM_ATTR_ID = 'data-img-id';
|
||||
/** @var string attribute to be added to IMG tags to contain secret */
|
||||
const DOM_ATTR_SECRET = 'data-img-secret';
|
||||
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -178,18 +183,19 @@ class InlineImage extends DBObject
|
||||
$oInlineImage->DBUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IssueLog::Error('InlineImage: Error during FinalizeInlineImages(), no transaction ID for object '.get_class($oObject).'#'.$oObject->GetKey().'.');
|
||||
|
||||
IssueLog::Error('|- Call stack:');
|
||||
$oException = new Exception();
|
||||
$sStackTrace = $oException->getTraceAsString();
|
||||
IssueLog::Error($sStackTrace);
|
||||
|
||||
IssueLog::Error('|- POST vars:');
|
||||
IssueLog::Error(print_r($_POST, true));
|
||||
}
|
||||
// For tracing issues with Inline Images... but beware not all updates are interactive, so this trace happens when creating objects non-interactively (REST, Synchro...)
|
||||
// else
|
||||
// {
|
||||
// IssueLog::Error('InlineImage: Error during FinalizeInlineImages(), no transaction ID for object '.get_class($oObject).'#'.$oObject->GetKey().'.');
|
||||
//
|
||||
// IssueLog::Error('|- Call stack:');
|
||||
// $oException = new Exception();
|
||||
// $sStackTrace = $oException->getTraceAsString();
|
||||
// IssueLog::Error($sStackTrace);
|
||||
//
|
||||
// IssueLog::Error('|- POST vars:');
|
||||
// IssueLog::Error(print_r($_POST, true));
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,7 +226,8 @@ class InlineImage extends DBObject
|
||||
$aNeedles = array();
|
||||
$aReplacements = array();
|
||||
// Find img tags with an attribute data-img-id
|
||||
if (preg_match_all('/<img ([^>]*)data-img-id="([0-9]+)"([^>]*)>/i', $sHtml, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
|
||||
if (preg_match_all('/<img ([^>]*)'.self::DOM_ATTR_ID.'="([0-9]+)"([^>]*)>/i',
|
||||
$sHtml, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().INLINEIMAGE_DOWNLOAD_URL;
|
||||
foreach($aMatches as $aImgInfo)
|
||||
@@ -242,6 +249,42 @@ class InlineImage extends DBObject
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an extra attribute data-img-id for images which are based on an actual InlineImage
|
||||
* so that we can later reconstruct the full "src" URL when needed
|
||||
*
|
||||
* @param \DOMElement $oElement
|
||||
*/
|
||||
public static function ProcessImageTag(DOMElement $oElement)
|
||||
{
|
||||
$sSrc = $oElement->getAttribute('src');
|
||||
$sDownloadUrl = str_replace(array('.', '?'), array('\.', '\?'), INLINEIMAGE_DOWNLOAD_URL); // Escape . and ?
|
||||
$sUrlPattern = '|'.$sDownloadUrl.'([0-9]+)&s=([0-9a-f]+)|';
|
||||
$bIsInlineImage = preg_match($sUrlPattern, $sSrc, $aMatches);
|
||||
if (!$bIsInlineImage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
$iInlineImageId = $aMatches[1];
|
||||
$sInlineIMageSecret = $aMatches[2];
|
||||
|
||||
$sAppRoot = utils::GetAbsoluteUrlAppRoot();
|
||||
$sAppRootPattern = '/^'.preg_quote($sAppRoot, '/').'/';
|
||||
$bIsSameItop = preg_match($sAppRootPattern, $sSrc);
|
||||
if (!$bIsSameItop)
|
||||
{
|
||||
// @see N°1921
|
||||
// image from another iTop should be treated as external images
|
||||
$oElement->removeAttribute(self::DOM_ATTR_ID);
|
||||
$oElement->removeAttribute(self::DOM_ATTR_SECRET);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$oElement->setAttribute(self::DOM_ATTR_ID, $iInlineImageId);
|
||||
$oElement->setAttribute(self::DOM_ATTR_SECRET, $sInlineIMageSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the javascript fragment - to be added to "on document ready" - to adjust (on the fly) the width on Inline Images
|
||||
*/
|
||||
|
||||
@@ -97,8 +97,9 @@ define('MYSQL_ENGINE', 'innodb');
|
||||
|
||||
|
||||
/**
|
||||
* (API) The objects definitions as well as their mapping to the database
|
||||
* The objects definitions as well as their mapping to the database
|
||||
*
|
||||
* @api
|
||||
* @package iTopORM
|
||||
*/
|
||||
abstract class MetaModel
|
||||
@@ -528,13 +529,15 @@ abstract class MetaModel
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param bool $bClassDefinitionOnly if true then will only return properties defined in the specified class on not the properties
|
||||
* from its parent classes
|
||||
*
|
||||
* @return array
|
||||
* @return array rule id as key, rule properties as value
|
||||
* @throws \CoreException
|
||||
*
|
||||
* @since 2.6 N°659 uniqueness constraint
|
||||
* @see #SetUniquenessRuleRootClass that fixes a specific 'root_class' property to know which class is root per rule
|
||||
*/
|
||||
final public static function GetUniquenessRules($sClass)
|
||||
final public static function GetUniquenessRules($sClass, $bClassDefinitionOnly = false)
|
||||
{
|
||||
if (!isset(self::$m_aClassParams[$sClass]))
|
||||
{
|
||||
@@ -548,6 +551,11 @@ abstract class MetaModel
|
||||
$aCurrentUniquenessRules = self::$m_aClassParams[$sClass]['uniqueness_rules'];
|
||||
}
|
||||
|
||||
if ($bClassDefinitionOnly)
|
||||
{
|
||||
return $aCurrentUniquenessRules;
|
||||
}
|
||||
|
||||
$sParentClass = self::GetParentClass($sClass);
|
||||
if ($sParentClass)
|
||||
{
|
||||
@@ -581,6 +589,22 @@ abstract class MetaModel
|
||||
return $aCurrentUniquenessRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRootClass
|
||||
* @param string $sRuleId
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @since 2.6.1 N°1918 (sous les pavés, la plage) initialize in 'root_class' property the class that has the first
|
||||
* definition of the rule in the hierarchy
|
||||
*/
|
||||
final private static function SetUniquenessRuleRootClass($sRootClass, $sRuleId)
|
||||
{
|
||||
foreach (self::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_ALL) as $sClass)
|
||||
{
|
||||
self::$m_aClassParams[$sClass]['uniqueness_rules'][$sRuleId]['root_class'] = $sClass;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRuleId
|
||||
* @param string $sLeafClassName
|
||||
@@ -608,6 +632,49 @@ abstract class MetaModel
|
||||
return $sFirstClassWithRuleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRootClass
|
||||
* @param string $sRuleId
|
||||
*
|
||||
* @return string[] child classes with the rule disabled, and that are concrete classes
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @since 2.6.1 N°1968 (soyez réalistes, demandez l'impossible)
|
||||
*/
|
||||
final public static function GetChildClassesWithDisabledUniquenessRule($sRootClass, $sRuleId)
|
||||
{
|
||||
$aClassesWithDisabledRule = array();
|
||||
foreach (self::EnumChildClasses($sRootClass, ENUM_CHILD_CLASSES_EXCLUDETOP) as $sChildClass)
|
||||
{
|
||||
if (array_key_exists($sChildClass, $aClassesWithDisabledRule))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!array_key_exists('uniqueness_rules', self::$m_aClassParams[$sChildClass]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!array_key_exists($sRuleId, self::$m_aClassParams[$sChildClass]['uniqueness_rules']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self::$m_aClassParams[$sChildClass]['uniqueness_rules'][$sRuleId]['disabled'] === true)
|
||||
{
|
||||
$aDisabledClassChildren = self::EnumChildClasses($sChildClass, ENUM_CHILD_CLASSES_ALL);
|
||||
foreach ($aDisabledClassChildren as $sDisabledClassChild)
|
||||
{
|
||||
if (!self::IsAbstract($sDisabledClassChild))
|
||||
{
|
||||
$aClassesWithDisabledRule[] = $sDisabledClassChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aClassesWithDisabledRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aRuleProperties
|
||||
*
|
||||
@@ -1167,6 +1234,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return array
|
||||
@@ -1219,9 +1287,12 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param string $sAttCode
|
||||
* @param bool $bExtended
|
||||
* Check it the given attribute exists in the specified class
|
||||
*
|
||||
* @api
|
||||
* @param string $sClass Class name
|
||||
* @param string $sAttCode Attribute code
|
||||
* @param bool $bExtended Allow the extended syntax: extkey_id->remote_attcode
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
@@ -1275,6 +1346,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
@@ -1290,6 +1362,9 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given class name is actually a persistent class
|
||||
*
|
||||
* @api
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return bool
|
||||
@@ -1564,17 +1639,20 @@ abstract class MetaModel
|
||||
/**
|
||||
* array of ("classname" => array filterdef)
|
||||
*
|
||||
* @deprecated
|
||||
* @var array
|
||||
*/
|
||||
private static $m_aFilterDefs = array();
|
||||
/**
|
||||
* array of ("classname" => array of ("attcode"=>"sourceclass"))
|
||||
*
|
||||
* @deprecated
|
||||
* @var array
|
||||
*/
|
||||
private static $m_aFilterOrigins = array();
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return mixed
|
||||
@@ -1587,6 +1665,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
@@ -1604,6 +1683,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
@@ -1622,6 +1702,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
@@ -1639,6 +1720,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
@@ -1656,6 +1738,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
@@ -1674,6 +1757,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sClass
|
||||
* @param string $sFilterCode
|
||||
* @param string $sOpCode
|
||||
@@ -1693,6 +1777,7 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param string $sFilterCode
|
||||
*
|
||||
* @return string
|
||||
@@ -1790,7 +1875,7 @@ abstract class MetaModel
|
||||
private static $m_aRelationInfos = array();
|
||||
|
||||
/**
|
||||
* TO BE DEPRECATED: use EnumRelationsEx instead
|
||||
* @deprecated Use EnumRelationsEx instead
|
||||
*
|
||||
* @param string $sClass
|
||||
*
|
||||
@@ -2779,21 +2864,26 @@ abstract class MetaModel
|
||||
}
|
||||
}
|
||||
|
||||
$aCurrentClassUniquenessRules = MetaModel::GetUniquenessRules($sPHPClass);
|
||||
$aCurrentClassUniquenessRules = MetaModel::GetUniquenessRules($sPHPClass, true);
|
||||
if (!empty($aCurrentClassUniquenessRules))
|
||||
{
|
||||
$aClassFields = self::GetAttributesList($sPHPClass);
|
||||
foreach ($aCurrentClassUniquenessRules as $sUniquenessRuleId => $aUniquenessRuleProperties)
|
||||
{
|
||||
$bHasSameRuleInParent = self::HasSameUniquenessRuleInParent($sPHPClass, $sUniquenessRuleId);
|
||||
$bIsRuleOverride = self::HasSameUniquenessRuleInParent($sPHPClass, $sUniquenessRuleId);
|
||||
try
|
||||
{
|
||||
self::CheckUniquenessRuleValidity($aUniquenessRuleProperties, $bHasSameRuleInParent, $aClassFields);
|
||||
self::CheckUniquenessRuleValidity($aUniquenessRuleProperties, $bIsRuleOverride, $aClassFields);
|
||||
}
|
||||
catch (CoreUnexpectedValue $e)
|
||||
{
|
||||
throw new Exception("Invalid uniqueness rule declaration : class={$sPHPClass}, rule=$sUniquenessRuleId, reason={$e->getMessage()}");
|
||||
}
|
||||
|
||||
if (!$bIsRuleOverride)
|
||||
{
|
||||
self::SetUniquenessRuleRootClass($sPHPClass, $sUniquenessRuleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3092,71 +3182,77 @@ abstract class MetaModel
|
||||
/**
|
||||
* @param array $aUniquenessRuleProperties
|
||||
* @param bool $bRuleOverride if false then control an original declaration validity,
|
||||
* otherwise an override validity (can have only the disabled key)
|
||||
* otherwise an override validity (can only have the 'disabled' key)
|
||||
* @param string[] $aExistingClassFields if non empty, will check that all fields declared in the rules exists in the class
|
||||
*
|
||||
* @throws \CoreUnexpectedValue if the rule is invalid
|
||||
*
|
||||
* @since 2.6 N°659 uniqueness constraint
|
||||
* @since 2.6.1 N°1968 (joli mois de mai...) disallow overrides of 'attributes' properties
|
||||
*/
|
||||
public static function CheckUniquenessRuleValidity($aUniquenessRuleProperties, $bRuleOverride = true, $aExistingClassFields = array())
|
||||
{
|
||||
$MANDATORY_ATTRIBUTES = array('attributes');
|
||||
$UNIQUENESS_MANDATORY_KEYS_NB = count($MANDATORY_ATTRIBUTES);
|
||||
$bHasDisabledKey = false;
|
||||
|
||||
$bHasMissingMandatoryKey = true;
|
||||
$iMissingMandatoryKeysNb = $UNIQUENESS_MANDATORY_KEYS_NB;
|
||||
$bHasAllMandatoryKeysMissing = false;
|
||||
/** @var boolean $bHasNonDisabledKeys true if rule contains at least one key that is not 'disabled' */
|
||||
$bHasNonDisabledKeys = false;
|
||||
$bDisabledKeyValue = null;
|
||||
|
||||
foreach ($aUniquenessRuleProperties as $sUniquenessRuleKey => $aUniquenessRuleProperty)
|
||||
{
|
||||
if (($sUniquenessRuleKey === 'disabled') && (!is_null($aUniquenessRuleProperty)))
|
||||
if ($sUniquenessRuleKey === 'disabled')
|
||||
{
|
||||
$bDisabledKeyValue = $aUniquenessRuleProperty;
|
||||
if (!is_null($aUniquenessRuleProperty))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (is_null($aUniquenessRuleProperty))
|
||||
{
|
||||
$bHasDisabledKey = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
$bHasNonDisabledKeys = true;
|
||||
|
||||
if (in_array($sUniquenessRuleKey, $MANDATORY_ATTRIBUTES, true)) {
|
||||
$bHasMissingMandatoryKey = false;
|
||||
$iMissingMandatoryKeysNb--;
|
||||
}
|
||||
|
||||
if (($sUniquenessRuleKey === 'attributes') && (!empty($aExistingClassFields)))
|
||||
if ($sUniquenessRuleKey === 'attributes')
|
||||
{
|
||||
foreach ($aUniquenessRuleProperties[$sUniquenessRuleKey] as $sRuleAttribute)
|
||||
if (!empty($aExistingClassFields))
|
||||
{
|
||||
if (!in_array($sRuleAttribute, $aExistingClassFields, true))
|
||||
foreach ($aUniquenessRuleProperties[$sUniquenessRuleKey] as $sRuleAttribute)
|
||||
{
|
||||
throw new CoreUnexpectedValue("Uniqueness rule : non existing field '$sRuleAttribute'");
|
||||
if (!in_array($sRuleAttribute, $aExistingClassFields, true))
|
||||
{
|
||||
throw new CoreUnexpectedValue("Uniqueness rule : non existing field '$sRuleAttribute'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($iMissingMandatoryKeysNb == $UNIQUENESS_MANDATORY_KEYS_NB)
|
||||
if ($iMissingMandatoryKeysNb === 0)
|
||||
{
|
||||
$bHasAllMandatoryKeysMissing = true;
|
||||
$bHasMissingMandatoryKey = false;
|
||||
}
|
||||
|
||||
if ($bHasDisabledKey)
|
||||
if ($bRuleOverride && $bHasNonDisabledKeys)
|
||||
{
|
||||
if ($bRuleOverride && $bHasAllMandatoryKeysMissing && !$bHasNonDisabledKeys)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ($bHasMissingMandatoryKey)
|
||||
{
|
||||
throw new CoreUnexpectedValue('Uniqueness rule : missing mandatory properties');
|
||||
}
|
||||
|
||||
return;
|
||||
throw new CoreUnexpectedValue('Uniqueness rule : only the \'disabled\' key can be overridden');
|
||||
}
|
||||
|
||||
if ($bHasMissingMandatoryKey)
|
||||
if ($bRuleOverride && is_null($bDisabledKeyValue))
|
||||
{
|
||||
throw new CoreUnexpectedValue('Uniqueness rule : missing mandatory properties');
|
||||
throw new CoreUnexpectedValue('Uniqueness rule : when overriding a rule, value must be set for the \'disabled\' key');
|
||||
}
|
||||
if (!$bRuleOverride && $bHasMissingMandatoryKey)
|
||||
{
|
||||
throw new CoreUnexpectedValue('Uniqueness rule : missing mandatory property');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3810,7 +3906,7 @@ abstract class MetaModel
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param int $iOption
|
||||
* @param int $iOption one of ENUM_CHILD_CLASSES_EXCLUDETOP, ENUM_CHILD_CLASSES_ALL
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
@@ -6566,22 +6662,24 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the specified class and id.
|
||||
* Instantiate an object already persisted to the Database.
|
||||
*
|
||||
* @api
|
||||
* @see MetaModel::GetObjectWithArchive to get object even if it's archived
|
||||
* @see utils::PushArchiveMode() to enable search on archived objects
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param int $iKey id value of the object to retrieve
|
||||
* @param bool $bMustBeFound see throws ArchivedObjectException
|
||||
* @param bool $bAllowAllData if true then no rights filtering
|
||||
* @param bool $bAllowAllData if true then user rights will be bypassed - use with care!
|
||||
* @param null $aModifierProperties
|
||||
*
|
||||
* @return DBObject|null null if : (the object is not found) or (archive mode disabled and object is archived and
|
||||
* @return \cmdbAbstractObject null if : (the object is not found) or (archive mode disabled and object is archived and
|
||||
* $bMustBeFound=false)
|
||||
* @throws CoreException if no result found and $bMustBeFound=true
|
||||
* @throws ArchivedObjectException if archive mode disabled and result is archived and $bMustBeFound=true
|
||||
* @throws \Exception
|
||||
*
|
||||
* @see MetaModel::GetObjectWithArchive to get object even if it's archived
|
||||
* @see utils::PushArchiveMode() to enable search on archived objects
|
||||
*/
|
||||
public static function GetObject($sClass, $iKey, $bMustBeFound = true, $bAllowAllData = false, $aModifierProperties = null)
|
||||
{
|
||||
@@ -6782,8 +6880,11 @@ abstract class MetaModel
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param array|null $aValues array of attcode => value
|
||||
* Instantiate a persistable object (not yet persisted)
|
||||
*
|
||||
* @api
|
||||
* @param string $sClass A persistable class
|
||||
* @param array|null $aValues array of attcode => attribute value to preset
|
||||
*
|
||||
* @return DBObject
|
||||
* @throws \CoreException
|
||||
@@ -6828,6 +6929,8 @@ abstract class MetaModel
|
||||
* @todo: protect it against forbidden usages (in such a case, delete objects one by one)
|
||||
*
|
||||
* @param \DBObjectSearch $oFilter
|
||||
* @deprecated
|
||||
* @experimental
|
||||
*
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
@@ -6845,6 +6948,8 @@ abstract class MetaModel
|
||||
* @param DBObjectSearch $oFilter
|
||||
* @param array $aValues array of attcode => value
|
||||
*
|
||||
* @deprecated
|
||||
* @experimental
|
||||
* @return int Modified objects
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
@@ -7139,6 +7244,10 @@ abstract class MetaModel
|
||||
{
|
||||
// Expand the parameters for the object
|
||||
$sName = substr($sSearch, 0, $iPos);
|
||||
// Note: Capturing
|
||||
// 1 - The delimiter
|
||||
// 2 - The arrow
|
||||
// 3 - The attribute code
|
||||
$aRegExps = array(
|
||||
'/(\\$)'.$sName.'-(>|>)([^\\$]+)\\$/', // Support both syntaxes: $this->xxx$ or $this->xxx$ for HTML compatibility
|
||||
'/(%24)'.$sName.'-(>|>)([^%24]+)%24/', // Support for urlencoded in HTML attributes (%20this->xxx%20)
|
||||
@@ -7173,8 +7282,28 @@ abstract class MetaModel
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearches[] = '$'.$sSearch.'$';
|
||||
$aReplacements[] = (string)$replace;
|
||||
$aRegExps = array(
|
||||
'/(\$)'.$sSearch.'\$/', // Support for regular placeholders (eg. $APP_URL$)
|
||||
'/(%24)'.$sSearch.'%24/', // Support for urlencoded in HTML attributes (eg. %24APP_URL%24)
|
||||
);
|
||||
foreach($aRegExps as $sRegExp)
|
||||
{
|
||||
if(preg_match_all($sRegExp, $sInput, $aMatches))
|
||||
{
|
||||
foreach($aMatches[1] as $idx => $sDelimiter)
|
||||
{
|
||||
try
|
||||
{
|
||||
$aReplacements[] = (string) $replace;
|
||||
$aSearches[] = $aMatches[1][$idx] . $sSearch . $aMatches[1][$idx];
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
// No replacement will occur
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return str_replace($aSearches, $aReplacements, $sInput);
|
||||
|
||||
@@ -45,7 +45,7 @@ class iTopMutex
|
||||
static protected $aAcquiredLocks = array(); // Number of instances of the Mutex, having the lock, in this page
|
||||
|
||||
public function __construct(
|
||||
$sName, $sDBHost = null, $sDBUser = null, $sDBPwd = null, $bDBTlsEnabled = false, $sDBTlsCA = null
|
||||
$sName, $sDBHost = null, $sDBUser = null, $sDBPwd = null, $bDBTlsEnabled = null, $sDBTlsCA = null
|
||||
)
|
||||
{
|
||||
// Compute the name of a lock for mysql
|
||||
|
||||
@@ -126,6 +126,7 @@ class ormDocument
|
||||
*/
|
||||
public function GetDisplayURL($sClass, $Id, $sAttCode)
|
||||
{
|
||||
// TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route)
|
||||
return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode";
|
||||
}
|
||||
|
||||
@@ -137,6 +138,7 @@ class ormDocument
|
||||
{
|
||||
// Compute a signature to reset the cache anytime the data changes (this is acceptable if used only with icon files)
|
||||
$sSignature = md5($this->GetData());
|
||||
// TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route)
|
||||
return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.document.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode&s=$sSignature&cache=86400";
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
*/
|
||||
final class ormTagSet extends ormSet
|
||||
{
|
||||
private $m_bDisplayPartial = false;
|
||||
|
||||
|
||||
/**
|
||||
* ormTagSet constructor.
|
||||
*
|
||||
@@ -299,6 +302,82 @@ final class ormTagSet extends ormSet
|
||||
return $aModifiedTagCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] list of codes for added entries
|
||||
*/
|
||||
public function GetAdded()
|
||||
{
|
||||
$aAddedTagCodes = array_keys($this->aAdded);
|
||||
sort($aAddedTagCodes);
|
||||
|
||||
return $aAddedTagCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] list of codes for removed entries
|
||||
*/
|
||||
public function GetRemoved()
|
||||
{
|
||||
$aRemovedTagCodes = array_keys($this->aRemoved);
|
||||
sort($aRemovedTagCodes);
|
||||
|
||||
return $aRemovedTagCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a delta to the current ItemSet
|
||||
* $aDelta['added] = array of added items
|
||||
* $aDelta['removed'] = array of removed items
|
||||
*
|
||||
* @param $aDelta
|
||||
*
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function ApplyDelta($aDelta)
|
||||
{
|
||||
if (isset($aDelta['removed']))
|
||||
{
|
||||
foreach($aDelta['removed'] as $oItem)
|
||||
{
|
||||
$this->Remove($oItem);
|
||||
}
|
||||
}
|
||||
if (isset($aDelta['added']))
|
||||
{
|
||||
foreach($aDelta['added'] as $oItem)
|
||||
{
|
||||
$this->Add($oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the added and removed arrays for bulk edit
|
||||
*
|
||||
* @param string[] $aItems
|
||||
*
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function GenerateDiffFromArray($aItems)
|
||||
{
|
||||
foreach($this->GetValues() as $oCurrentItem)
|
||||
{
|
||||
if (!in_array($oCurrentItem, $aItems))
|
||||
{
|
||||
$this->Remove($oCurrentItem);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($aItems as $oNewItem)
|
||||
{
|
||||
$this->Add($oNewItem);
|
||||
}
|
||||
|
||||
// Keep only the aModified list
|
||||
$this->aRemoved = array();
|
||||
$this->aAdded = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a tag code is valid or not for this TagSet
|
||||
*
|
||||
@@ -479,4 +558,21 @@ final class ormTagSet extends ormSet
|
||||
return TagSetFieldData::GetTagDataClassName($this->sClass, $this->sAttCode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function DisplayPartial()
|
||||
{
|
||||
return $this->m_bDisplayPartial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $m_bDisplayPartial
|
||||
*/
|
||||
public function SetDisplayPartial($m_bDisplayPartial)
|
||||
{
|
||||
$this->m_bDisplayPartial = $m_bDisplayPartial;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -257,13 +257,14 @@ class CoreServices implements iRestServiceProvider
|
||||
*/
|
||||
public function ListOperations($sVersion)
|
||||
{
|
||||
// 1.4 - iTop 2.5.2, 2.6.1, 2.7.0, Verb 'core/get': added pagination parameters limit and page
|
||||
// 1.3 - iTop 2.2.0, Verb 'get_related': added the options 'redundancy' and 'direction' to take into account the redundancy in the impact analysis
|
||||
// 1.2 - was documented in the wiki but never released ! Same as 1.3
|
||||
// 1.1 - In the reply, objects have a 'key' entry so that it is no more necessary to split class::key programmaticaly
|
||||
// 1.0 - Initial implementation in iTop 2.0.1
|
||||
//
|
||||
$aOps = array();
|
||||
if (in_array($sVersion, array('1.0', '1.1', '1.2', '1.3')))
|
||||
if (in_array($sVersion, array('1.0', '1.1', '1.2', '1.3', '1.4')))
|
||||
{
|
||||
$aOps[] = array(
|
||||
'verb' => 'core/create',
|
||||
@@ -299,9 +300,16 @@ class CoreServices implements iRestServiceProvider
|
||||
|
||||
/**
|
||||
* Enumerate services delivered by this class
|
||||
*
|
||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||
* @param string $sVerb
|
||||
* @param $aParams
|
||||
*
|
||||
* @return RestResult The standardized result structure (at least a message)
|
||||
* @throws Exception in case of internal failure.
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \SimpleGraphException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function ExecOperation($sVersion, $sVerb, $aParams)
|
||||
{
|
||||
@@ -436,8 +444,10 @@ class CoreServices implements iRestServiceProvider
|
||||
$key = RestUtils::GetMandatoryParam($aParams, 'key');
|
||||
$aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
|
||||
$bExtendedOutput = (RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+');
|
||||
$iLimit = (int)RestUtils::GetOptionalParam($aParams, 'limit', 0);
|
||||
$iPage = (int)RestUtils::GetOptionalParam($aParams, 'page', 1);
|
||||
|
||||
$oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
|
||||
$oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key, $iLimit, self::getOffsetFromLimitAndPage($iLimit, $iPage));
|
||||
$sTargetClass = $oObjectSet->GetFilter()->GetClass();
|
||||
|
||||
if (UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ) != UR_ALLOWED_YES)
|
||||
@@ -450,6 +460,11 @@ class CoreServices implements iRestServiceProvider
|
||||
$oResult->code = RestResult::UNAUTHORIZED;
|
||||
$oResult->message = "The current user does not have enough permissions for exporting data of class $sTargetClass";
|
||||
}
|
||||
elseif ($iPage < 1)
|
||||
{
|
||||
$oResult->code = RestResult::INVALID_PAGE;
|
||||
$oResult->message = "The request page number is not valid. It must be an integer greater than 0";
|
||||
}
|
||||
else
|
||||
{
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
@@ -774,4 +789,15 @@ class CoreServices implements iRestServiceProvider
|
||||
$oResult->message = $sRes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iLimit
|
||||
* @param int $iPage
|
||||
*
|
||||
* @return int Offset for a given page number
|
||||
*/
|
||||
protected static function getOffsetFromLimitAndPage($iLimit, $iPage)
|
||||
{
|
||||
return $iLimit * max(0, $iPage - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// iTop is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
@@ -66,7 +66,7 @@ class SimpleCrypt
|
||||
* Constructor
|
||||
* @param string $sEngineName Engine for encryption. Values: Simple, Mcrypt, Sodium or OpenSSL
|
||||
* @throws Exception This library is unkown
|
||||
*/
|
||||
*/
|
||||
function __construct($sEngineName = 'Mcrypt')
|
||||
{
|
||||
switch($sEngineName){
|
||||
@@ -88,7 +88,8 @@ class SimpleCrypt
|
||||
}
|
||||
break;
|
||||
case 'OpenSSL':
|
||||
if(!function_exists('openssl_decrypt')){
|
||||
case 'OpenSSLMcryptCompatibility':
|
||||
if(!function_exists('openssl_decrypt')){
|
||||
$sEngineName = 'Simple';
|
||||
}
|
||||
break;
|
||||
@@ -101,30 +102,30 @@ class SimpleCrypt
|
||||
$sEngineName = 'SimpleCrypt' . $sEngineName . 'Engine';
|
||||
$this->oEngine = new $sEngineName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts the string with the given key
|
||||
* @param string $key
|
||||
* @param string $sString Plaintext string
|
||||
* @return string Ciphered string
|
||||
*/
|
||||
*/
|
||||
function Encrypt($key, $sString)
|
||||
{
|
||||
return $this->oEngine->Encrypt($key,$sString);
|
||||
return $this->oEngine->Encrypt($key,$sString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decrypts the string by the given key
|
||||
* @param string $key
|
||||
* @param string $string Ciphered string
|
||||
* @return string Plaintext string
|
||||
* @return string Plaintext string
|
||||
*/
|
||||
function Decrypt($key, $string)
|
||||
{
|
||||
return $this->oEngine->Decrypt($key,$string);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a random "salt" value, to be used when "hashing" a password
|
||||
* using a one-way encryption algorithm, to prevent an attack using a "rainbow table"
|
||||
@@ -135,9 +136,9 @@ class SimpleCrypt
|
||||
{
|
||||
// Copied from http://www.php.net/manual/en/function.mt-rand.php#83655
|
||||
// get 128 pseudorandom bits in a string of 16 bytes
|
||||
|
||||
|
||||
$sRandomBits = null;
|
||||
|
||||
|
||||
// Unix/Linux platform?
|
||||
$fp = @fopen('/dev/urandom','rb');
|
||||
if ($fp !== FALSE)
|
||||
@@ -156,14 +157,14 @@ class SimpleCrypt
|
||||
{
|
||||
$CAPI_Util = new COM('CAPICOM.Utilities.1');
|
||||
$sBase64RandomBits = ''.$CAPI_Util->GetRandom(16,0);
|
||||
|
||||
|
||||
// if we ask for binary data PHP munges it, so we
|
||||
// request base64 return value. We squeeze out the
|
||||
// redundancy and useless ==CRLF by hashing...
|
||||
if ($sBase64RandomBits)
|
||||
{
|
||||
//echo "Random bits got from CAPICOM.Utilities.1<br/>\n";
|
||||
$sRandomBits = md5($sBase64RandomBits, TRUE);
|
||||
$sRandomBits = md5($sBase64RandomBits, TRUE);
|
||||
}
|
||||
}
|
||||
catch (Exception $ex)
|
||||
@@ -182,10 +183,10 @@ class SimpleCrypt
|
||||
{
|
||||
$sRandomBits .= sprintf('%04x', mt_rand(0, 65535));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
return $sRandomBits;
|
||||
return $sRandomBits;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +222,7 @@ class SimpleCryptSimpleEngine implements CryptEngine
|
||||
$char = chr(ord($char)+ord($keychar));
|
||||
$result.=$char;
|
||||
}
|
||||
return $result;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
@@ -235,7 +236,7 @@ class SimpleCryptSimpleEngine implements CryptEngine
|
||||
$result.=$char;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,10 +259,13 @@ class SimpleCryptMcryptEngine implements CryptEngine
|
||||
{
|
||||
$this->td = mcrypt_module_open($this->alg,'','cbc','');
|
||||
}
|
||||
|
||||
|
||||
public function Encrypt($key, $sString)
|
||||
{
|
||||
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND_URANDOM); // MCRYPT_RAND_URANDOM is now useable since itop requires php >= 5.6
|
||||
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($this->td), MCRYPT_DEV_URANDOM); // MCRYPT_DEV_URANDOM is now useable since itop requires php >= 5.6
|
||||
if (false === $iv) {
|
||||
throw new Exception('IV generation failed');
|
||||
}
|
||||
mcrypt_generic_init($this->td, $key, $iv);
|
||||
if (empty($sString))
|
||||
{
|
||||
@@ -275,7 +279,7 @@ class SimpleCryptMcryptEngine implements CryptEngine
|
||||
public function Decrypt($key, $encrypted_data)
|
||||
{
|
||||
$iv = substr($encrypted_data, 0, mcrypt_enc_get_iv_size($this->td));
|
||||
$string = substr($encrypted_data, mcrypt_enc_get_iv_size($this->td));
|
||||
$string = substr($encrypted_data, mcrypt_enc_get_iv_size($this->td));
|
||||
$r = mcrypt_generic_init($this->td, $key, $iv);
|
||||
if (($r < 0) || ($r === false))
|
||||
{
|
||||
@@ -288,7 +292,7 @@ class SimpleCryptMcryptEngine implements CryptEngine
|
||||
}
|
||||
return $decrypted_data;
|
||||
}
|
||||
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
mcrypt_module_close($this->td);
|
||||
|
||||
@@ -57,7 +57,7 @@ abstract class TagSetFieldData extends cmdbAbstractObject
|
||||
"default_value" => '',
|
||||
"is_null_allowed" => false,
|
||||
"depends_on" => array(),
|
||||
"validation_pattern" => '^[a-zA-Z][a-zA-Z0-9]{3,}$',
|
||||
"validation_pattern" => '^[a-zA-Z][a-zA-Z0-9]{2,}$',
|
||||
)));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("label", array(
|
||||
"allowed_values" => null,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0
|
||||
$version: "v2.6.0";
|
||||
$version: "v2.6.2";
|
||||
|
||||
// Base colors
|
||||
$gray-base: #000 !default;
|
||||
|
||||
@@ -343,10 +343,10 @@ a.small_action {
|
||||
padding-left: 5px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
background: #ea7d1e url(../images/actions_left.png?v=v2.6.0) no-repeat left;
|
||||
background: #ea7d1e url(../images/actions_left.png?v=v2.6.2) no-repeat left;
|
||||
}
|
||||
.actions_details span {
|
||||
background: url(../images/actions_right.png?v=v2.6.0) no-repeat right;
|
||||
background: url(../images/actions_right.png?v=v2.6.2) no-repeat right;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
padding-top: 2px;
|
||||
@@ -520,7 +520,7 @@ div.actions_menu > ul {
|
||||
nowidth: 70px;
|
||||
padding-left: 5px;
|
||||
/* Nasty work-around for IE... en attendant mieux */
|
||||
background: #ea7d1e url(../images/actions_left.png?v=v2.6.0) no-repeat top left;
|
||||
background: #ea7d1e url(../images/actions_left.png?v=v2.6.2) no-repeat top left;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -532,7 +532,7 @@ div.actions_menu > ul > li {
|
||||
height: 17px;
|
||||
padding-right: 16px;
|
||||
padding-left: 4px;
|
||||
background: url(../images/actions_right.png?v=v2.6.0) no-repeat top right transparent;
|
||||
background: url(../images/actions_right.png?v=v2.6.2) no-repeat top right transparent;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
vertical-align: middle;
|
||||
@@ -678,7 +678,7 @@ td a.dp-choose-date, a.dp-choose-date, td a.dp-choose-date:hover, a.dp-choose-da
|
||||
display: block;
|
||||
text-indent: -2000px;
|
||||
overflow: hidden;
|
||||
background: url(../images/calendar.png?v=v2.6.0) no-repeat;
|
||||
background: url(../images/calendar.png?v=v2.6.2) no-repeat;
|
||||
}
|
||||
td a.dp-choose-date.dp-disabled, a.dp-choose-date.dp-disabled {
|
||||
background-position: 0 -20px;
|
||||
@@ -1332,19 +1332,19 @@ input.dp-applied {
|
||||
}
|
||||
/* Beware: IE6 does not support multiple selector with multiple classes, only the last class is used */
|
||||
table.listResults tr.odd td.truncated, table.listResults tr td.truncated, .wizContainer table.listResults tr.odd td.truncated, .wizContainer table.listResults tr td.truncated {
|
||||
background: url(../images/truncated.png?v=v2.6.0) bottom repeat-x;
|
||||
background: url(../images/truncated.png?v=v2.6.2) bottom repeat-x;
|
||||
}
|
||||
/* Beware: IE6 does not support multiple selector with multiple classes, only the last class is used */
|
||||
table.listResults tr.even td.truncated, .wizContainer table.listResults tr.even td.truncated {
|
||||
background: #f9f9f1 url(../images/truncated.png?v=v2.6.0) bottom repeat-x;
|
||||
background: #f9f9f1 url(../images/truncated.png?v=v2.6.2) bottom repeat-x;
|
||||
}
|
||||
/* Beware: IE6 does not support multiple selector with multiple classes, only the last class is used */
|
||||
table.listResults tr.even td.hover.truncated, .wizContainer table.listResults tr.even td.hover.truncated {
|
||||
background: #fdf5d0 url(../images/truncated.png?v=v2.6.0) bottom repeat-x;
|
||||
background: #fdf5d0 url(../images/truncated.png?v=v2.6.2) bottom repeat-x;
|
||||
}
|
||||
/* Beware: IE6 does not support multiple selector with multiple classes, only the last class is used */
|
||||
table.listResults tr.odd td.hover.truncated, table.listResults tr td.hover.truncated, .wizContainer table.listResults tr.odd td.hover.truncated, .wizContainer table.listResults tr td.hover.truncated {
|
||||
background: #fdf5d0 url(../images/truncated.png?v=v2.6.0) bottom repeat-x;
|
||||
background: #fdf5d0 url(../images/truncated.png?v=v2.6.2) bottom repeat-x;
|
||||
}
|
||||
table.listResults.truncated {
|
||||
border-bottom: 0;
|
||||
@@ -1452,7 +1452,7 @@ div#logo {
|
||||
div#logo div {
|
||||
height: 88px;
|
||||
width: 244px;
|
||||
background: url(../images/itop-logo-2.png?v=v2.6.0) left no-repeat;
|
||||
background: url(../images/itop-logo-2.png?v=v2.6.2) left no-repeat;
|
||||
}
|
||||
#left-pane .ui-layout-north {
|
||||
overflow: hidden;
|
||||
@@ -1544,7 +1544,7 @@ div#logo div {
|
||||
}
|
||||
#global-search-image {
|
||||
vertical-align: middle;
|
||||
background: url(../images/search.png?v=v2.6.0) center center no-repeat;
|
||||
background: url(../images/search.png?v=v2.6.2) center center no-repeat;
|
||||
display: inline-block;
|
||||
width: 28px;
|
||||
height: 30px;
|
||||
@@ -1573,7 +1573,7 @@ span.ui-icon {
|
||||
margin: 0 2px;
|
||||
}
|
||||
.ui-layout-button-pin-down {
|
||||
background: url(../images/splitter-bkg.png?v=v2.6.0) transparent;
|
||||
background: url(../images/splitter-bkg.png?v=v2.6.2) transparent;
|
||||
width: 16px;
|
||||
background-position: -144px -144px;
|
||||
}
|
||||
@@ -1830,6 +1830,9 @@ fieldset .details > .field_container {
|
||||
padding-left: 0.4em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.field_container > div > div.field_value .attribute-edit .form-field-container .form-field-content > .form_validation, .field_container > div > div.field_value .attribute-edit .form-field-container .form-field-content > .field_status {
|
||||
display: inline;
|
||||
}
|
||||
.field_container > div > div.field_value .attribute-edit .field_input_zone {
|
||||
width: 100%;
|
||||
/* auto; */
|
||||
@@ -2089,7 +2092,7 @@ img.prev, img.first, img.next, img.last {
|
||||
}
|
||||
div.actions_button {
|
||||
float: right;
|
||||
background: #ea7d1e url("../images/actions_left.png?v=v2.6.0") no-repeat scroll left top;
|
||||
background: #ea7d1e url("../images/actions_left.png?v=v2.6.2") no-repeat scroll left top;
|
||||
padding-left: 5px;
|
||||
margin-top: 0;
|
||||
margin-right: 10px;
|
||||
@@ -2097,7 +2100,7 @@ div.actions_button {
|
||||
vertical-align: middle;
|
||||
}
|
||||
div.actions_button a, .actions_button a:hover, .actions_button a:visited {
|
||||
background: #ea7d1e url(../images/actions_bkg.png?v=v2.6.0) no-repeat scroll right top;
|
||||
background: #ea7d1e url(../images/actions_bkg.png?v=v2.6.2) no-repeat scroll right top;
|
||||
color: #fff;
|
||||
padding-right: 8px;
|
||||
cursor: pointer;
|
||||
@@ -2121,10 +2124,10 @@ select#org_id {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.dragHover {
|
||||
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.0);
|
||||
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.2);
|
||||
}
|
||||
.edit_mode .dashlet {
|
||||
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.0);
|
||||
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.2);
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
@@ -2134,6 +2137,17 @@ select#org_id {
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
}
|
||||
/* Prevent cursor clicking on the calendar (eg. While editing dashlet) */
|
||||
.dashlet-blocker {
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
/* To be above calendar links & all, but below .close-box (9) */
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
td.layout_cell {
|
||||
height: 50px;
|
||||
/* min-height does not work */
|
||||
@@ -2158,7 +2172,7 @@ table.prop_table {
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
background: transparent url(../images/delete.png?v=v2.6.0) no-repeat center;
|
||||
background: transparent url(../images/delete.png?v=v2.6.2) no-repeat center;
|
||||
}
|
||||
td.prop_value {
|
||||
text-align: left;
|
||||
@@ -2379,17 +2393,17 @@ a.summary, a.summary:hover {
|
||||
}
|
||||
.message_info {
|
||||
border: 1px solid #993;
|
||||
background: url(../images/info-mini.png?v=v2.6.0) 1em 1em no-repeat #ffc;
|
||||
background: url(../images/info-mini.png?v=v2.6.2) 1em 1em no-repeat #ffc;
|
||||
padding-left: 3em;
|
||||
}
|
||||
.message_ok {
|
||||
border: 1px solid #393;
|
||||
background: url(../images/ok.png?v=v2.6.0) 1em 1em no-repeat #cfc;
|
||||
background: url(../images/ok.png?v=v2.6.2) 1em 1em no-repeat #cfc;
|
||||
padding-left: 3em;
|
||||
}
|
||||
.message_error {
|
||||
border: 1px solid #933;
|
||||
background: url(../images/error.png?v=v2.6.0) 1em 1em no-repeat #fcc;
|
||||
background: url(../images/error.png?v=v2.6.2) 1em 1em no-repeat #fcc;
|
||||
padding-left: 3em;
|
||||
}
|
||||
.fg-menu a img {
|
||||
@@ -2520,18 +2534,18 @@ div.explain-printable {
|
||||
}
|
||||
#hiddeable_chapters .ui-tabs .ui-tabs-nav li.hideable-chapter span {
|
||||
padding-left: 20px;
|
||||
background: url(../images/eye-open-555.png?v=v2.6.0) 2px center no-repeat;
|
||||
background: url(../images/eye-open-555.png?v=v2.6.2) 2px center no-repeat;
|
||||
}
|
||||
#hiddeable_chapters .ui-tabs .ui-tabs-nav li.hideable-chapter.strikethrough span {
|
||||
text-decoration: line-through;
|
||||
background: url(../images/eye-closed-555.png?v=v2.6.0) 2px center no-repeat;
|
||||
background: url(../images/eye-closed-555.png?v=v2.6.2) 2px center no-repeat;
|
||||
}
|
||||
.printable-version legend {
|
||||
padding-left: 26px;
|
||||
background: #1c94c4 url(../images/eye-open-fff.png?v=v2.6.0) 8px center no-repeat;
|
||||
background: #1c94c4 url(../images/eye-open-fff.png?v=v2.6.2) 8px center no-repeat;
|
||||
}
|
||||
.printable-version .strikethrough legend {
|
||||
background: #1c94c4 url(../images/eye-closed-fff.png?v=v2.6.0) 8px center no-repeat;
|
||||
background: #1c94c4 url(../images/eye-closed-fff.png?v=v2.6.2) 8px center no-repeat;
|
||||
}
|
||||
.printable-version fieldset.strikethrough span {
|
||||
display: none;
|
||||
@@ -2682,7 +2696,7 @@ span.search-button, span.refresh-button {
|
||||
#itop-breadcrumb .breadcrumb-item a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-image: url(../images/breadcrumb-separator.png?v=v2.6.0);
|
||||
background-image: url(../images/breadcrumb-separator.png?v=v2.6.2);
|
||||
background-repeat: no-repeat;
|
||||
width: 8px;
|
||||
height: 16px;
|
||||
|
||||
@@ -2115,6 +2115,11 @@ fieldset .details>.field_container {
|
||||
padding-left: 0.4em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.form-field-container .form-field-content{
|
||||
> .form_validation, > .field_status {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.field_input_zone{
|
||||
width: 100%; /* auto; */
|
||||
@@ -2478,6 +2483,16 @@ select#org_id {
|
||||
padding: 5px;
|
||||
margin:0;
|
||||
}
|
||||
/* Prevent cursor clicking on the calendar (eg. While editing dashlet) */
|
||||
.dashlet-blocker {
|
||||
position: absolute;
|
||||
z-index: 9; /* To be above calendar links & all, but below .close-box (9) */
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
td.layout_cell {
|
||||
height: 50px; /* min-height does not work */
|
||||
vertical-align: top;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-external/2.6.0',
|
||||
'authent-external/2.6.2',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @link http://community.itop-itsm.ru iTop Russian Community
|
||||
* @link https://github.com/itop-itsm-ru/itop-rus
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*/
|
||||
//
|
||||
|
||||
38
datamodels/2.x/authent-external/sk.dict.authent-external.php
Normal file
38
datamodels/2.x/authent-external/sk.dict.authent-external.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
//
|
||||
// Class: UserExternal
|
||||
//
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Class:UserExternal' => 'Externý užívateľ',
|
||||
'Class:UserExternal+' => '',
|
||||
));
|
||||
@@ -2,6 +2,7 @@
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @author Robert Deng <denglx@gmail.com>
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
@@ -20,7 +21,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
@@ -30,11 +30,9 @@
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserExternal
|
||||
//
|
||||
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Class:UserExternal' => '外部用户',
|
||||
'Class:UserExternal+' => '用户在iTop 外部验证身份',
|
||||
|
||||
@@ -38,4 +38,6 @@
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Class:UserLDAP' => 'LDAP uživatel',
|
||||
'Class:UserLDAP+' => 'Uživatel ověřen přes LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Heslo',
|
||||
'Class:UserLDAP/Attribute:password+' => '',
|
||||
));
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/**
|
||||
* @author Erik Bøg <erik@boegmoeller.dk>
|
||||
* @author Erik Bøg <erik@boegmoeller.dk>
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Class:UserLDAP' => 'LDAP-Bruger',
|
||||
'Class:UserLDAP+' => 'Bruger der godkendes via LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Password',
|
||||
'Class:UserLDAP/Attribute:password+' => 'Brugerens password',
|
||||
));
|
||||
|
||||
@@ -25,4 +25,6 @@
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', array(
|
||||
'Class:UserLDAP' => 'LDAP-Benutzer',
|
||||
'Class:UserLDAP+' => 'Benutzer, der über LDAP authentifiziert wird',
|
||||
'Class:UserLDAP/Attribute:password' => 'Passwort',
|
||||
'Class:UserLDAP/Attribute:password+' => 'Benutzerpasswort',
|
||||
));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -38,4 +38,6 @@
|
||||
Dict::Add('EN US', 'English', 'English', array(
|
||||
'Class:UserLDAP' => 'LDAP user',
|
||||
'Class:UserLDAP+' => 'User authentified by LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Password',
|
||||
'Class:UserLDAP/Attribute:password+' => 'user authentication string',
|
||||
));
|
||||
|
||||
@@ -37,4 +37,6 @@
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
|
||||
'Class:UserLDAP' => 'Usuario LDAP',
|
||||
'Class:UserLDAP+' => 'Usuario Autenticado vía LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Contraseña',
|
||||
'Class:UserLDAP/Attribute:password+' => 'Contraseña',
|
||||
));
|
||||
|
||||
@@ -22,4 +22,6 @@
|
||||
Dict::Add('FR FR', 'French', 'Français', array(
|
||||
'Class:UserLDAP' => 'Utilisateur LDAP',
|
||||
'Class:UserLDAP+' => 'Utilisateur authentifié par un serveur LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Mot de passe LDAP',
|
||||
'Class:UserLDAP/Attribute:password+' => '',
|
||||
));
|
||||
|
||||
@@ -22,4 +22,6 @@
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
|
||||
'Class:UserLDAP' => 'LDAP felhasználó',
|
||||
'Class:UserLDAP+' => '',
|
||||
'Class:UserLDAP/Attribute:password' => 'Jelszó',
|
||||
'Class:UserLDAP/Attribute:password+' => '',
|
||||
));
|
||||
|
||||
@@ -36,4 +36,6 @@
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', array(
|
||||
'Class:UserLDAP' => 'Utente LDAP',
|
||||
'Class:UserLDAP+' => 'Utente autenticato da LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Password',
|
||||
'Class:UserLDAP/Attribute:password+' => 'user authentication string',
|
||||
));
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/**
|
||||
* @author Hirofumi Kosaka <kosaka@rworks.jp>
|
||||
* @author Hirofumi Kosaka <kosaka@rworks.jp>
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', array(
|
||||
'Class:UserLDAP' => 'LDAP ユーザー',
|
||||
'Class:UserLDAP+' => 'LDAP認証ユーザー',
|
||||
'Class:UserLDAP/Attribute:password' => 'パスワード',
|
||||
'Class:UserLDAP/Attribute:password+' => '認証文字列',
|
||||
));
|
||||
|
||||
@@ -9,7 +9,7 @@ if (function_exists('ldap_connect'))
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-ldap/2.6.0',
|
||||
'authent-ldap/2.6.2',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -36,4 +36,6 @@
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
|
||||
'Class:UserLDAP' => 'LDAP-gebruiker',
|
||||
'Class:UserLDAP+' => 'Gebruiker aangemeld via LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Password~~',
|
||||
'Class:UserLDAP/Attribute:password+' => 'user authentication string~~',
|
||||
));
|
||||
|
||||
@@ -22,4 +22,6 @@
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'Class:UserLDAP' => 'Usuário externo via LDAP',
|
||||
'Class:UserLDAP+' => '',
|
||||
'Class:UserLDAP/Attribute:password' => 'Senha',
|
||||
'Class:UserLDAP/Attribute:password+' => '',
|
||||
));
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @link http://community.itop-itsm.ru iTop Russian Community
|
||||
* @link https://github.com/itop-itsm-ru/itop-rus
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*/
|
||||
//
|
||||
@@ -14,4 +14,6 @@
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', array(
|
||||
'Class:UserLDAP' => 'Пользователь LDAP',
|
||||
'Class:UserLDAP+' => 'Пользователь, аутентифицируемый через LDAP',
|
||||
'Class:UserLDAP/Attribute:password' => 'Пароль',
|
||||
'Class:UserLDAP/Attribute:password+' => 'Строка аутентификации пользователя',
|
||||
));
|
||||
|
||||
40
datamodels/2.x/authent-ldap/sk.dict.authent-ldap.php
Normal file
40
datamodels/2.x/authent-ldap/sk.dict.authent-ldap.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
//
|
||||
// Class: UserLDAP
|
||||
//
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Class:UserLDAP' => 'LDAP užívateľ',
|
||||
'Class:UserLDAP+' => '',
|
||||
'Class:UserLDAP/Attribute:password' => 'Heslo',
|
||||
'Class:UserLDAP/Attribute:password+' => '',
|
||||
));
|
||||
@@ -37,4 +37,6 @@
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
|
||||
'Class:UserLDAP' => 'LDAP kullanıcısı',
|
||||
'Class:UserLDAP+' => 'Yetki kontrolü LDAP tarafından yapılan',
|
||||
'Class:UserLDAP/Attribute:password' => 'Şifre',
|
||||
'Class:UserLDAP/Attribute:password+' => 'şifre',
|
||||
));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @author Robert Deng <denglx@gmail.com>
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
@@ -20,7 +21,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
@@ -30,12 +30,12 @@
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLDAP
|
||||
//
|
||||
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Class:UserLDAP' => 'LDAP 用户',
|
||||
'Class:UserLDAP+' => '用户身份由LDAP 认证',
|
||||
'Class:UserLDAP/Attribute:password' => '密码',
|
||||
'Class:UserLDAP/Attribute:password+' => '用于验证用户身份的字符串',
|
||||
));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
SetupWebPage::AddModule(
|
||||
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
|
||||
'authent-local/2.6.0',
|
||||
'authent-local/2.6.2',
|
||||
array(
|
||||
// Identification
|
||||
//
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @author Vladimir Kunin <v.b.kunin@gmail.com>
|
||||
* @link http://community.itop-itsm.ru iTop Russian Community
|
||||
* @link https://github.com/itop-itsm-ru/itop-rus
|
||||
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
*/
|
||||
//
|
||||
|
||||
40
datamodels/2.x/authent-local/sk.dict.authent-local.php
Normal file
40
datamodels/2.x/authent-local/sk.dict.authent-local.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>
|
||||
// Class:<class_name>/Attribute:<attribute_code>+
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
|
||||
'Class:UserLocal' => 'iTop užívateľ',
|
||||
'Class:UserLocal+' => '',
|
||||
'Class:UserLocal/Attribute:password' => 'Heslo',
|
||||
'Class:UserLocal/Attribute:password+' => '',
|
||||
));
|
||||
@@ -2,6 +2,7 @@
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @author Robert Deng <denglx@gmail.com>
|
||||
* @copyright Copyright (C) 2010-2018 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*
|
||||
@@ -20,7 +21,6 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
// Dictionnay conventions
|
||||
// Class:<class_name>
|
||||
// Class:<class_name>+
|
||||
@@ -30,11 +30,9 @@
|
||||
// Class:<class_name>/Attribute:<attribute_code>/Value:<value>+
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>
|
||||
// Class:<class_name>/Stimulus:<stimulus_code>+
|
||||
|
||||
//
|
||||
// Class: UserLocal
|
||||
//
|
||||
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
|
||||
'Class:UserLocal' => 'iTop 用户',
|
||||
'Class:UserLocal+' => '用户由 iTop 验证身份',
|
||||
|
||||
@@ -37,4 +37,26 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Attachment:Max_Ko' => '(Maximální velikost souboru: %1$s KiB)',
|
||||
'Attachments:NoAttachment' => 'Žádná příloha. ',
|
||||
'Attachments:PreviewNotAvailable' => 'Pro tento typ přílohy není náhled k dispozici.',
|
||||
'Attachments:Error:FileTooLarge' => 'File is too large to be uploaded. %1$s~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: Attachment
|
||||
//
|
||||
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', array(
|
||||
'Class:Attachment' => 'Attachment~~',
|
||||
'Class:Attachment+' => '~~',
|
||||
'Class:Attachment/Attribute:expire' => 'Expire~~',
|
||||
'Class:Attachment/Attribute:expire+' => '~~',
|
||||
'Class:Attachment/Attribute:temp_id' => 'Temporary id~~',
|
||||
'Class:Attachment/Attribute:temp_id+' => '~~',
|
||||
'Class:Attachment/Attribute:item_class' => 'Item class~~',
|
||||
'Class:Attachment/Attribute:item_class+' => '~~',
|
||||
'Class:Attachment/Attribute:item_id' => 'Item~~',
|
||||
'Class:Attachment/Attribute:item_id+' => '~~',
|
||||
'Class:Attachment/Attribute:item_org_id' => 'Item organization~~',
|
||||
'Class:Attachment/Attribute:item_org_id+' => '~~',
|
||||
'Class:Attachment/Attribute:contents' => 'Contents~~',
|
||||
'Class:Attachment/Attribute:contents+' => '~~',
|
||||
));
|
||||
|
||||
@@ -34,4 +34,26 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Attachment:Max_Ko' => '(Maksimal størrelse: %1$s KB)',
|
||||
'Attachments:NoAttachment' => 'Intet vedhæftet. ',
|
||||
'Attachments:PreviewNotAvailable' => 'Preview not available for this type of attachment.~~',
|
||||
'Attachments:Error:FileTooLarge' => 'File is too large to be uploaded. %1$s~~',
|
||||
));
|
||||
|
||||
//
|
||||
// Class: Attachment
|
||||
//
|
||||
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', array(
|
||||
'Class:Attachment' => 'Attachment~~',
|
||||
'Class:Attachment+' => '~~',
|
||||
'Class:Attachment/Attribute:expire' => 'Expire~~',
|
||||
'Class:Attachment/Attribute:expire+' => '~~',
|
||||
'Class:Attachment/Attribute:temp_id' => 'Temporary id~~',
|
||||
'Class:Attachment/Attribute:temp_id+' => '~~',
|
||||
'Class:Attachment/Attribute:item_class' => 'Item class~~',
|
||||
'Class:Attachment/Attribute:item_class+' => '~~',
|
||||
'Class:Attachment/Attribute:item_id' => 'Item~~',
|
||||
'Class:Attachment/Attribute:item_id+' => '~~',
|
||||
'Class:Attachment/Attribute:item_org_id' => 'Item organization~~',
|
||||
'Class:Attachment/Attribute:item_org_id+' => '~~',
|
||||
'Class:Attachment/Attribute:contents' => 'Contents~~',
|
||||
'Class:Attachment/Attribute:contents+' => '~~',
|
||||
));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user