Compare commits

..

14 Commits

Author SHA1 Message Date
Eric
b0414748cb Typo 2019-06-13 11:55:10 +02:00
Molkobain
b6418d95e7 Add PHPDoc for type hinting as iTop replaces \DOMDocument with \MFDocument 2019-05-28 10:36:18 +02:00
Molkobain
2d6251e5df 💄 Add warning message CSS class (like error message) 2019-05-15 17:53:48 +02:00
Molkobain
91f410a85c 💄 Fix images being too large in icon selector (dashboards and Designer)
Note: The widget still needs a more aggressive refactoring to render nicely...
2019-05-02 16:42:21 +02:00
Eric
0a48696cd8 Carbon: N°1855 - Fix: Cannot remove last 'dependencies' with UI
Note that multi-select value when no entry is selected is "" and not []
in order to be posted, so multi-select values are not always arrays.
2019-04-30 15:46:44 +02:00
Eric
2f71570390 Carbon: N°1855 - fix "depends on" displaying fields from children 2019-04-30 12:02:13 +02:00
Molkobain
78b6c03af7 💡 Add some PHPDoc 2019-04-25 12:46:57 +02:00
Molkobain
22342cdc05 🐛 N°2184 Fix validation issue when several label fiels in a dashlet/designer form 2019-04-25 12:42:16 +02:00
Molkobain
dcf4963e0c N°2152 Fix bad XML generation when adding a dashboard attribute on a new class 2019-04-16 17:15:15 +02:00
Eric
9ec36a76f6 Carbon: N°1589 - Check migration 2019-04-10 12:12:31 +02:00
Eric
09b470e6c7 Better output 2019-04-09 10:43:39 +02:00
Molkobain
40151c7a43 N°2147 Fix non working impact relation when based on default value 2019-04-05 16:25:26 +02:00
Molkobain
34c030b501 N°2070 Extend ModelFactory implementations to optionally check meta classes (PHP) along with regular XML classes 2019-04-05 15:48:29 +02:00
Molkobain
c59d3cc624 Fix unreachable log message on exception 2019-04-01 16:52:22 +02:00
340 changed files with 5280 additions and 21248 deletions

View File

@@ -1,103 +0,0 @@
# 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

View File

@@ -1,7 +0,0 @@
#!/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

View File

@@ -1,8 +0,0 @@
#!/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

View File

@@ -1,20 +0,0 @@
<?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>

View File

@@ -1,58 +0,0 @@
<?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>-->
<!--&lt;!&ndash;<default>data/phpdocumentor/log/objects-manipulation/{DATE}.log</default>&ndash;&gt;-->
<!--&lt;!&ndash;<errors>data/phpdocumentor/log/objects-manipulation/{DATE}.errors.log</errors>&ndash;&gt;-->
<!--<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>

View File

@@ -1,136 +0,0 @@
{% 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 %}

View File

@@ -1,31 +0,0 @@
{% 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 %}

View File

@@ -1,95 +0,0 @@
{% 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 %}

View File

@@ -1,49 +0,0 @@
{% 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 %}

View File

@@ -1 +0,0 @@
{{ node.source|raw }}

View File

@@ -1,122 +0,0 @@
{% 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 %}

View File

@@ -1,42 +0,0 @@
{% 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 %}

View File

@@ -1,5 +0,0 @@
# 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>

View File

@@ -1,34 +0,0 @@
{% 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 %}

View File

@@ -1,12 +0,0 @@
{% 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 %}

View File

@@ -1,26 +0,0 @@
{% 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 %}

View File

@@ -1,26 +0,0 @@
{% 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 %}

View File

@@ -1,56 +0,0 @@
{% 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 %}

View File

@@ -1,20 +0,0 @@
{% 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 -%}

View File

@@ -1,22 +0,0 @@
{% 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 %}

View File

@@ -1,24 +0,0 @@
{% 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 %}#}

View File

@@ -1,24 +0,0 @@
{% 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 %}#}

View File

@@ -1,11 +0,0 @@
{% 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 %}

View File

@@ -1,121 +0,0 @@
{% 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 %}

View File

@@ -1,5 +0,0 @@
{% use 'elements/constant.txt.twig' %}
{% use 'elements/property.txt.twig' %}
{% use 'elements/method.txt.twig' %}
{% block content %}{% endblock %}

View File

@@ -1,51 +0,0 @@
{% 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 %}

View File

@@ -1,49 +0,0 @@
====== 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 %}

View File

@@ -1,27 +0,0 @@
<?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>

3
.gitignore vendored
View File

@@ -33,8 +33,7 @@ test/vendor/*
!/.idea/inspectionProfiles
!/.idea/inspectionProfiles/*
#phpdocumentor temp file
ast.dump
# CMake
cmake-build-*/

View File

@@ -1,5 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="projectProfile" value="Combodo" />
<option name="PROJECT_PROFILE" value="Combodo" />
<version value="1.0" />
</settings>

View File

View File

@@ -35,7 +35,7 @@ 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.1][61]
- [Download iTop 2.6.0][61]
### Version 2.5
@@ -74,7 +74,6 @@ 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
@@ -138,4 +137,4 @@ We would like to give a special thank you to the people from the community who c
[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.1
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.0

View File

@@ -365,7 +365,7 @@ interface iPopupMenuExtension
* Base class for the various types of custom menus
*
* @package Extensibility
* @api
* @internal
* @since 2.0
*/
abstract class ApplicationPopupMenuItem
@@ -378,10 +378,8 @@ abstract class ApplicationPopupMenuItem
protected $aCssClasses;
/**
* Constructor
*
* @api
*
* Constructor
*
* @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
@@ -511,9 +509,6 @@ 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

View File

@@ -385,7 +385,6 @@ EOF
if (!isset($aExtraParams['disable_plugins']) || !$aExtraParams['disable_plugins'])
{
/** @var iApplicationUIExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
{
$oExtensionInstance->OnDisplayProperties($this, $oPage, $bEditMode);
@@ -649,7 +648,6 @@ EOF
}
$oPage->SetCurrentTab('');
/** @var \iApplicationUIExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
{
$oExtensionInstance->OnDisplayRelations($this, $oPage, $bEditMode);
@@ -910,7 +908,7 @@ EOF
/**
* @param \WebPage $oPage
* @param \iTopWebPage $oPage
* @param bool $bEditMode
*
* @throws \CoreException
@@ -920,9 +918,8 @@ EOF
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
* @throws \Exception
*/
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
function DisplayDetails(WebPage $oPage, $bEditMode = false)
{
$sTemplate = Utils::ReadFromFile(MetaModel::GetDisplayTemplate(get_class($this)));
if (!empty($sTemplate))
@@ -944,7 +941,6 @@ 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'));
@@ -2105,7 +2101,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'))); });
$('#{$iId}_console_form').bind('value_change', function() { $('#{$iId}').val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); console.error($('#{$iId}').val()); });
// 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'))); });
@@ -2178,11 +2174,6 @@ 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
@@ -3041,7 +3032,6 @@ 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);
@@ -3463,7 +3453,6 @@ 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);

View File

@@ -184,10 +184,6 @@ 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);
@@ -226,21 +222,14 @@ class DataTable
}
$sCombo = '<select class="pagesize">';
if($iPageSize < 1)
for($iPage = 1; $iPage < 5; $iPage++)
{
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
$iNbItems = $iPage * $iDefaultPageSize;
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</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>";
}
$sSelected = ($iPageSize < 1) ? 'selected="selected"' : '';
$sCombo .= "<option $sSelected value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
$sCombo .= '</select>';
$sPages = Dict::S('UI:Pagination:PagesLabel');
@@ -588,8 +577,8 @@ EOF
public function UpdatePager(WebPage $oPage, $iDefaultPageSize, $iStart)
{
$iPageSize = $iDefaultPageSize;
$iPageIndex = 0;
$iPageSize = ($iDefaultPageSize < 1) ? 1 : $iDefaultPageSize;
$iPageIndex = 1 + floor($iStart / $iPageSize);
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
if ($iDefaultPageSize < 1)
@@ -947,4 +936,4 @@ class DataTableSettings implements Serializable
}
return $ret;
}
}
}

View File

@@ -500,10 +500,7 @@ 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));
@@ -702,7 +699,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])");
@@ -1175,26 +1172,16 @@ EOF
}
if (($bAutoReload) && ($this->m_sStyle != 'search')) // Search form do NOT auto-reload
{
// 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));
$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
$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
);
$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.');');
}
return $sHtml;
@@ -1732,7 +1719,6 @@ class MenuBlock extends DisplayBlock
*/
}
$this->AddMenuSeparator($aActions);
/** @var \iApplicationUIExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
{
$oSet->Rewind();
@@ -1828,7 +1814,6 @@ class MenuBlock extends DisplayBlock
}
$this->AddMenuSeparator($aActions);
/** @var \iApplicationUIExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance)
{
$oSet->Rewind();

View File

@@ -395,6 +395,7 @@ EOF
{
foreach($aFields as $oField)
{
/** @var \DesignerFormField $oField */
$oField->ReadParam($aValues);
}
}
@@ -679,18 +680,34 @@ class DesignerTabularForm extends DesignerForm
class DesignerFormField
{
/** @var string $sLabel */
protected $sLabel;
/** @var string $sCode */
protected $sCode;
/** @var mixed $defaultValue */
protected $defaultValue;
/** @var \DesignerForm $oForm */
protected $oForm;
/** @var bool $bMandatory */
protected $bMandatory;
/** @var bool $bReadOnly */
protected $bReadOnly;
/** @var bool $bAutoApply */
protected $bAutoApply;
/** @var array $aCSSClasses */
protected $aCSSClasses;
/** @var bool $bDisplayed */
protected $bDisplayed;
/** @var array $aWidgetExtraParams */
protected $aWidgetExtraParams;
/**
* DesignerFormField constructor.
*
* @param string $sCode
* @param string $sLabel
* @param mixed $defaultValue
*/
public function __construct($sCode, $sLabel, $defaultValue)
{
$this->sLabel = $sLabel;
@@ -703,7 +720,10 @@ class DesignerFormField
$this->bDisplayed = true;
$this->aWidgetExtraParams = array();
}
/**
* @return string
*/
public function GetCode()
{
return $this->sCode;
@@ -712,69 +732,108 @@ class DesignerFormField
/**
* @param \DesignerForm $oForm
*/
public function SetForm(\DesignerForm $oForm)
public function SetForm(DesignerForm $oForm)
{
$this->oForm = $oForm;
}
/**
* @param bool $bMandatory
*/
public function SetMandatory($bMandatory = true)
{
$this->bMandatory = $bMandatory;
}
/**
* @param bool $bReadOnly
*/
public function SetReadOnly($bReadOnly = true)
{
$this->bReadOnly = $bReadOnly;
}
/**
* @return bool
*/
public function IsReadOnly()
{
return ($this->oForm->IsReadOnly() || $this->bReadOnly);
}
/**
* @param bool $bAutoApply
*/
public function SetAutoApply($bAutoApply)
{
$this->bAutoApply = $bAutoApply;
}
/**
* @return bool
*/
public function IsAutoApply()
{
return $this->bAutoApply;
}
/**
* @param bool $bDisplayed
*/
public function SetDisplayed($bDisplayed)
{
$this->bDisplayed = $bDisplayed;
}
/**
* @return bool
*/
public function IsDisplayed()
{
return $this->bDisplayed;
}
/**
* @return string
*/
public function GetFieldId()
{
return $this->oForm->GetFieldId($this->sCode);
}
/**
* @return string
*/
public function GetWidgetClass()
{
return 'property_field';
}
/**
* @return array
*/
public function GetWidgetExtraParams()
{
return $this->aWidgetExtraParams;
}
/**
* @param \WebPage $oP
* @param string $sFormId
* @param string $sRenderMode
*
* @return array
*/
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
{
$sId = $this->oForm->GetFieldId($this->sCode);
$sName = $this->oForm->GetFieldName($this->sCode);
return array('label' => $this->sLabel, 'value' => "<input type=\"text\" id=\"$sId\" name=\"$sName\" value=\"".htmlentities($this->defaultValue, ENT_QUOTES, 'UTF-8')."\">");
}
/**
* @param array $aValues
*/
public function ReadParam(&$aValues)
{
if ($this->IsReadOnly())
@@ -801,12 +860,18 @@ class DesignerFormField
}
}
}
/**
* @return bool
*/
public function IsVisible()
{
return true;
}
/**
* @param string $sCSSClass
*/
public function AddCSSClass($sCSSClass)
{
$this->aCSSClasses[] = $sCSSClass;
@@ -814,6 +879,8 @@ class DesignerFormField
/**
* A way to set/change the default value after constructing the field
*
* @param array $aAllDefaultValue
*/
public function SetDefaultValueFrom($aAllDefaultValue)
{
@@ -822,7 +889,12 @@ class DesignerFormField
$this->defaultValue = $aAllDefaultValue[$this->GetCode()];
}
}
/**
* @param $sFieldCode
*
* @return \DesignerFormField|false
*/
public function FindField($sFieldCode)
{
if ($this->sCode == $sFieldCode)
@@ -832,11 +904,17 @@ class DesignerFormField
return false;
}
/**
* @return string
*/
public function GetHandlerEquals()
{
return 'null';
}
/**
* @return string
*/
public function GetHandlerGetValue()
{
return 'null';
@@ -845,25 +923,43 @@ class DesignerFormField
class DesignerLabelField extends DesignerFormField
{
/** @var int $iCount A counter to automatically make the field code */
protected static $iCount = 0;
/** @var string $sDescription */
protected $sDescription;
/**
* @inheritdoc
*/
public function __construct($sLabel, $sDescription)
{
parent::__construct('', $sLabel, '');
// Increase counter
static::$iCount++;
parent::__construct('label_number_' . static::$iCount, $sLabel, '');
$this->sDescription = $sDescription;
}
/**
* @inheritdoc
*/
public function Render(WebPage $oP, $sFormId, $sRenderMode='dialog')
{
$sId = $this->oForm->GetFieldId($this->sCode);
$sName = $this->oForm->GetFieldName($this->sCode);
return array('label' => $this->sLabel, 'value' => $this->sDescription);
}
/**
* @inheritdoc
*/
public function ReadParam(&$aValues)
{
}
/**
* @inheritdoc
*/
public function IsVisible()
{
return true;
@@ -1334,7 +1430,8 @@ class DesignerIconSelectionField extends DesignerFormField
$sPostUploadTo = ($this->sUploadUrl == null) ? 'null' : "'{$this->sUploadUrl}'";
if (!$this->IsReadOnly())
{
$sValue = "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"{$this->defaultValue}\"/>";
$sDefaultValue = ($this->defaultValue !== '') ? : $this->aAllowedValues[$idx]['value'];
$sValue = "<input type=\"hidden\" id=\"$sId\" name=\"$sName\" value=\"{$sDefaultValue}\"/>";
$oP->add_ready_script(
<<<EOF
$('#$sId').icon_select({current_idx: $idx, items: $sJSItems, post_upload_to: $sPostUploadTo});

View File

@@ -399,7 +399,6 @@ class ObjectDetailsTemplate extends DisplayTemplate
$aPlugInProperties = $aMatches[1];
foreach($aPlugInProperties as $sPlugInClass)
{
/** @var \iApplicationUIExtension $oInstance */
$oInstance = MetaModel::GetPlugins('iApplicationUIExtension', $sPlugInClass);
if ($oInstance != null) // Safety check...
{

View File

@@ -208,11 +208,6 @@ 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
{

View File

@@ -286,13 +286,11 @@ class UILinksWidgetDirect
* @param DBObject $oCurrentObj
* @param $aAlreadyLinked
*
* @param array $aPrefillFormParam
*
* @throws \CoreException
* @throws \MissingQueryArgument
* @throws \Exception
* @throws \OQLException
*/
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked, $aPrefillFormParam = array())
public function GetObjectsSelectionDlg($oPage, $oCurrentObj, $aAlreadyLinked)
{
$sHtml = "<div class=\"wizContainer\" style=\"vertical-align:top;\">\n";
@@ -335,8 +333,6 @@ 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}",
@@ -363,17 +359,13 @@ 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...
* @param array $aPrefillFormParam
*
* @throws \CoreException
* @throws \OQLException
* @throws Exception
*/
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null, $aPrefillFormParam = array())
public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinked = array(), $oCurrentObj = null)
{
if ($sRemoteClass == '')
{
@@ -403,19 +395,16 @@ 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

View File

@@ -133,15 +133,14 @@ class UILinksWidget
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
$aRow = array();
$aFieldsMap = array();
$iKey = 0;
if(is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
{
$iKey = $linkObjOrId->GetKey();
$key = $linkObjOrId->GetKey();
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
$sPrefix .= "[$iKey][";
$sPrefix .= "[$key][";
$sNameSuffix = "]"; // To make a tabular form
$aArgs['prefix'] = $sPrefix;
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$key}";
$aArgs['this'] = $linkObjOrId;
if($bReadOnly)
@@ -155,7 +154,7 @@ class UILinksWidget
}
else
{
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
$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\">";
foreach($this->m_aEditableFields as $sFieldCode)
{
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']';
@@ -196,30 +195,7 @@ 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=\"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
);
}
$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\">";
foreach($this->m_aEditableFields as $sFieldCode)
{
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.-$iUniqueId.']';
@@ -231,12 +207,20 @@ EOF
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)
@@ -353,19 +337,8 @@ EOF
$sHtmlValue .= "<input type=\"hidden\" id=\"{$sFormPrefix}{$this->m_iInputId}\">\n";
$oValue->Rewind();
$aForm = 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
);
$iAddedId = 1; // Unique id for new links
$aAddedLinks = array();
while($oCurrentLink = $oValue->Fetch())
{
// We try to retrieve the remote object as usual
@@ -384,7 +357,9 @@ EOF
if ($oCurrentLink->IsNew())
{
$key = $iAddedId--;
$key = -($iAddedId++);
$iUniqueId = -$key;
$aAddedLinks[] = array('iAddedId' => $iUniqueId, 'iRemote' => $oCurrentLink->Get($this->m_sExtKeyToRemote));
}
else
{
@@ -393,6 +368,24 @@ 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;\">&nbsp;&nbsp;&nbsp;<img src=\"../images/tv-item-last.gif\">&nbsp;&nbsp;<input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
$sHtmlValue .= "&nbsp;&nbsp;&nbsp;<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";

View File

@@ -602,17 +602,19 @@ class utils
/**
* Format a value into a more friendly format (KB, MB, GB, TB) instead a juste a Bytes amount.
*
* @param type $value
* @param int $value
* @return string
*/
public static function BytesToFriendlyFormat($value)
{
$sReturn = '';
$iPrecision = 0;
// Kilobytes
if ($value >= 1024)
{
$sReturn = 'K';
$value = $value / 1024;
$iPrecision = 1;
}
// Megabytes
if ($value >= 1024)
@@ -633,7 +635,7 @@ class utils
$value = $value / 1024;
}
$value = round($value, 1);
$value = round($value, $iPrecision);
return $value . '' . $sReturn . 'B';
}

3054
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -512,7 +512,7 @@ abstract class AttributeDefinition
}
/**
* @param string|null $sDefault if null, will return the attribute code replacing "_" by " "
* @param string|null $sDefault
*
* @return string
*
@@ -6525,60 +6525,26 @@ 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;
}
$oRemoteAtt = $this->GetExtAttDef();
$sLabel = $oRemoteAtt->GetLabel($this->m_sCode);
$oKeyAtt = $this->GetKeyAttDef();
$sKeyLabel = $oKeyAtt->GetLabel($this->GetKeyAttCode());
$sLabel = "{$sKeyLabel}->{$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}";
}
}
return $sLabel;
}
@@ -7870,87 +7836,6 @@ 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';
@@ -8300,39 +8185,9 @@ class AttributeStopWatch extends AttributeDefinition
*/
class AttributeSubItem extends AttributeDefinition
{
/**
* 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();
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
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()
static public function ListExpectedParams()
{
return array_merge(parent::ListExpectedParams(), array('target_attcode', 'item_code'));
}

View File

@@ -696,8 +696,6 @@ 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
{

View File

@@ -19,7 +19,7 @@
define('ITOP_APPLICATION', 'iTop');
define('ITOP_APPLICATION_SHORT', 'iTop');
define('ITOP_VERSION', '2.6.2');
define('ITOP_VERSION', '2.6.0');
define('ITOP_REVISION', 'svn');
define('ITOP_BUILD_DATE', '$WCNOW$');

File diff suppressed because it is too large Load Diff

View File

@@ -17,22 +17,9 @@
// along with iTop. If not, see <http://www.gnu.org/licenses/>
//
/** @internal Dev hack for disabling some query build optimizations (Folding/Merging) */
// Dev hack for disabling the 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)
@@ -42,23 +29,11 @@ class DBObjectSearch extends DBSearch
private $m_aPointingTo;
private $m_aReferencedBy;
/**
* @var bool whether or not some information should be hidden to the current user. Default to false == hide information.
* @see AllowAllData()
*/
// By default, some information may be hidden to the current user
// But it may happen that we need to disable that feature
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();
@@ -549,7 +524,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
@@ -1667,7 +1642,7 @@ class DBObjectSearch extends DBSearch
// Query caching
//
$sOqlAPCCacheId = null;
if (self::$m_bQueryCacheEnabled && $bCanCache)
if (self::$m_bQueryCacheEnabled)
{
// 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?)
@@ -2369,8 +2344,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

View File

@@ -27,13 +27,9 @@ require_once('dbobjectiterator.php');
/**
* 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.
* A set of persistent objects, could be heterogeneous as long as the objects in the set have a common ancestor class
*
* @package iTopORM
* @api
*/
class DBObjectSet implements iDBObjectSetIterator
{
@@ -85,8 +81,6 @@ 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
@@ -116,9 +110,6 @@ class DBObjectSet implements iDBObjectSetIterator
$this->m_oSQLResult = null;
}
/**
* @internal
*/
public function __destruct()
{
if (is_object($this->m_oSQLResult))
@@ -128,8 +119,6 @@ class DBObjectSet implements iDBObjectSetIterator
}
/**
* @internal
*
* @return string
*
* @throws \Exception
@@ -156,9 +145,6 @@ class DBObjectSet implements iDBObjectSetIterator
return $sRet;
}
/**
* @internal
*/
public function __clone()
{
$this->m_oFilter = $this->m_oFilter->DeepClone();
@@ -172,7 +158,6 @@ class DBObjectSet implements iDBObjectSetIterator
/**
* Called when unserializing a DBObjectSet
* @internal
*/
public function __wakeup()
{
@@ -183,30 +168,18 @@ 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
* this subset is specified for each class of objects,
* this has to be done before the actual fetch.
*
* @api
* Specify the subset of attributes to load (for each class of objects) before performing the SQL query for retrieving the rows from the DB
*
* @param array $aAttToLoad Format: alias => array of attribute_codes
*
@@ -289,8 +262,6 @@ class DBObjectSet implements iDBObjectSetIterator
/**
* Create a set (in-memory) containing just the given object
*
* @internal
*
* @param \DBobject $oObject
*
* @return \DBObjectSet The singleton set
@@ -307,8 +278,6 @@ 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
@@ -328,8 +297,6 @@ 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
*
@@ -347,11 +314,9 @@ 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))
*
@@ -380,9 +345,6 @@ class DBObjectSet implements iDBObjectSetIterator
}
/**
*
* @internal
*
* @param $oObject
* @param string $sLinkSetAttCode
* @param string $sExtKeyToRemote
@@ -409,15 +371,11 @@ 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 DBObject[]
* @return array
*
* @throws \Exception
* @throws \CoreException
@@ -443,14 +401,7 @@ class DBObjectSet implements iDBObjectSetIterator
}
/**
* 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[]
* @return array
*
* @throws \Exception
* @throws \CoreException
@@ -822,7 +773,6 @@ 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
@@ -846,13 +796,11 @@ 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
@@ -883,13 +831,11 @@ 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
@@ -931,11 +877,9 @@ class DBObjectSet implements iDBObjectSetIterator
}
/**
* Fetch an object (with the given class alias) at the current position in the set and move the cursor to the next position.
* Fetch the object (with the given class alias) at the current position in the set and move the cursor to the next position.
*
* @api
*
* @param string $sRequestedClassAlias The class alias to fetch (defaults to the first selected class)
* @param string $sRequestedClassAlias The class alias to fetch (if there are several objects/classes per row)
*
* @return \DBObject The fetched object or null when at the end
*
@@ -989,8 +933,6 @@ 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
@@ -1039,10 +981,8 @@ class DBObjectSet implements iDBObjectSetIterator
/**
* Position the cursor (for iterating in the set) to the first position (equivalent to Seek(0))
*
* @api
*
* @throws \Exception
*
* @throws \Exception
*/
public function Rewind()
{
@@ -1260,9 +1200,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)
{
@@ -1505,8 +1445,6 @@ class DBObjectSet implements iDBObjectSetIterator
/**
* Helper function to perform a custom sort of a hash array
*
* @internal
*/
function HashCountComparison($a, $b) // Sort descending on 'count'
{
@@ -1526,11 +1464,6 @@ 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
{
@@ -1575,8 +1508,6 @@ class DBObjectSetComparator
/**
* Builds the lists of fingerprints and initializes internal structures, if it was not already done
*
* @internal
*
* @throws \CoreException
*/
protected function ComputeFingerprints()
@@ -1626,9 +1557,6 @@ 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
@@ -1675,10 +1603,8 @@ 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
*
* @internal
*
* @return array 'added' => DBObject(s), 'removed' => DBObject(s), 'modified' => DBObjects(s)
* Returns a hash: 'added' => DBObject(s), 'removed' => DBObject(s), 'modified' => DBObjects(s)
* @return array
*
* @throws \Exception
* @throws \CoreException
@@ -1733,9 +1659,7 @@ class DBObjectSetComparator
}
/**
* Helper to clone (in memory) an object and to apply to it the values taken from a second object
*
* @internal
* Helpr to clone (in memory) an object and to apply to it the values taken from a second object
*
* @param \DBObject $oObjToClone
* @param \DBObject $oObjWithValues
@@ -1758,4 +1682,4 @@ class DBObjectSetComparator
}
return $oObj;
}
}
}

View File

@@ -22,35 +22,24 @@ 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 : `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
* 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
*
* @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;
@@ -58,23 +47,14 @@ 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;
}
@@ -82,8 +62,6 @@ 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()
@@ -91,62 +69,22 @@ 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())
@@ -161,36 +99,14 @@ 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))
@@ -203,44 +119,18 @@ 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
*
* 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
*/
* 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
*/
abstract public function ChangeClass($sNewClass, $sAlias = null);
/**
* @internal
* @return mixed
*/
abstract public function GetSelectedClasses();
/**
* @internal
* @param array $aSelectedClasses array of aliases
* @throws CoreException
*/
@@ -249,207 +139,64 @@ 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
*
* @internal
*
* @param string $sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively
* @param 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 mixed $value The value to match (can be an array => IN(val1, val2...)
* @param 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 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)
*
* @param $sExtKeyAttCode
* @param int $iOperatorCode
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
* @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 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)
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
*/
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);
/**
* 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
*/
/**
* @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
*/
public function Join(DBSearch $oFilter, $iDirection, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
{
$oSourceFilter = $this->DeepClone();
@@ -484,68 +231,21 @@ 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
*
* The goal is to easily serialize a search
* Turn the parameters (:xxx) into scalar values in order 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();
@@ -593,10 +293,6 @@ abstract class DBSearch
}
/**
* Convert a serialized query back to an instance of DBSearch
*
* @api
*
* @param string $sValue Serialized OQL query
*
* @return \DBSearch
@@ -640,13 +336,11 @@ abstract class DBSearch
/**
* Create a new DBObjectSearch from $oSearch with a new alias $sAlias
*
* @internal Note : This has not be tested with UNION queries.
* 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)
{
@@ -655,37 +349,12 @@ 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();
/**
* 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
*/
// Do not filter out depending on user rights
// In particular when we are currently in the process of evaluating the user rights...
static public function FromOQL_AllData($sQuery, $aParams = null)
{
$oRes = self::FromOQL($sQuery, $aParams);
@@ -694,19 +363,9 @@ abstract class DBSearch
}
/**
* 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
*
* @param string $sQuery
* @param array $aParams
* @return self
* @throws OQLException
*/
static public function FromOQL($sQuery, $aParams = null)
@@ -783,20 +442,14 @@ 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 The columns you'd like to fetch.
* @param array $aColumns
* @param array $aOrderBy Array of '[<classalias>.]attcode' => bAscending
* @param array $aArgs
*
* @return array|void
*
* @throws \CoreException
* @throws \MissingQueryArgument
* @throws \MySQLException
@@ -853,11 +506,7 @@ abstract class DBSearch
protected static $m_aQueryStructCache = array();
/**
* Generate a Group By SQL query from the current search
*
* @internal
*
/** Generate a Group By SQL request from a search
* @param array $aArgs
* @param array $aGroupByExpr array('alias' => Expression)
* @param bool $bExcludeNullValues
@@ -865,9 +514,7 @@ 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)
@@ -943,10 +590,6 @@ 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
@@ -1041,33 +684,9 @@ 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;
@@ -1108,46 +727,18 @@ 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() {
@@ -1168,78 +759,36 @@ 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)
@@ -1259,16 +808,7 @@ 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)
@@ -1284,15 +824,6 @@ abstract class DBSearch
}
}
/**
* @internal
*
* @param $aQueryData
* @param $sOql
* @param $sSql
*
* @throws MySQLException
*/
protected static function AddQueryTrace($aQueryData, $sOql, $sSql)
{
if (self::$m_bTraceQueries)
@@ -1323,9 +854,6 @@ abstract class DBSearch
}
}
/**
* @internal
*/
public static function RecordQueryTrace()
{
if (!self::$m_bTraceQueries)
@@ -1386,10 +914,6 @@ abstract class DBSearch
file_put_contents($sAllQueries, $sLog);
}
/**
* @internal
* @param $value
*/
protected static function DbgTrace($value)
{
if (!self::$m_bDebugQuery)
@@ -1425,9 +949,7 @@ abstract class DBSearch
/**
* Experimental!
* @todo implement the change tracking
*
* @internal
* todo: implement the change tracking
*
* @param $bArchive
* @throws Exception
@@ -1503,9 +1025,6 @@ abstract class DBSearch
}
}
/**
* @internal
*/
public function UpdateContextFromUser()
{
$this->SetShowObsoleteData(utils::ShowObsoleteData());

View File

@@ -18,21 +18,10 @@
/**
* 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
* A union of DBObjectSearches
*
* @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
@@ -40,15 +29,6 @@ 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)

View File

@@ -243,16 +243,10 @@ 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+\$_.-]*))?)?)';
// 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 = $sUrlPattern . '|' . $sMailtoPattern;
$sPattern = '/'.str_replace('/', '\/', $sPattern).'/i';
self::$aAttrsWhiteList['href'] = $sPattern;
}
@@ -267,7 +261,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|&nbsp;)*</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

View File

@@ -97,9 +97,8 @@ define('MYSQL_ENGINE', 'innodb');
/**
* The objects definitions as well as their mapping to the database
* (API) The objects definitions as well as their mapping to the database
*
* @api
* @package iTopORM
*/
abstract class MetaModel
@@ -1234,7 +1233,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
*
* @return array
@@ -1287,12 +1285,9 @@ abstract class MetaModel
}
/**
* 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
* @param string $sClass
* @param string $sAttCode
* @param bool $bExtended
*
* @return bool
* @throws \Exception
@@ -1346,7 +1341,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
*
@@ -1362,9 +1356,6 @@ abstract class MetaModel
}
/**
* Check if the given class name is actually a persistent class
*
* @api
* @param string $sClass
*
* @return bool
@@ -1639,20 +1630,17 @@ 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
@@ -1665,7 +1653,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
*
@@ -1683,7 +1670,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
*
@@ -1702,7 +1688,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
*
@@ -1720,7 +1705,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
*
@@ -1738,7 +1722,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
*
@@ -1757,7 +1740,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sClass
* @param string $sFilterCode
* @param string $sOpCode
@@ -1777,7 +1759,6 @@ abstract class MetaModel
}
/**
* @deprecated
* @param string $sFilterCode
*
* @return string
@@ -1875,7 +1856,7 @@ abstract class MetaModel
private static $m_aRelationInfos = array();
/**
* @deprecated Use EnumRelationsEx instead
* TO BE DEPRECATED: use EnumRelationsEx instead
*
* @param string $sClass
*
@@ -6662,24 +6643,22 @@ abstract class MetaModel
}
/**
* 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
* Search for the specified class and id.
*
* @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 user rights will be bypassed - use with care!
* @param bool $bAllowAllData if true then no rights filtering
* @param null $aModifierProperties
*
* @return \cmdbAbstractObject null if : (the object is not found) or (archive mode disabled and object is archived and
* @return DBObject|null 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)
{
@@ -6880,11 +6859,8 @@ abstract class MetaModel
}
/**
* 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
* @param string $sClass
* @param array|null $aValues array of attcode => value
*
* @return DBObject
* @throws \CoreException
@@ -6929,8 +6905,6 @@ 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
@@ -6948,8 +6922,6 @@ abstract class MetaModel
* @param DBObjectSearch $oFilter
* @param array $aValues array of attcode => value
*
* @deprecated
* @experimental
* @return int Modified objects
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
@@ -7244,10 +7216,6 @@ 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.'-(>|&gt;)([^\\$]+)\\$/', // Support both syntaxes: $this->xxx$ or $this-&gt;xxx$ for HTML compatibility
'/(%24)'.$sName.'-(>|&gt;)([^%24]+)%24/', // Support for urlencoded in HTML attributes (%20this-&gt;xxx%20)
@@ -7282,28 +7250,8 @@ abstract class MetaModel
}
else
{
$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
}
}
}
}
$aSearches[] = '$'.$sSearch.'$';
$aReplacements[] = (string)$replace;
}
}
return str_replace($aSearches, $aReplacements, $sInput);

View File

@@ -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 = null, $sDBTlsCA = null
$sName, $sDBHost = null, $sDBUser = null, $sDBPwd = null, $bDBTlsEnabled = false, $sDBTlsCA = null
)
{
// Compute the name of a lock for mysql

View File

@@ -126,7 +126,6 @@ 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";
}
@@ -138,7 +137,6 @@ 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";
}

View File

@@ -3,7 +3,7 @@
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
@@ -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,8 +88,7 @@ class SimpleCrypt
}
break;
case 'OpenSSL':
case 'OpenSSLMcryptCompatibility':
if(!function_exists('openssl_decrypt')){
if(!function_exists('openssl_decrypt')){
$sEngineName = 'Simple';
}
break;
@@ -102,30 +101,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"
@@ -136,9 +135,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)
@@ -157,14 +156,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)
@@ -183,10 +182,10 @@ class SimpleCrypt
{
$sRandomBits .= sprintf('%04x', mt_rand(0, 65535));
}
}
return $sRandomBits;
return $sRandomBits;
}
}
@@ -222,7 +221,7 @@ class SimpleCryptSimpleEngine implements CryptEngine
$char = chr(ord($char)+ord($keychar));
$result.=$char;
}
return $result;
return $result;
}
public function Decrypt($key, $encrypted_data)
@@ -236,7 +235,7 @@ class SimpleCryptSimpleEngine implements CryptEngine
$result.=$char;
}
return $result;
}
}
}
/**
@@ -259,13 +258,10 @@ 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_DEV_URANDOM); // MCRYPT_DEV_URANDOM is now useable since itop requires php >= 5.6
if (false === $iv) {
throw new Exception('IV generation failed');
}
$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
mcrypt_generic_init($this->td, $key, $iv);
if (empty($sString))
{
@@ -279,7 +275,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))
{
@@ -292,7 +288,7 @@ class SimpleCryptMcryptEngine implements CryptEngine
}
return $decrypted_data;
}
public function __destruct()
{
mcrypt_module_close($this->td);

View File

@@ -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]{2,}$',
"validation_pattern" => '^[a-zA-Z][a-zA-Z0-9]{3,}$',
)));
MetaModel::Init_AddAttribute(new AttributeString("label", array(
"allowed_values" => null,

View File

@@ -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.2";
$version: "v2.6.1";
// Base colors
$gray-base: #000 !default;

View File

@@ -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.2) no-repeat left;
background: #ea7d1e url(../images/actions_left.png?v=v2.6.1) no-repeat left;
}
.actions_details span {
background: url(../images/actions_right.png?v=v2.6.2) no-repeat right;
background: url(../images/actions_right.png?v=v2.6.1) 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.2) no-repeat top left;
background: #ea7d1e url(../images/actions_left.png?v=v2.6.1) 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.2) no-repeat top right transparent;
background: url(../images/actions_right.png?v=v2.6.1) 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.2) no-repeat;
background: url(../images/calendar.png?v=v2.6.1) 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.2) bottom repeat-x;
background: url(../images/truncated.png?v=v2.6.1) 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.2) bottom repeat-x;
background: #f9f9f1 url(../images/truncated.png?v=v2.6.1) 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.2) bottom repeat-x;
background: #fdf5d0 url(../images/truncated.png?v=v2.6.1) 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.2) bottom repeat-x;
background: #fdf5d0 url(../images/truncated.png?v=v2.6.1) 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.2) left no-repeat;
background: url(../images/itop-logo-2.png?v=v2.6.1) 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.2) center center no-repeat;
background: url(../images/search.png?v=v2.6.1) 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.2) transparent;
background: url(../images/splitter-bkg.png?v=v2.6.1) transparent;
width: 16px;
background-position: -144px -144px;
}
@@ -1830,9 +1830,6 @@ 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; */
@@ -2092,7 +2089,7 @@ img.prev, img.first, img.next, img.last {
}
div.actions_button {
float: right;
background: #ea7d1e url("../images/actions_left.png?v=v2.6.2") no-repeat scroll left top;
background: #ea7d1e url("../images/actions_left.png?v=v2.6.1") no-repeat scroll left top;
padding-left: 5px;
margin-top: 0;
margin-right: 10px;
@@ -2100,7 +2097,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.2) no-repeat scroll right top;
background: #ea7d1e url(../images/actions_bkg.png?v=v2.6.1) no-repeat scroll right top;
color: #fff;
padding-right: 8px;
cursor: pointer;
@@ -2124,10 +2121,10 @@ select#org_id {
cursor: not-allowed;
}
.dragHover {
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.2);
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.1);
}
.edit_mode .dashlet {
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.2);
background: url(./ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png?v=v2.6.1);
padding: 5px;
margin: 0;
position: relative;
@@ -2172,7 +2169,7 @@ table.prop_table {
top: 0;
right: 0;
z-index: 10;
background: transparent url(../images/delete.png?v=v2.6.2) no-repeat center;
background: transparent url(../images/delete.png?v=v2.6.1) no-repeat center;
}
td.prop_value {
text-align: left;
@@ -2393,17 +2390,23 @@ a.summary, a.summary:hover {
}
.message_info {
border: 1px solid #993;
background: url(../images/info-mini.png?v=v2.6.2) 1em 1em no-repeat #ffc;
background: url(../images/info-mini.png?v=v2.6.1) 1em 1em no-repeat #ffc;
padding-left: 3em;
}
.message_ok {
border: 1px solid #393;
background: url(../images/ok.png?v=v2.6.2) 1em 1em no-repeat #cfc;
background: url(../images/ok.png?v=v2.6.1) 1em 1em no-repeat #cfc;
padding-left: 3em;
}
.message_warning {
border: 1px solid #ec9800;
background: url(../images/error.png?v=v2.6.1) 1em 1em no-repeat #ffd78d;
color: #000;
padding-left: 3em;
}
.message_error {
border: 1px solid #933;
background: url(../images/error.png?v=v2.6.2) 1em 1em no-repeat #fcc;
background: url(../images/error.png?v=v2.6.1) 1em 1em no-repeat #fcc;
padding-left: 3em;
}
.fg-menu a img {
@@ -2534,18 +2537,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.2) 2px center no-repeat;
background: url(../images/eye-open-555.png?v=v2.6.1) 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.2) 2px center no-repeat;
background: url(../images/eye-closed-555.png?v=v2.6.1) 2px center no-repeat;
}
.printable-version legend {
padding-left: 26px;
background: #1c94c4 url(../images/eye-open-fff.png?v=v2.6.2) 8px center no-repeat;
background: #1c94c4 url(../images/eye-open-fff.png?v=v2.6.1) 8px center no-repeat;
}
.printable-version .strikethrough legend {
background: #1c94c4 url(../images/eye-closed-fff.png?v=v2.6.2) 8px center no-repeat;
background: #1c94c4 url(../images/eye-closed-fff.png?v=v2.6.1) 8px center no-repeat;
}
.printable-version fieldset.strikethrough span {
display: none;
@@ -2696,7 +2699,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.2);
background-image: url(../images/breadcrumb-separator.png?v=v2.6.1);
background-repeat: no-repeat;
width: 8px;
height: 16px;
@@ -2930,6 +2933,17 @@ table.listResults .originColor {
.menu-icon-select > .ui-menu-item {
padding: 0.3em 3%;
}
.menu-icon-select > .ui-menu-item > * {
width: 100%;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.menu-icon-select > .ui-menu-item > * > img {
max-width: 80px;
max-height: 45px;
margin-right: 10px;
}
.attribute.attribute-set .attribute-set-item::after {
content: ",";
margin-right: 0.5em;

View File

@@ -2115,11 +2115,6 @@ 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; */
@@ -2767,6 +2762,12 @@ a.summary, a.summary:hover {
background: url(../images/ok.png?v=#{$version}) 1em 1em no-repeat #cfc;
padding-left: 3em;
}
.message_warning {
border: 1px solid #ec9800;
background: url(../images/error.png?v=#{$version}) 1em 1em no-repeat #ffd78d;
color: #000;
padding-left: 3em;
}
.message_error {
border: 1px solid #933;
background: url(../images/error.png?v=#{$version}) 1em 1em no-repeat #fcc;
@@ -3358,6 +3359,19 @@ table.listResults .originColor{
}
.menu-icon-select > .ui-menu-item{
padding: .3em 3%;
> *{
width: 100%;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
> img{
max-width: 80px;
max-height: 45px;
margin-right: 10px;
}
}
}
//////////////////////

View File

@@ -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.
*

View File

@@ -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.2',
'authent-external/2.6.1',
array(
// Identification
//

View File

@@ -1,38 +0,0 @@
<?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+' => '',
));

View File

@@ -2,7 +2,6 @@
/**
* Localized data
*
* @author Robert Deng <denglx@gmail.com>
* @copyright Copyright (C) 2010-2018 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*

View File

@@ -38,6 +38,4 @@
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+' => '',
));

View File

@@ -16,13 +16,11 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* @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',
));

View File

@@ -25,6 +25,4 @@
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',
));

View File

@@ -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,6 +38,4 @@
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',
));

View File

@@ -37,6 +37,4 @@
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',
));

View File

@@ -22,6 +22,4 @@
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+' => '',
));

View File

@@ -22,6 +22,4 @@
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'Class:UserLDAP' => 'LDAP felhasználó',
'Class:UserLDAP+' => '',
'Class:UserLDAP/Attribute:password' => 'Jelszó',
'Class:UserLDAP/Attribute:password+' => '',
));

View File

@@ -36,6 +36,4 @@
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',
));

View File

@@ -16,13 +16,11 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* @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+' => '認証文字列',
));

View File

@@ -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.2',
'authent-ldap/2.6.1',
array(
// Identification
//

View File

@@ -36,6 +36,4 @@
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~~',
));

View File

@@ -22,6 +22,4 @@
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+' => '',
));

View File

@@ -14,6 +14,4 @@
Dict::Add('RU RU', 'Russian', 'Русский', array(
'Class:UserLDAP' => 'Пользователь LDAP',
'Class:UserLDAP+' => 'Пользователь, аутентифицируемый через LDAP',
'Class:UserLDAP/Attribute:password' => 'Пароль',
'Class:UserLDAP/Attribute:password+' => 'Строка аутентификации пользователя',
));

View File

@@ -1,40 +0,0 @@
<?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+' => '',
));

View File

@@ -37,6 +37,4 @@
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',
));

View File

@@ -2,7 +2,6 @@
/**
* Localized data
*
* @author Robert Deng <denglx@gmail.com>
* @copyright Copyright (C) 2010-2018 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*
@@ -36,6 +35,4 @@
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:UserLDAP' => 'LDAP 用户',
'Class:UserLDAP+' => '用户身份由LDAP 认证',
'Class:UserLDAP/Attribute:password' => '密码',
'Class:UserLDAP/Attribute:password+' => '用于验证用户身份的字符串',
));

View File

@@ -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.
*

View File

@@ -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.2',
'authent-local/2.6.1',
array(
// Identification
//

View File

@@ -1,40 +0,0 @@
<?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+' => '',
));

View File

@@ -2,7 +2,6 @@
/**
* Localized data
*
* @author Robert Deng <denglx@gmail.com>
* @copyright Copyright (C) 2010-2018 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*

View File

@@ -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.
*

View File

@@ -19,7 +19,7 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'itop-attachments/2.6.2',
'itop-attachments/2.6.1',
array(
// Identification
//

View File

@@ -1,59 +0,0 @@
<?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/>
*/
Dict::Add('SK SK', 'Slovak', 'Slovenčina', array(
'Attachments:TabTitle_Count' => 'Prílohy (%1$d)',
'Attachments:EmptyTabTitle' => 'Prílohy',
'Attachments:FieldsetTitle' => 'Prílohy',
'Attachments:DeleteBtn' => 'Odstrániť',
'Attachments:History_File_Added' => 'Príloha %1$s pridaná.',
'Attachments:History_File_Removed' => 'Príloha %1$s odstránená.',
'Attachments:AddAttachment' => 'Pridaj prílohu: ',
'Attachments:UploadNotAllowedOnThisSystem' => 'Nahrávanie súboru NIE JE povolené na tomto systéme.',
'Attachment:Max_Go' => '(Maximálna Veľkosť súboru : %1$s Go)',
'Attachment:Max_Mo' => '(Maximálna Veľkosť súboru : %1$s Mo)',
'Attachment:Max_Ko' => '(Maximálna Veľkosť súboru : %1$s Ko)',
'Attachments:NoAttachment' => 'Bez prílohy. ',
'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('SK SK', 'Slovak', 'Slovenčina', 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+' => '~~',
));

View File

@@ -26,7 +26,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'bkp-week-days' => 'Záloha bude provedena <b>vždy v %1$s v %2$s</b>',
'bkp-retention' => 'V cílové složce <b>bude uchováno maximálně %1$d souborů záloh</b>.',
'bkp-next-to-delete' => 'Bude odstraněna při další záloze (nastavení "retention_count")',
'bkp-table-file' => 'Soubor',
'bkp-table-file' => 'Soubor',
'bkp-table-file+' => 'Pouze soubory s příponou .zip jsou považovány za soubory zálohy.',
'bkp-table-size' => 'Velikost',
'bkp-table-size+' => '',

View File

@@ -39,7 +39,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'bkp-week-days' => 'Backups will occur <b>every %1$s at %2$s</b>~~',
'bkp-retention' => 'At most <b>%1$d backup files will be kept</b> in the target directory.~~',
'bkp-next-to-delete' => 'Will be deleted when the next backup occurs (see the setting "retention_count")~~',
'bkp-table-file' => 'File~~',
'bkp-table-file' => 'File~~',
'bkp-table-file+' => 'Only files having the extension .zip are considered as being backup files~~',
'bkp-table-size' => 'Size~~',
'bkp-table-size+' => '~~',

View File

@@ -41,7 +41,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'bkp-week-days' => 'Backups werden <b>jeden %1$s um %2$s durchgeführt</b>',
'bkp-retention' => 'Mindestens <b>%1$d Backups werden im Zielverzeichniss vorgehalten</b>',
'bkp-next-to-delete' => 'Wird gelöscht, wenn das nächste Backup angelegt wird (unter Einstellungen "Menge vorhalten")',
'bkp-table-file' => 'Datei',
'bkp-table-file' => 'Datei',
'bkp-table-file+' => 'Nur Dateien mit der Endung .zip werden als Backup-Dateien berücksichtigt.',
'bkp-table-size' => 'Grösse',
'bkp-table-size+' => '',

View File

@@ -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.
*
@@ -40,7 +40,7 @@ Dict::Add('EN US', 'English', 'English', array(
'bkp-week-days' => 'Backups will occur <b>every %1$s at %2$s</b>',
'bkp-retention' => 'At most <b>%1$d backup files will be kept</b> in the target directory.',
'bkp-next-to-delete' => 'Will be deleted when the next backup occurs (see the setting "retention_count")',
'bkp-table-file' => 'File',
'bkp-table-file' => 'File',
'bkp-table-file+' => 'Only files having the extension .zip are considered as being backup files',
'bkp-table-size' => 'Size',
'bkp-table-size+' => '',

View File

@@ -39,7 +39,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
'bkp-week-days' => 'Respaldos se realizaran <b>cada %1$s a %2$s</b>',
'bkp-retention' => 'Al menos <b>%1$d archivos de respaldo serán conservados</b> en el directorio destino.',
'bkp-next-to-delete' => 'Serán borrados cuando el siguiente respaldo ocurra (ver configuración "retention_count")',
'bkp-table-file' => 'Archivo',
'bkp-table-file' => 'Archivo',
'bkp-table-file+' => 'Solo archivos con la extensión .zip son considerados como archivos de respaldos',
'bkp-table-size' => 'Tamaño',
'bkp-table-size+' => '',

View File

@@ -24,7 +24,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
'bkp-week-days' => 'Les sauvegardes seront effectuées <b>tous les %1$s à %2$s</b>',
'bkp-retention' => 'Au plus <b>%1$d fichiers de sauvegardes seront conservés</b> dans le répertoire cible.',
'bkp-next-to-delete' => 'Sera effacé lors de la prochaine sauvegarde (Cf. réglage "retention_count")',
'bkp-table-file' => 'Fichier',
'bkp-table-file' => 'Fichier',
'bkp-table-file+' => 'Seuls les fichiers ayant l\'extension .zip sont considérés comme étant des fichiers de sauvegarde',
'bkp-table-size' => 'Taille',
'bkp-table-size+' => '',

View File

@@ -39,7 +39,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'bkp-week-days' => 'Backups will occur <b>every %1$s at %2$s</b>~~',
'bkp-retention' => 'At most <b>%1$d backup files will be kept</b> in the target directory.~~',
'bkp-next-to-delete' => 'Will be deleted when the next backup occurs (see the setting "retention_count")~~',
'bkp-table-file' => 'File~~',
'bkp-table-file' => 'File~~',
'bkp-table-file+' => 'Only files having the extension .zip are considered as being backup files~~',
'bkp-table-size' => 'Size~~',
'bkp-table-size+' => '~~',

View File

@@ -39,7 +39,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'bkp-week-days' => 'Backups will occur <b>every %1$s at %2$s</b>~~',
'bkp-retention' => 'At most <b>%1$d backup files will be kept</b> in the target directory.~~',
'bkp-next-to-delete' => 'Will be deleted when the next backup occurs (see the setting "retention_count")~~',
'bkp-table-file' => 'File~~',
'bkp-table-file' => 'File~~',
'bkp-table-file+' => 'Only files having the extension .zip are considered as being backup files~~',
'bkp-table-size' => 'Size~~',
'bkp-table-size+' => '~~',

View File

@@ -39,7 +39,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'bkp-week-days' => 'Backups will occur <b>every %1$s at %2$s</b>~~',
'bkp-retention' => 'At most <b>%1$d backup files will be kept</b> in the target directory.~~',
'bkp-next-to-delete' => 'Will be deleted when the next backup occurs (see the setting "retention_count")~~',
'bkp-table-file' => 'File~~',
'bkp-table-file' => 'File~~',
'bkp-table-file+' => 'Only files having the extension .zip are considered as being backup files~~',
'bkp-table-size' => 'Size~~',
'bkp-table-size+' => '~~',

View File

@@ -3,7 +3,7 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'itop-backup/2.6.2',
'itop-backup/2.6.1',
array(
// Identification
//

View File

@@ -40,7 +40,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'bkp-week-days' => 'Backups gebeuren <b>elke %1$s om %2$s</b>',
'bkp-retention' => 'Maximaal <b>%1$d backup-bestanden blijven bewaard</b> in de doelmap.',
'bkp-next-to-delete' => 'Zal verwijderd worden bij de volgende backuptaak (volgens de instelling "retention_count")',
'bkp-table-file' => 'Bestand',
'bkp-table-file' => 'Bestand',
'bkp-table-file+' => 'Enkel .ZIP-bestanden worden beschouwd als backupbestanden.',
'bkp-table-size' => 'Grootte',
'bkp-table-size+' => '',

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