Compare commits

..

1 Commits
2.5.1 ... 2.5.0

Author SHA1 Message Date
Guillaume Lajarige
eadb11ce39 Creating SVN tag for iTop 2.5.0
SVN:2.5.0[5921]
2018-06-28 08:24:45 +00:00
76 changed files with 5137 additions and 6691 deletions

122
.gitignore vendored
View File

@@ -1,122 +0,0 @@
/toolkit/
/conf/*
/env-*/*
# composer reserver directory, from sources, populate/update using "composer install"
vendor/*
test/vendor/*
# all datas but listing prevention
data/*
!data/.htaccess
!data/index.php
!data/web.config
# iTop extensions
extensions/*
!extensions/readme.txt
# all logs but listing prevention
log/*
!log/.htaccess
!log/index.php
!log/web.config
# Jetbrains
.idea/**
!.idea/encodings.xml
!.idea/codeStyles
!.idea/codeStyles/*
!.idea/inspectionProfiles
!.idea/inspectionProfiles/*
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
### Eclipse template
.metadata
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet

View File

@@ -1,45 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<PHPCodeStyleSettings>
<option name="CONCAT_SPACES" value="false" />
<option name="PHPDOC_BLANK_LINE_BEFORE_TAGS" value="true" />
<option name="PHPDOC_BLANK_LINES_AROUND_PARAMETERS" value="true" />
<option name="PHPDOC_WRAP_LONG_LINES" value="true" />
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
<option name="LOWER_CASE_NULL_CONST" value="true" />
<option name="BLANK_LINES_BEFORE_RETURN_STATEMENT" value="1" />
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
<option name="PHPDOC_USE_FQCN" value="true" />
</PHPCodeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="BRACE_STYLE" value="2" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="BLANK_LINES_AFTER_PACKAGE" value="1" />
<option name="BRACE_STYLE" value="2" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Combodo" />
</state>
</component>

6
.idea/encodings.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@@ -1,154 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="BladeControlDirectives" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckEmptyScriptTag" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckImageSize" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckNodeTest" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckTagEmptyBody" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckValidXmlInScriptTagBody" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptArgumentsOutsideFunction" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptFunctionSignatures" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptInfiniteLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptLiteralNotFunction" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptSillyAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptSwitchStatementWithNoDefaultBranch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptUnusedLocalSymbols" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ComposeFileStructure" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssFloatPxLength" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidAtRule" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidCharsetRule" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidElement" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidFunction" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidHtmlTagReference" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidImport" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidMediaFeature" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidPropertyValue" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidPseudoSelector" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssMissingComma" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssNegativeValue" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssNoGenericFontName" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssOptimizeSimilarProperties" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="CssOverwrittenProperties" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssRedundantUnit" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssUnitlessNumber" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssUnknownProperty" enabled="false" level="WARNING" enabled_by_default="false">
<option name="myCustomPropertiesEnabled" value="false" />
<option name="myIgnoreVendorSpecificProperties" value="false" />
<option name="myCustomPropertiesList">
<value>
<list size="0" />
</value>
</option>
</inspection_tool>
<inspection_tool class="CssUnknownTarget" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnresolvedClass" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnresolvedCustomProperty" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnresolvedCustomPropertySet" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnusedSymbol" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CucumberExamplesColon" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CucumberMissedExamples" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CucumberTableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CucumberUndefinedStep" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DockerFileArgumentCount" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="DuplicateKeyInSection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateSectionInFile" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyEventHandler" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FileHeaderInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="GherkinBrokenTableInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="GherkinMisplacedBackground" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="HamlNestedTagContent" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HardwiredNamespacePrefix" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlDeprecatedTag" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlExtraClosingTag" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlFormInputWithoutLabel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlMissingClosingTag" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="HtmlPresentationalElement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlUnknownAnchorTarget" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlUnknownAttribute" enabled="false" level="WARNING" enabled_by_default="false">
<option name="myValues">
<value>
<list size="0" />
</value>
</option>
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
<inspection_tool class="HtmlUnknownBooleanAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlUnknownTag" enabled="false" level="WARNING" enabled_by_default="false">
<option name="myValues">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="nobr" />
<item index="1" class="java.lang.String" itemvalue="noembed" />
<item index="2" class="java.lang.String" itemvalue="comment" />
<item index="3" class="java.lang.String" itemvalue="noscript" />
<item index="4" class="java.lang.String" itemvalue="embed" />
<item index="5" class="java.lang.String" itemvalue="script" />
</list>
</value>
</option>
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
<inspection_tool class="HtmlUnknownTarget" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ImplicitTypeConversion" enabled="false" level="WARNING" enabled_by_default="false">
<option name="BITS" value="1720" />
<option name="FLAG_EXPLICIT_CONVERSION" value="true" />
<option name="IGNORE_NODESET_TO_BOOLEAN_VIA_STRING" value="true" />
</inspection_tool>
<inspection_tool class="IndexZeroUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSLastCommaInArrayLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSLastCommaInObjectLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnresolvedFunction" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnresolvedVariable" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="LossyEncoding" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MissingSinceTagDocInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="MysqlParsingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NonAsciiCharacters" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpDocMissingReturnTagInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PhpDocMissingThrowsInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PhpIncludeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpRedundantClosingTagInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedClassConstantInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedClassInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedConstantInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedFieldInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedFunctionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedGotoLabelInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUndefinedNamespaceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpUnusedParameterInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantTypeConversion" enabled="false" level="WARNING" enabled_by_default="false">
<option name="CHECK_ANY" value="false" />
</inspection_tool>
<inspection_tool class="RequiredAttributes" enabled="false" level="WARNING" enabled_by_default="false">
<option name="myAdditionalRequiredHtmlAttributes" value="" />
</inspection_tool>
<inspection_tool class="SqlAddNotNullColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlAmbiguousColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlAutoIncrementDuplicateInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlCheckUsingColumnsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlConstantConditionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDeprecateTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDerivedTableAliasInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDropIndexedColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlIdentifierInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlInsertValuesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlNullComparisonInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlPostgresqlSelectFromProcedureInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlResolveInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlShouldBeInGroupByInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlSignatureInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlStorageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlUnusedVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TaskProblemsInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptPreferShortImport" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlDefaultAttributeValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlUnboundNsPrefix" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlUnusedNamespaceDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XsltUnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XsltVariableShadowing" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

View File

@@ -1,14 +0,0 @@
#!/usr/bin/env bash
set -x
# create target dirs
mkdir -p var
mkdir -p toolkit
# cleanup target dirs
rm -rf toolkit/*
# fill target dirs
curl http://www.combodo.com/documentation/iTopDataModelToolkit-2.3.zip | tar xvz --directory toolkit
cp -r .jenkins/configuration/default-environment/unattended_install/* toolkit

View File

@@ -1,11 +0,0 @@
#!/usr/bin/env bash
set -x
# on the root dir
composer install
# under the test dir
cd test
composer install

View File

@@ -1,13 +0,0 @@
#!/usr/bin/env bash
set -x
whoami
pwd
ls
echo "$BRANCH_NAME:${BRANCH_NAME}"
echo "printenv :"
printenv

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
set -x
cd test
export DEBUG_UNIT_TEST="0"
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -x
cd toolkit
php unattended_install.php default-params.xml

View File

@@ -1,285 +0,0 @@
<?php
/**
*
* Configuration file, generated by the iTop configuration wizard
*
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
*
*/
$MySettings = array(
// access_message: Message displayed to the users when there is any access restriction
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
// default: 3
'access_mode' => 3,
'allowed_login_types' => 'form|basic|external',
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
// default: true
'apc_cache.enabled' => true,
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
// default: 3600
'apc_cache.query_ttl' => 3600,
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
// default: ''
'app_root_url' => 'http://127.0.0.1/itop/svn/trunk/',
// buttons_position: Position of the forms buttons: bottom | top | both
// default: 'both'
'buttons_position' => 'both',
// cas_include_path: The path where to find the phpCAS library
// default: '/usr/share/php'
'cas_include_path' => '/usr/share/php',
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
// default: 600
'cron_max_execution_time' => 600,
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
// default: 'ISO-8859-1'
'csv_file_default_charset' => 'ISO-8859-1',
'csv_import_charsets' => array (
),
// csv_import_history_display: Display the history tab in the import wizard
// default: false
'csv_import_history_display' => false,
// date_and_time_format: Format for date and time display (per language)
// default: array (
// 'default' =>
// array (
// 'date' => 'Y-m-d',
// 'time' => 'H:i:s',
// 'date_time' => '$date $time',
// ),
// )
'date_and_time_format' => array (
'default' =>
array (
'date' => 'Y-m-d',
'time' => 'H:i:s',
'date_time' => '$date $time',
),
'FR FR' =>
array (
'date' => 'd/m/Y',
'time' => 'H:i:s',
'date_time' => '$date $time',
),
),
'db_host' => '',
'db_name' => 'itop_ci_main',
'db_pwd' => 'c8mb0do',
'db_subname' => '',
'db_user' => 'root',
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
// default: '$difference$'
'deadline_format' => '$difference$',
'default_language' => 'EN US',
// disable_attachments_download_legacy_portal: Disable attachments download from legacy portal
// default: true
'disable_attachments_download_legacy_portal' => true,
// draft_attachments_lifetime: Lifetime (in seconds) of drafts' attachments and inline images: after this duration, the garbage collector will delete them.
// default: 3600
'draft_attachments_lifetime' => 3600,
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
// default: false
'email_asynchronous' => false,
// email_default_sender_address: Default address provided in the email from header field.
// default: ''
'email_default_sender_address' => '',
// email_default_sender_label: Default label provided in the email from header field.
// default: ''
'email_default_sender_label' => '',
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocole)
// default: 'PHPMail'
'email_transport' => 'SMTP',
// email_transport_smtp.host: host name or IP address (optional)
// default: 'localhost'
'email_transport_smtp.host' => 'smtp.combodo.com',
// email_transport_smtp.password: Authentication password (optional)
// default: ''
'email_transport_smtp.password' => '++combodo++',
// email_transport_smtp.port: port number (optional)
// default: 25
'email_transport_smtp.port' => 25,
// email_transport_smtp.username: Authentication user (optional)
// default: ''
'email_transport_smtp.username' => 'test2@combodo.com',
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
'encryption_key' => '@iT0pEncr1pti0n!',
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
'fast_reload_interval' => '60',
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
// default: '/usr/bin/dot'
'graphviz_path' => '/usr/bin/dot',
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
// default: '250'
'inline_image_max_display_width' => 250,
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
// default: '1600'
'inline_image_max_storage_width' => 1600,
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
// default: '\''
'link_set_attribute_qualifier' => '\'',
// link_set_attribute_separator: Link set from string: attribute separator
// default: ';'
'link_set_attribute_separator' => ';',
// link_set_item_separator: Link set from string: line separator
// default: '|'
'link_set_item_separator' => '|',
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
// default: ':'
'link_set_value_separator' => ':',
'log_global' => true,
'log_issue' => true,
'log_notification' => true,
'log_web_service' => true,
// max_combo_length: The maximum number of elements in a drop-down list. If more then an autocomplete will be used
// default: 50
'max_combo_length' => 50,
'max_display_limit' => '15',
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
// default: 100
'max_linkset_output' => 100,
'min_display_limit' => '10',
// online_help: Hyperlink to the online-help web page
// default: 'http://www.combodo.com/itop-help'
'online_help' => 'http://www.combodo.com/itop-help',
// php_path: Path to the php executable in CLI mode
// default: 'php'
'php_path' => 'php',
// portal_tickets: CSV list of classes supported in the portal
// default: 'UserRequest'
'portal_tickets' => 'UserRequest',
'query_cache_enabled' => true,
// search_manual_submit: Force manual submit of search requests (class => true)
// default: false
'search_manual_submit' => array (
'Person' => true,
),
'secure_connection_required' => false,
// session_name: The name of the cookie used to store the PHP session id
// default: 'iTop'
'session_name' => 'iTop',
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
// default: 'UI:Menu:Modify,UI:Menu:New'
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
// default: ''
'source_dir' => 'datamodels/2.x/',
'standard_reload_interval' => '300',
// synchro_trace: Synchronization details: none, display, save (includes 'display')
// default: 'none'
'synchro_trace' => 'none',
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitely configured in PHP
// default: 'Europe/Paris'
'timezone' => 'Europe/Paris',
// tracking_level_linked_set_default: Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
// default: 1
'tracking_level_linked_set_default' => 0,
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
);
/**
*
* Modules specific settings
*
*/
$MyModuleSettings = array(
'itop-attachments' => array (
'allowed_classes' => array (
0 => 'Ticket',
),
'position' => 'relations',
'preview_max_width' => 290,
),
'itop-backup' => array (
'mysql_bindir' => '',
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
'time' => '23:30',
'retention_count' => 5,
'enabled' => true,
'debug' => false,
),
'molkobain-console-tooltips' => array (
'decoration_class' => 'fas fa-question',
'enabled' => true,
),
);
/**
*
* Data model modules to be loaded. Names are specified as relative paths
*
*/
$MyModules = array(
'addons' => array (
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
),
);
?>

View File

@@ -1,69 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<installation>
<mode>upgrade</mode>
<preinstall>
<copies type="array"/>
</preinstall>
<source_dir>datamodels/2.x/</source_dir>
<datamodel_version>2.5.0</datamodel_version>
<previous_configuration_file>/var/lib/jenkins/workspace/iTop-CI/unattended_install/default-config-itop.php</previous_configuration_file>
<extensions_dir>extensions</extensions_dir>
<target_env>production</target_env>
<workspace_dir></workspace_dir>
<database>
<server></server>
<user>root</user>
<pwd>c8mb0do</pwd>
<name>itop_ci</name>
<db_tls_enabled></db_tls_enabled>
<db_tls_ca></db_tls_ca>
<prefix></prefix>
</database>
<url>http://127.0.0.1/itop/svn/trunk/</url>
<graphviz_path>/usr/bin/dot</graphviz_path>
<admin_account>
<user>admin</user>
<pwd>admin</pwd>
<language>EN US</language>
</admin_account>
<language>EN US</language>
<selected_modules type="array">
<item>authent-external</item>
<item>authent-local</item>
<item>itop-backup</item>
<item>itop-config</item>
<item>itop-profiles-itil</item>
<item>itop-sla-computation</item>
<item>itop-tickets</item>
<item>itop-welcome-itil</item>
<item>itop-config-mgmt</item>
<item>itop-attachments</item>
<item>itop-datacenter-mgmt</item>
<item>itop-endusers-devices</item>
<item>itop-storage-mgmt</item>
<item>itop-virtualization-mgmt</item>
<item>itop-bridge-virtualization-storage</item>
<item>itop-service-mgmt</item>
<item>itop-request-mgmt</item>
<item>itop-portal</item>
<item>itop-portal-base</item>
<item>itop-change-mgmt</item>
</selected_modules>
<selected_extensions type="array">
<item>itop-config-mgmt-core</item>
<item>itop-config-mgmt-datacenter</item>
<item>itop-config-mgmt-end-user</item>
<item>itop-config-mgmt-storage</item>
<item>itop-config-mgmt-virtualization</item>
<item>itop-service-mgmt-enterprise</item>
<item>itop-ticket-mgmt-simple-ticket</item>
<item>itop-ticket-mgmt-simple-ticket-enhanced-portal</item>
<item>itop-change-mgmt-simple</item>
</selected_extensions>
<sample_data>1</sample_data>
<old_addon></old_addon>
<options>
<generate_config>1</generate_config>
</options>
<mysql_bindir></mysql_bindir>
</installation>

View File

@@ -1,190 +0,0 @@
<?php
//this scrit will be run under the ./toolkit directory, relatively to the document root
require_once('../approot.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/application/clipage.class.inc.php');
require_once(APPROOT.'/core/config.class.inc.php');
require_once(APPROOT.'/core/log.class.inc.php');
require_once(APPROOT.'/core/kpi.class.inc.php');
require_once(APPROOT.'/core/cmdbsource.class.inc.php');
require_once(APPROOT.'/setup/setuppage.class.inc.php');
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
require_once(APPROOT.'/setup/applicationinstaller.class.inc.php');
/////////////////////////////////////////////////
$sParamFile = utils::ReadParam('response_file', 'default-params.xml', true /* CLI allowed */, 'raw_data');
$bCheckConsistency = (utils::ReadParam('check_consistency', '0', true /* CLI allowed */) == '1');
$oParams = new XMLParameters($sParamFile);
$sMode = $oParams->Get('mode');
if ($sMode == 'install')
{
echo "Installation mode detected.\n";
$bClean = utils::ReadParam('clean', false, true /* CLI allowed */);
if ($bClean)
{
echo "Cleanup mode detected.\n";
$sTargetEnvironment = $oParams->Get('target_env', '');
if ($sTargetEnvironment == '')
{
$sTargetEnvironment = 'production';
}
$sTargetDir = APPROOT.'env-'.$sTargetEnvironment;
// Configuration file
$sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
if (file_exists($sConfigFile))
{
echo "Trying to delete the configuration file: '$sConfigFile'.\n";
@chmod($sConfigFile, 0770); // RWX for owner and group, nothing for others
unlink($sConfigFile);
}
else
{
echo "No config file to delete ($sConfigFile does not exist).\n";
}
// env-xxx directory
if (file_exists($sTargetDir))
{
if (is_dir($sTargetDir))
{
echo "Emptying the target directory '$sTargetDir'.\n";
SetupUtils::tidydir($sTargetDir);
}
else
{
die("ERROR the target dir '$sTargetDir' exists, but is NOT a directory !!!\nExiting.\n");
}
}
else
{
echo "No target directory to delete ($sTargetDir does not exist).\n";
}
// Database
$aDBSettings = $oParams->Get('database', array());
$sDBServer = $aDBSettings['server'];
$sDBUser = $aDBSettings['user'];
$sDBPwd = $aDBSettings['pwd'];
$sDBName = $aDBSettings['name'];
$sDBPrefix = $aDBSettings['prefix'];
if ($sDBPrefix != '')
{
die("Cleanup not implemented for a partial database (prefix= '$sDBPrefix')\nExiting.");
}
$oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
if ($oMysqli->connect_errno)
{
die("Cannot connect to the MySQL server (".$mysqli->connect_errno . ") ".$mysqli->connect_error."\nExiting");
}
else
{
if ($oMysqli->select_db($sDBName))
{
echo "Deleting database '$sDBName'\n";
$oMysqli->query("DROP DATABASE `$sDBName`");
}
else
{
echo "The database '$sDBName' does not seem to exist. Nothing to cleanup.\n";
}
}
}
}
$bHasErrors = false;
$aChecks = SetupUtils::CheckBackupPrerequisites(APPROOT.'data'); // mmm should be the backup destination dir
$aSelectedModules = $oParams->Get('selected_modules');
$sSourceDir = $oParams->Get('source_dir', 'datamodels/latest');
$sExtensionDir = $oParams->Get('extensions_dir', 'extensions');
$aChecks = array_merge($aChecks, SetupUtils::CheckSelectedModules($sSourceDir, $sExtensionDir, $aSelectedModules));
foreach($aChecks as $oCheckResult)
{
switch($oCheckResult->iSeverity)
{
case CheckResult::ERROR:
$bHasErrors = true;
$sHeader = "Error";
break;
case CheckResult::WARNING:
$sHeader = "Warning";
break;
case CheckResult::INFO:
default:
$sHeader = "Info";
break;
}
echo $sHeader.": ".$oCheckResult->sLabel;
if (strlen($oCheckResult->sDescription))
{
echo ' - '.$oCheckResult->sDescription;
}
echo "\n";
}
if ($bHasErrors)
{
echo "Encountered stopper issues. Aborting...\n";
die;
}
$bFoundIssues = false;
$bInstall = utils::ReadParam('install', true, true /* CLI allowed */);
if ($bInstall)
{
echo "Starting the unattended installation...\n";
$oWizard = new ApplicationInstaller($oParams);
$bRes = $oWizard->ExecuteAllSteps();
if (!$bRes)
{
echo "\nencountered installation issues!";
$bFoundIssues = true;
}
}
else
{
echo "No installation requested.\n";
}
if (!$bFoundIssues && $bCheckConsistency)
{
echo "Checking data model consistency.\n";
ob_start();
$sCheckRes = '';
try
{
MetaModel::CheckDefinitions(false);
$sCheckRes = ob_get_clean();
}
catch(Exception $e)
{
$sCheckRes = ob_get_clean()."\nException: ".$e->getMessage();
}
if (strlen($sCheckRes) > 0)
{
echo $sCheckRes;
echo "\nfound consistency issues!";
$bFoundIssues = true;
}
}
if (!$bFoundIssues)
{
// last line: used to check the install
// the only way to track issues in case of Fatal error or even parsing error!
echo "\ninstalled!";
exit;
}

62
Jenkinsfile vendored
View File

@@ -1,62 +0,0 @@
pipeline {
agent any
stages {
stage('init') {
parallel {
stage('debug') {
steps {
sh './.jenkins/bin/init/debug.sh'
}
}
stage('append files to project') {
steps {
sh './.jenkins/bin/init/append_files.sh'
}
}
stage('composer install') {
steps {
sh './.jenkins/bin/init/composer_install.sh'
}
}
}
}
stage('unattended_install') {
parallel {
stage('unattended_install default env') {
steps {
sh './.jenkins/bin/unattended_install/default_env.sh'
}
}
}
}
stage('test') {
parallel {
stage('phpunit') {
steps {
sh './.jenkins/bin/tests/phpunit.sh'
}
}
}
}
}
post {
always {
junit 'var/test/phpunit-log.junit.xml'
}
failure {
slackSend(channel: "#jenkins-itop", color: '#FF0000', message: "Ho no! Build failed! (${currentBuild.result}), Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
}
environment {
DEBUG_UNIT_TEST = '0'
}
options {
timeout(time: 20, unit: 'MINUTES')
}
}

View File

@@ -402,9 +402,9 @@ class URP_UserOrg extends UserRightsBaseClassGUI
*/
protected function CheckIfOrgIsAllowed()
{
if (!UserRights::IsLoggedIn() || UserRights::IsAdministrator()) { return; }
if (UserRights::IsAdministrator()) { return; }
$oUser = UserRights::GetUserObject();
$oUser = UserRights::GetUserObject();
$oAddon = UserRights::GetModuleInstance();
$aOrgs = $oAddon->GetUserOrgs($oUser, '');
if (count($aOrgs) > 0)

View File

@@ -1757,27 +1757,6 @@ EOF
$sConfigJS = json_encode($aConfig);
$oPage->add_ready_script("$('#$iId').ckeditor(function() { /* callback code */ }, $sConfigJS);"); // Transform $iId into a CKEdit
$oPage->add_ready_script(
<<<EOF
$('#$iId').bind('update', function(evt){
BlockField('cke_$iId', $('#$iId').attr('disabled'));
//Delayed execution - ckeditor must be properly initialized before setting readonly
var retryCount = 0;
var oMe = $('#$iId');
var delayedSetReadOnly = function () {
if (oMe.data('ckeditorInstance').editable() == undefined && retryCount++ < 10) {
setTimeout(delayedSetReadOnly, retryCount * 100); //Wait a while longer each iteration
}
else
{
oMe.data('ckeditorInstance').setReadOnly(oMe.prop('disabled'));
}
};
setTimeout(delayedSetReadOnly, 50);
});
EOF
);
break;
case 'HTML':
@@ -2401,7 +2380,7 @@ EOF
return $oObj->DisplayModifyForm( $oPage, $aExtraParams);
}
public function DisplayStimulusForm(WebPage $oPage, $sStimulus, $aPrefillFormParam = null)
public function DisplayStimulusForm(WebPage $oPage, $sStimulus)
{
$sClass = get_class($this);
$iKey = $this->GetKey();
@@ -2443,12 +2422,6 @@ EOF
$oPage->add("<h1>$sActionDetails</h1>\n");
$sTargetState = $aTransitions[$sStimulus]['target_state'];
$aExpectedAttributes = $this->GetTransitionAttributes($sStimulus /*, current state*/);
if ($aPrefillFormParam != null)
{
$aPrefillFormParam['expected_attributes'] = $aExpectedAttributes;
$this->PrefillForm('state_change', $aPrefillFormParam);
$aExpectedAttributes = $aPrefillFormParam['expected_attributes'];
}
$sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
if ($sButtonsPosition == 'bottom')
{
@@ -2515,7 +2488,7 @@ EOF
else
{
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
if (is_array($aAllowedValues) && count($aAllowedValues) == 1)
if (count($aAllowedValues) == 1)
{
$aValues = array_keys($aAllowedValues);
$this->Set($sAttCode, $aValues[0]);
@@ -3532,7 +3505,7 @@ EOF
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
if (is_array($aNewIssues) && count($aNewIssues) > 0)
if (count($aNewIssues) > 0)
{
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
}
@@ -3710,7 +3683,7 @@ EOF
$currValue = $oObj->Get($sAttCode);
if ($oAttDef instanceof AttributeCaseLog)
{
$currValue = ''; // Put a single scalar value to force caselog to mock a new entry. For more info see N°1059.
$currValue = ' '; // Don't put an empty string, in case the field would be considered as mandatory...
}
if (is_object($currValue)) continue; // Skip non scalar values...
if(!array_key_exists($currValue, $aValues[$sAttCode]))

View File

@@ -330,62 +330,31 @@ EOF
protected function GetGroupByOptions($sOql)
{
$oQuery = $this->oModelReflection->GetQuery($sOql);
$sClass = $oQuery->GetClass();
$aGroupBy = array();
try
foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
{
$oQuery = $this->oModelReflection->GetQuery($sOql);
$sClass = $oQuery->GetClass();
foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
if ($sAttType == 'AttributeLinkedSet') continue;
if (is_subclass_of($sAttType, 'AttributeLinkedSet')) continue;
if ($sAttType == 'AttributeFriendlyName') continue;
if (is_subclass_of($sAttType, 'AttributeFriendlyName')) continue;
if ($sAttType == 'AttributeExternalField') continue;
if (is_subclass_of($sAttType, 'AttributeExternalField')) continue;
if ($sAttType == 'AttributeOneWayPassword') continue;
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
$aGroupBy[$sAttCode] = $sLabel;
if (is_subclass_of($sAttType, 'AttributeDateTime') || $sAttType == 'AttributeDateTime')
{
if ($sAttType == 'AttributeLinkedSet')
{
continue;
}
if (is_subclass_of($sAttType, 'AttributeLinkedSet'))
{
continue;
}
if ($sAttType == 'AttributeFriendlyName')
{
continue;
}
if (is_subclass_of($sAttType, 'AttributeFriendlyName'))
{
continue;
}
if ($sAttType == 'AttributeExternalField')
{
continue;
}
if (is_subclass_of($sAttType, 'AttributeExternalField'))
{
continue;
}
if ($sAttType == 'AttributeOneWayPassword')
{
continue;
}
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
$aGroupBy[$sAttCode] = $sLabel;
if (is_subclass_of($sAttType, 'AttributeDateTime') || $sAttType == 'AttributeDateTime')
{
$aGroupBy[$sAttCode.':hour'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Hour', $sLabel);
$aGroupBy[$sAttCode.':month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Month',
$sLabel);
$aGroupBy[$sAttCode.':day_of_week'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek',
$sLabel);
$aGroupBy[$sAttCode.':day_of_month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth',
$sLabel);
}
$aGroupBy[$sAttCode.':hour'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Hour', $sLabel);
$aGroupBy[$sAttCode.':month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-Month', $sLabel);
$aGroupBy[$sAttCode.':day_of_week'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfWeek', $sLabel);
$aGroupBy[$sAttCode.':day_of_month'] = Dict::Format('UI:DashletGroupBy:Prop-GroupBy:Select-DayOfMonth', $sLabel);
}
asort($aGroupBy);
}
catch(Exception $e)
{
// Bad OQL is ignored
}
asort($aGroupBy);
return $aGroupBy;
}
@@ -1250,32 +1219,25 @@ abstract class DashletGroupBy extends Dashlet
protected function GetNumericAttributes($sOql)
{
$aFunctionAttributes = array();
try
$oQuery = $this->oModelReflection->GetQuery($sOql);
$sClass = $oQuery->GetClass();
if (is_null($sClass))
{
$oQuery = $this->oModelReflection->GetQuery($sOql);
$sClass = $oQuery->GetClass();
if (is_null($sClass))
{
return $aFunctionAttributes;
}
foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
{
switch ($sAttType)
{
case 'AttributeDecimal':
case 'AttributeDuration':
case 'AttributeInteger':
case 'AttributePercentage':
case 'AttributeSubItem': // TODO: Known limitation: no unit displayed (values in sec)
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
$aFunctionAttributes[$sAttCode] = $sLabel;
break;
}
}
return $aFunctionAttributes;
}
catch (Exception $e)
foreach($this->oModelReflection->ListAttributes($sClass) as $sAttCode => $sAttType)
{
// Ignore bad OQL
switch ($sAttType)
{
case 'AttributeDecimal':
case 'AttributeDuration':
case 'AttributeInteger':
case 'AttributePercentage':
case 'AttributeSubItem': // TODO: Known limitation: no unit displayed (values in sec)
$sLabel = $this->oModelReflection->GetLabel($sClass, $sAttCode);
$aFunctionAttributes[$sAttCode] = $sLabel;
break;
}
}
return $aFunctionAttributes;

View File

@@ -326,8 +326,7 @@ class DisplayBlock
{
$aQueryParams = $aExtraParams['query_params'];
}
// In case of search, the context filtering is done by the search itself
if (($this->m_sStyle != 'links') && ($this->m_sStyle != 'search'))
if ($this->m_sStyle != 'links')
{
$oAppContext = new ApplicationContext();
$sClass = $this->m_oFilter->GetClass();
@@ -652,21 +651,16 @@ class DisplayBlock
if (isset($aExtraParams['update_history']) && true == $aExtraParams['update_history'])
{
$sSearchFilter = $this->m_oSet->GetFilter()->serialize();
// Limit the size of the URL (N°1585 - request uri too long)
if (strlen($sSearchFilter) < SERVER_MAX_URL_LENGTH)
{
$seventAttachedData = json_encode(array(
'filter' => $sSearchFilter,
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
'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'
));
$oPage->add_ready_script("$('body').trigger('update_history.itop', [$seventAttachedData])");
}
$seventAttachedData = json_encode(array(
'filter' => $this->m_oSet->GetFilter()->serialize(),
'breadcrumb_id' => "ui-search-".$this->m_oSet->GetClass(),
'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'
));
$oPage->add_ready_script("$('body').trigger('update_history.itop', [$seventAttachedData])");
}
}
break;

View File

@@ -230,8 +230,7 @@ class LoginWebPage extends NiceWebPage
try
{
UserRights::Login($sAuthUser); // Set the user's language (if possible!)
/** @var UserInternal $oUser */
$oUser = UserRights::GetUserObject();
$oUser = UserRights::GetUserObject();
if ($oUser == null)
{
throw new Exception(Dict::Format('UI:ResetPwd-Error-WrongLogin', $sAuthUser));
@@ -255,7 +254,6 @@ class LoginWebPage extends NiceWebPage
$sToken = substr(md5(APPROOT.uniqid()), 0, 16);
$oUser->Set('reset_pwd_token', $sToken);
CMDBObject::SetTrackInfo('Reset password');
$oUser->AllowWrite(true);
$oUser->DBUpdate();
$oEmail = new Email();

View File

@@ -1,62 +1,49 @@
<?php
// Copyright (C) 2010-2016 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* File to include to initialize the datamodel in memory
*
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
require_once(APPROOT.'/core/cmdbobject.class.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/core/contexttag.class.inc.php');
session_name('itop-'.md5(APPROOT));
session_start();
$sSwitchEnv = utils::ReadParam('switch_env', null);
$bAllowCache = true;
if (($sSwitchEnv != null) && (file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE)) && isset($_SESSION['itop_env']) && ($_SESSION['itop_env'] !== $sSwitchEnv))
{
$_SESSION['itop_env'] = $sSwitchEnv;
$sEnv = $sSwitchEnv;
$bAllowCache = false;
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset'))
{
// Zend opcode cache
opcache_reset();
}
if (function_exists('apc_clear_cache'))
{
// APC(u) cache
apc_clear_cache();
}
// TODO: reset the credentials as well ??
}
else if (isset($_SESSION['itop_env']))
{
$sEnv = $_SESSION['itop_env'];
}
else
{
$sEnv = ITOP_DEFAULT_ENV;
$_SESSION['itop_env'] = ITOP_DEFAULT_ENV;
}
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
<?php
// Copyright (C) 2010-2016 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* File to include to initialize the datamodel in memory
*
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
require_once(APPROOT.'/core/cmdbobject.class.inc.php');
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/core/contexttag.class.inc.php');
session_name('itop-'.md5(APPROOT));
session_start();
$sSwitchEnv = utils::ReadParam('switch_env', null);
if (($sSwitchEnv != null) && (file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE)))
{
$_SESSION['itop_env'] = $sSwitchEnv;
$sEnv = $sSwitchEnv;
// TODO: reset the credentials as well ??
}
else if (isset($_SESSION['itop_env']))
{
$sEnv = $_SESSION['itop_env'];
}
else
{
$sEnv = ITOP_DEFAULT_ENV;
$_SESSION['itop_env'] = ITOP_DEFAULT_ENV;
}
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, true /* $bAllowCache */, false /* $bTraceSourceFiles */, $sEnv);

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +0,0 @@
{
"require": {
"php": ">=5.6.0",
"ext-mysql": "*",
"ext-ldap": "*",
"ext-mcrypt": "*",
"ext-cli": "*",
"ext-soap": "*",
"ext-json": "*",
"ext-zip": "*",
"ext-mysqli": "*"
},
"config": {
"platform": {
"php": "5.6.0"
}
}
}

View File

@@ -360,7 +360,6 @@ class ActionEmail extends ActionNotification
$sTestBody .= "</div>\n";
$oEmail->SetBody($sTestBody, 'text/html', $sStyles);
$oEmail->SetRecipientTO($this->Get('test_recipient'));
$oEmail->SetRecipientFrom($sFrom);
$oEmail->SetReferences($sReference);
$oEmail->SetMessageId($sMessageId);
}

View File

@@ -1578,7 +1578,7 @@ class AttributeDBFieldVoid extends AttributeDefinition
protected function GetSQLCol($bFullSpec = false)
{
return 'VARCHAR(255)'
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? $this->GetSQLColSpec() : '');
}
protected function GetSQLColSpec()
@@ -2205,7 +2205,7 @@ class AttributeString extends AttributeDBField
protected function GetSQLCol($bFullSpec = false)
{
return 'VARCHAR(255)'
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? $this->GetSQLColSpec() : '');
}
@@ -2606,7 +2606,7 @@ class AttributePassword extends AttributeString
protected function GetSQLCol($bFullSpec = false)
{
return "VARCHAR(64)"
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? $this->GetSQLColSpec() : '');
}
@@ -2739,7 +2739,7 @@ class AttributeText extends AttributeString
protected function GetSQLCol($bFullSpec = false)
{
return "TEXT".CMDBSource::GetSqlStringColumnDefinition();
return "TEXT".CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
}
public function GetSQLColumns($bFullSpec = false)
@@ -2749,7 +2749,7 @@ class AttributeText extends AttributeString
if ($this->GetOptional('format', null) != null )
{
// Add the extra column only if the property 'format' is specified for the attribute
$aColumns[$this->Get('sql').'_format'] = "ENUM('text','html')".CMDBSource::GetSqlStringColumnDefinition();
$aColumns[$this->Get('sql').'_format'] = "ENUM('text','html')".CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
if ($bFullSpec)
{
$aColumns[$this->Get('sql').'_format'].= " DEFAULT 'text'"; // default 'text' is for migrating old records
@@ -3072,7 +3072,7 @@ class AttributeLongText extends AttributeText
{
protected function GetSQLCol($bFullSpec = false)
{
return "LONGTEXT".CMDBSource::GetSqlStringColumnDefinition();
return "LONGTEXT".CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
}
public function GetMaxSize()
@@ -3254,7 +3254,7 @@ class AttributeCaseLog extends AttributeLongText
{
$aColumns = array();
$aColumns[$this->GetCode()] = 'LONGTEXT' // 2^32 (4 Gb)
.CMDBSource::GetSqlStringColumnDefinition();
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
$aColumns[$this->GetCode().'_index'] = 'BLOB';
return $aColumns;
}
@@ -3642,13 +3642,13 @@ class AttributeEnum extends AttributeString
// make sure that this string will match the field type returned by the DB
// (used to perform a comparison between the current DB format and the data model)
return "ENUM(".implode(",", $aValues).")"
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? $this->GetSQLColSpec() : '');
}
else
{
return "VARCHAR(255)"
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? " DEFAULT ''" : ""); // ENUM() is not an allowed syntax!
}
}
@@ -5463,7 +5463,7 @@ class AttributeURL extends AttributeString
protected function GetSQLCol($bFullSpec = false)
{
return "VARCHAR(2048)"
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? $this->GetSQLColSpec() : '');
}
@@ -5640,8 +5640,8 @@ class AttributeBlob extends AttributeDefinition
{
$aColumns = array();
$aColumns[$this->GetCode().'_data'] = 'LONGBLOB'; // 2^32 (4 Gb)
$aColumns[$this->GetCode().'_mimetype'] = 'VARCHAR(255)'.CMDBSource::GetSqlStringColumnDefinition();
$aColumns[$this->GetCode().'_filename'] = 'VARCHAR(255)'.CMDBSource::GetSqlStringColumnDefinition();
$aColumns[$this->GetCode().'_mimetype'] = 'VARCHAR(255)'.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
$aColumns[$this->GetCode().'_filename'] = 'VARCHAR(255)'.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
return $aColumns;
}
@@ -5835,32 +5835,6 @@ class AttributeImage extends AttributeBlob
{
return '\\Combodo\\iTop\\Form\\Field\\ImageField';
}
public function MakeFormField(DBObject $oObject, $oFormField = null)
{
if ($oFormField === null)
{
$sFormFieldClass = static::GetFormFieldClass();
$oFormField = new $sFormFieldClass($this->GetCode());
}
parent::MakeFormField($oObject, $oFormField);
// Generating urls
$value = $oObject->Get($this->GetCode());
if (is_object($value) && !$value->IsEmpty())
{
$oFormField->SetDownloadUrl($value->GetDownloadURL(get_class($oObject), $oObject->GetKey(), $this->GetCode()));
$oFormField->SetDisplayUrl($value->GetDisplayURL(get_class($oObject), $oObject->GetKey(), $this->GetCode()));
}
else
{
$oFormField->SetDownloadUrl($this->Get('default_image'));
$oFormField->SetDisplayUrl($this->Get('default_image'));
}
return $oFormField;
}
}
/**
* A stop watch is an ormStopWatch object, it is stored as several columns in the database
@@ -6805,7 +6779,7 @@ class AttributeOneWayPassword extends AttributeDefinition
public function GetImportColumns()
{
$aColumns = array();
$aColumns[$this->GetCode()] = 'TINYTEXT'.CMDBSource::GetSqlStringColumnDefinition();
$aColumns[$this->GetCode()] = 'TINYTEXT'.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
return $aColumns;
}
@@ -6879,7 +6853,7 @@ class AttributeTable extends AttributeDBField
protected function GetSQLCol($bFullSpec = false)
{
return "LONGTEXT".CMDBSource::GetSqlStringColumnDefinition();
return "LONGTEXT".CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION;
}
public function GetMaxSize()
@@ -7287,7 +7261,7 @@ class AttributeRedundancySettings extends AttributeDBField
protected function GetSQLCol($bFullSpec = false)
{
return "VARCHAR(20)"
.CMDBSource::GetSqlStringColumnDefinition()
.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION
.($bFullSpec ? $this->GetSQLColSpec() : '');
}

View File

@@ -108,6 +108,16 @@ class MySQLHasGoneAwayException extends MySQLException
*/
class CMDBSource
{
/**
* SQL charset & collation declaration for text columns
*
* Using an attribute instead of a constant to avoid crash in the setup for older PHP versions
*
* @see https://dev.mysql.com/doc/refman/5.7/en/charset-column.html
* @since 2.5 #1001 switch to utf8mb4
*/
public static $SQL_STRING_COLUMNS_CHARSET_DEFINITION = ' CHARACTER SET '.DEFAULT_CHARACTER_SET.' COLLATE '.DEFAULT_COLLATION;
protected static $m_sDBHost;
protected static $m_sDBUser;
protected static $m_sDBPwd;
@@ -126,20 +136,6 @@ class CMDBSource
/** @var mysqli $m_oMysqli */
protected static $m_oMysqli;
/**
* SQL charset & collation declaration for text columns
*
* Using a function instead of a constant or attribute to avoid crash in the setup for older PHP versions (cannot
* use expression as value)
*
* @see https://dev.mysql.com/doc/refman/5.7/en/charset-column.html
* @since 2.5 #1001 switch to utf8mb4
*/
public static function GetSqlStringColumnDefinition()
{
return ' CHARACTER SET '.DEFAULT_CHARACTER_SET.' COLLATE '.DEFAULT_COLLATION;
}
/**
* @param Config $oConfig
*
@@ -1063,7 +1059,7 @@ class CMDBSource
}
return 'ALTER TABLE `'.$sTableName.'` '.self::GetSqlStringColumnDefinition().';';
return 'ALTER TABLE `'.$sTableName.'` '.self::$SQL_STRING_COLUMNS_CHARSET_DEFINITION.';';
}
@@ -1209,6 +1205,6 @@ class CMDBSource
return null;
}
return 'ALTER DATABASE'.CMDBSource::GetSqlStringColumnDefinition().';';
return 'ALTER DATABASE'.CMDBSource::$SQL_STRING_COLUMNS_CHARSET_DEFINITION.';';
}
}

View File

@@ -127,3 +127,5 @@ class SecurityException extends CoreException
class ArchivedObjectException extends CoreException
{
}
?>

View File

@@ -568,8 +568,7 @@ abstract class DBObject implements iDisplay
{
throw new CoreException("Unknown attribute code '$sAttCode' for the class ".get_class($this));
}
$aOrigValues = $this->m_aOrigValues;
return isset($aOrigValues[$sAttCode]) ? $aOrigValues[$sAttCode] : null;
return $this->m_aOrigValues[$sAttCode];
}
/**

View File

@@ -497,8 +497,6 @@ class DBObjectSearch extends DBSearch
* @param bool $bPositiveMatch if true will add a IN filter, else a NOT IN
*
* @throws \CoreException
*
* @since 2.5 N°1418
*/
public function AddConditionForInOperatorUsingParam($sFilterCode, $aValues, $bPositiveMatch = true)
{
@@ -508,7 +506,7 @@ class DBObjectSearch extends DBSearch
$sInParamName = $this->GenerateUniqueParamName();
$oParamExpression = new VariableExpression($sInParamName);
$this->GetInternalParamsByRef()[$sInParamName] = $aValues;
$this->SetInternalParams(array($sInParamName => $aValues));
$oListExpression = new ListExpression(array($oParamExpression));
@@ -1088,45 +1086,11 @@ class DBObjectSearch extends DBSearch
return $this->m_aParams = $aParams;
}
/**
* @return array <strong>warning</strong> : array returned by value
* @see self::GetInternalParamsByRef to get the attribute by reference
*/
public function GetInternalParams()
{
return $this->m_aParams;
}
/**
* @return array
* @see http://php.net/manual/en/language.references.return.php
* @since 2.5.1 N°1582
*/
public function &GetInternalParamsByRef()
{
return $this->m_aParams;
}
/**
* @param string $sKey
* @param mixed $value
* @param bool $bDoNotOverride
*
* @throws \CoreUnexpectedValue if $bDoNotOverride and $sKey already exists
*/
public function AddInternalParam($sKey, $value, $bDoNotOverride = false)
{
if ($bDoNotOverride)
{
if (array_key_exists($sKey, $this->m_aParams))
{
throw new CoreUnexpectedValue("The key $sKey already exists with value : ".$this->m_aParams[$sKey]);
}
}
$this->m_aParams[$sKey] = $value;
}
public function GetQueryParams($bExcludeMagicParams = true)
{
$aParams = array();

File diff suppressed because it is too large Load Diff

View File

@@ -234,6 +234,7 @@ EOF
}
}
$sData = '';
$sData .= '<style>table br {mso-data-placement:same-cell;}</style>'; // Trick for Excel: keep line breaks inside the same cell !
$sData .= "<table border=\"1\">\n";
$sData .= "<tr>\n";
foreach($aData as $sLabel)

View File

@@ -228,23 +228,10 @@ class ValueSetObjects extends ValueSetDefinition
}
}
$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname');
$aFields = $oExpression->ListRequiredFields();
$sClass = $oFilter->GetClass();
foreach($aFields as $sField)
{
$aFieldItems = explode('.', $sField);
if ($aFieldItems[0] != $sClass)
{
$sOperation = 'contains';
break;
}
}
switch ($sOperation)
{
case 'equals':
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($oFilter->GetClass());
$sClassAlias = $oFilter->GetClassAlias();
$aFilters = array();
$oValueExpr = new ScalarExpression($sContains);
@@ -260,7 +247,7 @@ class ValueSetObjects extends ValueSetDefinition
$oFilter = new DBUnionSearch($aFilters);
break;
case 'start_with':
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($oFilter->GetClass());
$sClassAlias = $oFilter->GetClassAlias();
$aFilters = array();
$oValueExpr = new ScalarExpression($sContains.'%');

View File

@@ -2588,6 +2588,7 @@ span.search-button, span.refresh-button {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
filter: gray;
filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
opacity: 0.5;
}
#itop-breadcrumb .breadcrumb-item a {

View File

@@ -2934,6 +2934,7 @@ span.search-button, span.refresh-button {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
filter: gray;
filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><feColorMatrix type='matrix' values='0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0' /></filter></svg>#greyscale");
// IE has no filter option: at least, have some effect when hovering...
opacity: 0.5;

View File

@@ -1,45 +1,49 @@
<?php
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
// 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('ES CR', 'Spanish', 'Español, Castellaño', array(
'Class:UserExternal' => 'Usuario Externo',
'Class:UserExternal+' => 'Usuario Autenticado fuera de iTop',
));
<?php
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
// 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('ES CR', 'Spanish', 'Español, Castellaño', array(
'Class:UserExternal' => 'Usuario Externo',
'Class:UserExternal+' => 'Usuario Autenticado fuera de iTop',
));
?>

View File

@@ -1,47 +1,48 @@
<?php
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
// 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('ES CR', 'Spanish', 'Español, Castellano', array(
'Class:UserLDAP' => 'Usuario LDAP',
'Class:UserLDAP+' => 'Usuario Autenticado vía LDAP',
'Class:UserLDAP/Attribute:password' => 'Contraseña',
'Class:UserLDAP/Attribute:password+' => 'Contraseña',
));
<?php
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
// 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('ES CR', 'Spanish', 'Español, Castellano', 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

@@ -1,47 +1,47 @@
<?php
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
// 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('ES CR', 'Spanish', 'Español, Castellano', array(
'Class:UserLocal' => 'Usuario de iTop',
'Class:UserLocal+' => 'Usuario Autenticado vía iTop',
'Class:UserLocal/Attribute:password' => 'Contraseña',
'Class:UserLocal/Attribute:password+' => 'Contraseña',
));
<?php
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
// 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('ES CR', 'Spanish', 'Español, Castellano', array(
'Class:UserLocal' => 'Usuario de iTop',
'Class:UserLocal+' => 'Usuario Autenticado vía iTop',
'Class:UserLocal/Attribute:password' => 'Contraseña',
'Class:UserLocal/Attribute:password+' => 'Contraseña',
));

View File

@@ -1,44 +1,44 @@
<?php
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
'Attachments:TabTitle_Count' => 'Anexos (%1$d)',
'Attachments:EmptyTabTitle' => 'Anexos',
'Attachments:FieldsetTitle' => 'Anexos',
'Attachments:DeleteBtn' => 'Borrar',
'Attachments:History_File_Added' => 'Anexo %1$s agregado.',
'Attachments:History_File_Removed' => 'Anexo %1$s removido.',
'Attachments:AddAttachment' => 'Agregar Anexo: ',
'Attachments:UploadNotAllowedOnThisSystem' => 'La carga de archivos NO está permitida en este sistema.',
'Attachment:Max_Go' => '(Tamaño Máximo de Archivo: %1$s Gb)',
'Attachment:Max_Mo' => '(Tamaño Máximo de Archivo: %1$s Mb)',
'Attachment:Max_Ko' => '(Tamaño Máximo de Archivo: %1$s Kb)',
'Attachments:NoAttachment' => 'No hay Anexo. ',
'Class:Attachment' => 'Anexo',
'Class:Attachment+' => 'Anexo',
'Attachments:PreviewNotAvailable' => 'Vista preliminar no disponible para este tipo de Anexo.',
));
<?php
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Localized data
*
* @copyright Copyright (C) 2010-2013 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @traductor Miguel Turrubiates <miguel_tf@yahoo.com>
*/
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
'Attachments:TabTitle_Count' => 'Anexos (%1$d)',
'Attachments:EmptyTabTitle' => 'Anexos',
'Attachments:FieldsetTitle' => 'Anexos',
'Attachments:DeleteBtn' => 'Borrar',
'Attachments:History_File_Added' => 'Anexo %1$s agregado.',
'Attachments:History_File_Removed' => 'Anexo %1$s removido.',
'Attachments:AddAttachment' => 'Agregar Anexo: ',
'Attachments:UploadNotAllowedOnThisSystem' => 'La carga de archivos NO está permitida en este sistema.',
'Attachment:Max_Go' => '(Tamaño Máximo de Archivo: %1$s Gb)',
'Attachment:Max_Mo' => '(Tamaño Máximo de Archivo: %1$s Mb)',
'Attachment:Max_Ko' => '(Tamaño Máximo de Archivo: %1$s Kb)',
'Attachments:NoAttachment' => 'No hay Anexo. ',
'Class:Attachment' => 'Anexo',
'Class:Attachment+' => 'Anexo',
'Attachments:PreviewNotAvailable' => 'Vista preliminar no disponible para este tipo de Anexo.',
));

View File

@@ -129,7 +129,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:ApplicationSolution+' => '',
'Class:ApplicationSolution/Attribute:functionalcis_list' => 'CIs',
'Class:ApplicationSolution/Attribute:functionalcis_list+' => '',
'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Business-Prozesse',
'Class:ApplicationSolution/Attribute:businessprocess_list' => 'Geschäftsprozesse',
'Class:ApplicationSolution/Attribute:businessprocess_list+' => '',
'Class:ApplicationSolution/Attribute:status' => 'Status',
'Class:ApplicationSolution/Attribute:status+' => '',
@@ -139,7 +139,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:ApplicationSolution/Attribute:status/Value:inactive+' => '',
'Class:BusinessProcess' => 'Business-Prozess',
'Class:BusinessProcess+' => '',
'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Anwendungslösungen',
'Class:BusinessProcess/Attribute:applicationsolutions_list' => 'Applikationslösungen',
'Class:BusinessProcess/Attribute:applicationsolutions_list+' => '',
'Class:BusinessProcess/Attribute:status' => 'Status',
'Class:BusinessProcess/Attribute:status+' => '',
@@ -373,9 +373,9 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_id+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:functionalci_id' => 'FunctionalCI',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:functionalci_id+' => '',
'Class:lnkApplicationSolutionToBusinessProcess' => 'Verknüpfung Anwendungslösung/Business-Prozess',
'Class:lnkApplicationSolutionToBusinessProcess' => 'Verknüpfung Anwendungslösung/Geschäftsprozess',
'Class:lnkApplicationSolutionToBusinessProcess+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id' => 'Business-Prozess',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id' => 'Geschäftsprozes',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_id+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:applicationsolution_id' => 'Anwendungslösung',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:applicationsolution_id+' => '',
@@ -999,7 +999,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:applicationsolution_name+' => '',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:functionalci_name' => 'FunctionalCI-Name',
'Class:lnkApplicationSolutionToFunctionalCI/Attribute:functionalci_name+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_name' => 'Business-Prozess-Name',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_name' => 'Geschäftsprozess-Name',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:businessprocess_name+' => '',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:applicationsolution_name' => 'Applikationslösungs-Name',
'Class:lnkApplicationSolutionToBusinessProcess/Attribute:applicationsolution_name+' => '',
@@ -1039,7 +1039,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Menu:ConfigManagementOverview+' => 'Übersicht',
'Menu:Contact' => 'Kontakte',
'Menu:Contact+' => 'Kontakte',
'Menu:Contact:Count' => '%1$d kontakten',
'Menu:Contact:Count' => '%1$d Kontakte',
'Menu:Person' => 'Personen',
'Menu:Person+' => 'Alle Personen',
'Menu:Team' => 'Teams',

View File

@@ -138,7 +138,7 @@ $(function()
if (this.options.redirect_after_completion_url != '')
{
var sUrl = this.options.redirect_after_completion_url;
window.setTimeout(function() { window.location.href = sUrl; }, 3000);
window.setTimeout(function() { window.location.href = sUrl; }, 500);
}
}
else

View File

@@ -51,10 +51,10 @@ class BrowseBrickController extends BrickController
// Getting current browse mode (First from router pamater, then default brick value)
$sBrowseMode = (!empty($sBrowseMode)) ? $sBrowseMode : $oBrick->GetDefaultBrowseMode();
// Getting current dataloading mode (First from router parameter, then query parameter, then default brick value)
$sDataLoading = ($sDataLoading !== null) ? $sDataLoading : $oApp['request_manipulator']->ReadParam('sDataLoading', $oBrick->GetDataLoading());
$sDataLoading = ($sDataLoading !== null) ? $sDataLoading : ( ($oRequest->query->get('sDataLoading') !== null) ? $oRequest->query->get('sDataLoading') : $oBrick->GetDataLoading() );
// Getting search value
$sSearchValue = $oApp['request_manipulator']->ReadParam('sSearchValue', '');
if (!empty($sSearchValue))
$sSearchValue = $oRequest->get('sSearchValue', null);
if ($sSearchValue !== null)
{
$sDataLoading = AbstractBrick::ENUM_DATA_LOADING_LAZY;
}
@@ -109,7 +109,7 @@ class BrowseBrickController extends BrickController
// Adding search clause
// Note : For know the search is naive and looks only for the exact match. It doesn't search for words separately
if (!empty($sSearchValue))
if ($sSearchValue !== null)
{
// - Cleaning the search value by exploding and trimming spaces
$aSearchValues = explode(' ', $sSearchValue);
@@ -182,7 +182,7 @@ class BrowseBrickController extends BrickController
{
$aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->SetSelectedClasses($aLevelsClasses);
if (!empty($sSearchValue))
if ($sSearchValue !== null)
{
// Note : This could be way more simpler if we had a SetInternalParam($sParam, $value) verb
$aQueryParams = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->GetInternalParams();
@@ -216,8 +216,8 @@ class BrowseBrickController extends BrickController
{
case BrowseBrick::ENUM_BROWSE_MODE_LIST:
// Retrieving parameters
$iPageNumber = (int) $oApp['request_manipulator']->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT);
$iListLength = (int) $oApp['request_manipulator']->ReadParam('iListLength', BrowseBrick::DEFAULT_LIST_LENGTH, FILTER_SANITIZE_NUMBER_INT);
$iPageNumber = (int) $oRequest->get('iPageNumber', 1);
$iListLength = (int) $oRequest->get('iListLength', BrowseBrick::DEFAULT_LIST_LENGTH);
// Getting total records number
$oCountSet = new DBObjectSet($oQuery);
@@ -232,8 +232,8 @@ class BrowseBrickController extends BrickController
case BrowseBrick::ENUM_BROWSE_MODE_TREE:
case BrowseBrick::ENUM_BROWSE_MODE_MOSAIC:
// Retrieving parameters
$sLevelAlias = $oApp['request_manipulator']->ReadParam('sLevelAlias', '');
$sNodeId = $oApp['request_manipulator']->ReadParam('sNodeId', '');
$sLevelAlias = $oRequest->get('sLevelAlias');
$sNodeId = $oRequest->get('sNodeId');
// If no values for those parameters, we might be loading page in lazy mode for the first time, therefore the URL doesn't have those informations.
if (empty($sLevelAlias))
@@ -631,9 +631,8 @@ class BrowseBrickController extends BrickController
if ($aLevelsProperties[$key][$sOptionalAttribute] !== null)
{
$sPropertyName = substr($sOptionalAttribute, 0, -4);
$oAttDef = MetaModel::GetAttributeDef(get_class($value), $aLevelsProperties[$key][$sOptionalAttribute]);
$tmpAttValue = $value->GetAsHTML($aLevelsProperties[$key][$sOptionalAttribute]);
$tmpAttValue = $value->Get($aLevelsProperties[$key][$sOptionalAttribute]);
if($sOptionalAttribute === 'image_att')
{
if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty())
@@ -642,7 +641,7 @@ class BrowseBrickController extends BrickController
}
else
{
$tmpAttValue = $oAttDef->Get('default_image');
$tmpAttValue = MetaModel::GetAttributeDef(get_class($value), $aLevelsProperties[$key][$sOptionalAttribute])->Get('default_image');
}
}
@@ -656,7 +655,7 @@ class BrowseBrickController extends BrickController
foreach ($aLevelsProperties[$key]['fields'] as $aField)
{
$oAttDef = MetaModel::GetAttributeDef(get_class($value), $aField['code']);
$aRow[$key]['fields'][$aField['code']] = $oAttDef->GetAsHTML($value->Get($aField['code']));
$aRow[$key]['fields'][$aField['code']] = $oAttDef->GetValueLabel($value->Get($aField['code']));
}
}
}
@@ -724,9 +723,8 @@ class BrowseBrickController extends BrickController
if ($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute] !== null)
{
$sPropertyName = substr($sOptionalAttribute, 0, -4);
$oAttDef = MetaModel::GetAttributeDef(get_class($aCurrentRowValues[0]), $aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]);
$tmpAttValue = $aCurrentRowValues[0]->GetAsHTML($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]);
$tmpAttValue = $aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]);
if($sOptionalAttribute === 'image_att')
{
if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty())
@@ -735,7 +733,7 @@ class BrowseBrickController extends BrickController
}
else
{
$tmpAttValue = $oAttDef->Get('default_image');
$tmpAttValue = MetaModel::GetAttributeDef(get_class($aCurrentRowValues[0]), $aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute])->Get('default_image');
}
}

View File

@@ -50,22 +50,22 @@ class ManageBrickController extends BrickController
{
const EXCEL_EXPORT_TEMPLATE_PATH = 'itop-portal-base/portal/src/views/bricks/manage/popup-export-excel.html.twig';
/**
* @param Request $oRequest
* @param Application $oApp
* @param string $sBrickId
* @param string $sGroupingTab
* @param string $sDisplayMode
*
* @return Response
*
* @throws \Exception
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \MySQLException
* @throws \OQLException
*/
public function DisplayAction(Request $oRequest, Application $oApp, $sBrickId, $sGroupingTab, $sDisplayMode = null)
/**
* @param \Symfony\Component\HttpFoundation\Request $oRequest
* @param \Silex\Application $oApp
* @param string $sBrickId
* @param string $sDisplayMode
* @param string $sGroupingTab
* @param string $sDataLoading
*
* @return \Symfony\Component\HttpFoundation\Response
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \OQLException
*/
public function DisplayAction(Request $oRequest, Application $oApp, $sBrickId, $sGroupingTab, $sDisplayMode = null, $sDataLoading = null)
{
/** @var ManageBrick $oBrick */
$oBrick = ApplicationHelper::GetLoadedBrickFromId($oApp, $sBrickId);
@@ -160,7 +160,7 @@ class ManageBrickController extends BrickController
$oScopeHelper = $oApp['scope_validator'];
$oScopeHelper->AddScopeToQuery($oQuery, $sClass);
$aData = array();
$this->ManageSearchValue($oApp, $aData, $oQuery, $sClass);
$this->ManageSearchValue($oRequest, $aData, $oQuery, $sClass);
// Grouping tab
if ($oBrick->HasGroupingTabs())
@@ -256,11 +256,11 @@ class ManageBrickController extends BrickController
$bHasScope = true;
// Getting current dataloading mode (First from router parameter, then query parameter, then default brick value)
$sDataLoading = $oApp['request_manipulator']->ReadParam('sDataLoading', $oBrick->GetDataLoading());
$sDataLoading = ($oRequest->get('sDataLoading') !== null) ? $oRequest->get('sDataLoading') : $oBrick->GetDataLoading();
// - Retrieving the grouping areas to display
$sGroupingArea = $oApp['request_manipulator']->ReadParam('sGroupingArea', '');
if (!empty($sGroupingArea))
$sGroupingArea = $oRequest->get('sGroupingArea');
if (!is_null($sGroupingArea))
{
$bNeedDetails = true;
}
@@ -340,7 +340,7 @@ class ManageBrickController extends BrickController
}
// - Retrieving the current grouping tab to display if necessary and altering the query to do so
if (empty($sGroupingTab))
if ($sGroupingTab === null)
{
if ($oBrick->HasGroupingTabs())
{
@@ -361,7 +361,7 @@ class ManageBrickController extends BrickController
}
// - Adding search clause if necessary
$this->ManageSearchValue($oApp, $aData, $oQuery, $sClass, $aColumnsAttrs);
$this->ManageSearchValue($oRequest, $aData, $oQuery, $sClass, $aColumnsAttrs);
// Preparing areas
// - We need to retrieve distinct values for the grouping attribute
@@ -411,7 +411,7 @@ class ManageBrickController extends BrickController
}
// - If specified or lazy loading, we truncate the $aGroupingAreasValues to keep only this one
if (!empty($sGroupingArea))
if ($sGroupingArea !== null)
{
$aGroupingAreasValues = array($sGroupingArea => $aGroupingAreasValues[$sGroupingArea]);
}
@@ -467,8 +467,8 @@ class ManageBrickController extends BrickController
if ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY)
{
// Retrieving parameters
$iPageNumber = (int)$oApp['request_manipulator']->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT);
$iListLength = (int)$oApp['request_manipulator']->ReadParam('iListLength', ManageBrick::DEFAULT_LIST_LENGTH, FILTER_SANITIZE_NUMBER_INT);
$iPageNumber = (int)$oRequest->get('iPageNumber', 1);
$iListLength = (int)$oRequest->get('iListLength', ManageBrick::DEFAULT_LIST_LENGTH);
// Getting total records number
$oCountSet = new DBObjectSet($oQuery);
@@ -577,7 +577,7 @@ class ManageBrickController extends BrickController
$oAttDef = MetaModel::GetAttributeDef($sCurrentClass, $sItemAttr);
if ($oAttDef->IsExternalKey())
{
$sValue = $oCurrentRow->GetAsHTML($sItemAttr.'_friendlyname');
$sValue = $oCurrentRow->Get($sItemAttr.'_friendlyname');
// Adding a view action on the external keys
if ($oCurrentRow->Get($sItemAttr) !== $oAttDef->GetNullValue())
@@ -595,22 +595,13 @@ class ManageBrickController extends BrickController
}
}
}
elseif ($oAttDef instanceof AttributeImage)
{
$oOrmDoc = $oCurrentRow->Get($sItemAttr);
if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty())
{
$sUrl = $oApp['url_generator']->generate('p_object_document_display', array('sObjectClass' => get_class($oCurrentRow), 'sObjectId' => $oCurrentRow->GetKey(), 'sObjectField' => $sItemAttr, 'cache' => 86400));
}
else
{
$sUrl = $oAttDef->Get('default_image');
}
$sValue = '<img src="' . $sUrl . '" />';
}
elseif ($oAttDef instanceof AttributeSubItem || $oAttDef instanceof AttributeDuration)
{
$sValue = $oAttDef->GetAsHTML($oCurrentRow->Get($sItemAttr));
}
else
{
$sValue = $oAttDef->GetAsHTML($oCurrentRow->Get($sItemAttr));
$sValue = $oAttDef->GetValueLabel($oCurrentRow->Get($sItemAttr));
}
unset($oAttDef);
@@ -745,24 +736,20 @@ class ManageBrickController extends BrickController
return $aData;
}
/**
* @param Application $oApp
* @param array $aData
* @param DBSearch $oQuery
* @param string $sClass
* @param array $aColumnsAttrs
*
* @throws \Exception
* @throws \CoreException
*/
protected function ManageSearchValue(Application $oApp, &$aData, DBSearch &$oQuery, $sClass, $aColumnsAttrs)
/**
* @param Request $oRequest
* @param array $aData
* @param DBSearch $oQuery
* @param string $sClass
*/
protected function ManageSearchValue(Request $oRequest, &$aData, DBSearch &$oQuery, $sClass, $aColumnsAttrs)
{
// Getting search value
$sSearchValue = $oApp['request_manipulator']->ReadParam('sSearchValue', '');
$sSearchValue = $oRequest->get('sSearchValue', null);
// - Adding search clause if necessary
// Note : This is a very naive search at the moment
if (!empty($sSearchValue))
if ($sSearchValue !== null)
{
// Putting only valid attributes as one can define attributes of leaf classes in the brick definition (<fields>), but at this stage we are working on the abstract class.
// Note: This won't fix everything as the search will not be looking in all fields.

View File

@@ -40,7 +40,6 @@ use ListExpression;
use ScalarExpression;
use DBObjectSet;
use AttributeEnum;
use AttributeImage;
use AttributeFinalClass;
use AttributeFriendlyName;
use UserRights;
@@ -62,8 +61,6 @@ class ObjectController extends AbstractController
const ENUM_MODE_VIEW = 'view';
const ENUM_MODE_EDIT = 'edit';
const ENUM_MODE_CREATE = 'create';
const DEFAULT_PAGE_NUMBER = 1;
const DEFAULT_LIST_LENGTH = 10;
/**
@@ -100,8 +97,6 @@ class ObjectController extends AbstractController
$oApp->abort(404, Dict::S('UI:ObjectDoesNotExist'));
}
$sOperation = $oApp['request_manipulator']->ReadParam('operation', '');
$aData = array('sMode' => 'view');
$aData['form'] = $this->HandleForm($oRequest, $oApp, $aData['sMode'], $sObjectClass, $sObjectId);
$aData['form']['title'] = Dict::Format('Brick:Portal:Object:Form:View:Title', MetaModel::GetName($sObjectClass), $oObject->GetName());
@@ -122,7 +117,7 @@ class ObjectController extends AbstractController
if ($oRequest->isXmlHttpRequest())
{
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
if ($oRequest->request->get('operation') === null)
{
$oResponse = $oApp['twig']->render('itop-portal-base/portal/src/views/bricks/object/modal.html.twig', $aData);
}
@@ -134,8 +129,8 @@ class ObjectController extends AbstractController
else
{
// Adding brick if it was passed
$sBrickId = $oApp['request_manipulator']->ReadParam('sBrickId', '');
if (!empty($sBrickId))
$sBrickId = $oRequest->get('sBrickId');
if ($sBrickId !== null)
{
$oBrick = ApplicationHelper::GetLoadedBrickFromId($oApp, $sBrickId);
if ($oBrick !== null)
@@ -177,8 +172,6 @@ class ObjectController extends AbstractController
$oApp->abort(404, Dict::S('UI:ObjectDoesNotExist'));
}
$sOperation = $oApp['request_manipulator']->ReadParam('operation', '');
$aData = array('sMode' => 'edit');
$aData['form'] = $this->HandleForm($oRequest, $oApp, $aData['sMode'], $sObjectClass, $sObjectId);
$aData['form']['title'] = Dict::Format('Brick:Portal:Object:Form:Edit:Title', MetaModel::GetName($sObjectClass), $aData['form']['object_name']);
@@ -187,7 +180,7 @@ class ObjectController extends AbstractController
if ($oRequest->isXmlHttpRequest())
{
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
if ($oRequest->request->get('operation') === null)
{
$oResponse = $oApp['twig']->render('itop-portal-base/portal/src/views/bricks/object/modal.html.twig', $aData);
}
@@ -199,8 +192,8 @@ class ObjectController extends AbstractController
else
{
// Adding brick if it was passed
$sBrickId = $oApp['request_manipulator']->ReadParam('sBrickId', '');
if (!empty($sBrickId))
$sBrickId = $oRequest->get('sBrickId');
if ($sBrickId !== null)
{
$oBrick = ApplicationHelper::GetLoadedBrickFromId($oApp, $sBrickId);
if ($oBrick !== null)
@@ -232,8 +225,6 @@ class ObjectController extends AbstractController
$oApp->abort(404, Dict::S('UI:ObjectDoesNotExist'));
}
$sOperation = $oApp['request_manipulator']->ReadParam('operation', '');
$aData = array('sMode' => 'create');
$aData['form'] = $this->HandleForm($oRequest, $oApp, $aData['sMode'], $sObjectClass);
$aData['form']['title'] = Dict::Format('Brick:Portal:Object:Form:Create:Title', MetaModel::GetName($sObjectClass));
@@ -242,7 +233,7 @@ class ObjectController extends AbstractController
if ($oRequest->isXmlHttpRequest())
{
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
if ($oRequest->request->get('operation') === null)
{
$oResponse = $oApp['twig']->render('itop-portal-base/portal/src/views/bricks/object/modal.html.twig', $aData);
}
@@ -254,8 +245,8 @@ class ObjectController extends AbstractController
else
{
// Adding brick if it was passed
$sBrickId = $oApp['request_manipulator']->ReadParam('sBrickId', '');
if (!empty($sBrickId))
$sBrickId = $oRequest->get('sBrickId');
if ($sBrickId !== null)
{
$oBrick = ApplicationHelper::GetLoadedBrickFromId($oApp, $sBrickId);
if ($oBrick !== null)
@@ -356,7 +347,7 @@ class ObjectController extends AbstractController
}
// Retrieving request parameters
$sOperation = $oApp['request_manipulator']->ReadParam('operation', '');
$sOperation = $oRequest->request->get('operation');
// Retrieving form properties
$aStimuliForms = ApplicationHelper::GetLoadedFormFromClass($oApp, $sObjectClass, 'apply_stimulus');
@@ -391,7 +382,7 @@ class ObjectController extends AbstractController
// TODO : This is a ugly patch to avoid showing a modal with a readonly form to the user as it would prevent user from finishing the transition.
// Instead, we apply the stimulus directly here and then go to the edited object.
if (empty($sOperation))
if ($sOperation === null)
{
if (isset($aData['form']['editable_fields_count']) && $aData['form']['editable_fields_count'] === 0)
{
@@ -399,7 +390,7 @@ class ObjectController extends AbstractController
$oSubRequest = $oRequest;
$oSubRequest->request->set('operation', 'submit');
$oSubRequest->request->set('stimulus_code', '');
$oSubRequest->request->set('stimulus_code', null);
$aData = array('sMode' => 'apply_stimulus');
$aData['form'] = $this->HandleForm($oSubRequest, $oApp, $aData['sMode'], $sObjectClass, $sObjectId, $aFormProperties);
@@ -414,7 +405,7 @@ class ObjectController extends AbstractController
if ($oRequest->isXmlHttpRequest())
{
// We have to check whether the 'operation' parameter is defined or not in order to know if the form is required via ajax (to be displayed as a modal dialog) or if it's a lifecycle call from a existing form.
if (empty($sOperation))
if ($sOperation === null)
{
$oResponse = $oApp['twig']->render('itop-portal-base/portal/src/views/bricks/object/modal.html.twig', $aData);
}
@@ -438,8 +429,9 @@ class ObjectController extends AbstractController
public static function HandleForm(Request $oRequest, Application $oApp, $sMode, $sObjectClass, $sObjectId = null, $aFormProperties = null)
{
$aFormData = array();
$sOperation = $oApp['request_manipulator']->ReadParam('operation', '');
$bModal = ($oRequest->isXmlHttpRequest() && empty($sOperation));
$oRequestParams = $oRequest->request;
$sOperation = $oRequestParams->get('operation');
$bModal = ($oRequest->isXmlHttpRequest() && ($oRequest->request->get('operation') === null) );
// - Retrieve form properties
if ($aFormProperties === null)
@@ -448,14 +440,14 @@ class ObjectController extends AbstractController
}
// - Create and
if (empty($sOperation))
if ($sOperation === null)
{
// Retrieving action rules
//
// Note : The action rules must be a base64-encoded JSON object, this is just so users are tempted to changes values.
// But it would not be a security issue as it only presets values in the form.
$sActionRulesToken = $oApp['request_manipulator']->ReadParam('ar_token', '');
$aActionRules = (!empty($sActionRulesToken)) ? ContextManipulatorHelper::DecodeRulesToken($sActionRulesToken) : array();
$sActionRulesToken = $oRequest->get('ar_token');
$aActionRules = ($sActionRulesToken !== null) ? ContextManipulatorHelper::DecodeRulesToken($sActionRulesToken) : array();
// Preparing object
if ($sObjectId === null)
@@ -528,11 +520,9 @@ class ObjectController extends AbstractController
}
else
{
$aPrefillFormParam = array(
'user' => $_SESSION["auth_user"],
$aPrefillFormParam = array('user' => $_SESSION["auth_user"],
'origin' => 'portal',
'stimulus' => $oApp['request_manipulator']->ReadParam('apply_stimulus', null)['code'],
);
'stimulus' => $oRequestParams->get('apply_stimulus')['code']);
$oObject->PrefillForm('state_change', $aPrefillFormParam);
}
@@ -570,9 +560,9 @@ class ObjectController extends AbstractController
else
{
// Update / Submit / Cancel
$sFormManagerClass = $oApp['request_manipulator']->ReadParam('formmanager_class', '', FILTER_UNSAFE_RAW);
$sFormManagerData = $oApp['request_manipulator']->ReadParam('formmanager_data', '', FILTER_UNSAFE_RAW);
if ( empty($sFormManagerClass) || empty($sFormManagerData) )
$sFormManagerClass = $oRequestParams->get('formmanager_class');
$sFormManagerData = $oRequestParams->get('formmanager_data');
if ($sFormManagerClass === null || $sFormManagerData === null)
{
IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameters formmanager_class and formamanager_data must be defined.');
$oApp->abort(500, 'Parameters formmanager_class and formmanager_data must be defined.');
@@ -594,13 +584,13 @@ class ObjectController extends AbstractController
{
case 'submit':
// Applying modification to object
$aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oApp['request_manipulator']->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), 'attachmentIds' => $oApp['request_manipulator']->ReadParam('attachment_ids', array(), FILTER_UNSAFE_RAW), 'formProperties' => $aFormProperties, 'applyStimulus' => $oApp['request_manipulator']->ReadParam('apply_stimulus', null)));
$aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oRequestParams->get('current_values'), 'attachmentIds' => $oRequest->get('attachment_ids'), 'formProperties' => $aFormProperties, 'applyStimulus' => $oRequestParams->get('apply_stimulus')));
if ($aFormData['validation']['valid'] === true)
{
// Note : We don't use $sObjectId there as it can be null if we are creating a new one. Instead we use the id from the created object once it has been seralized
// Check if stimulus has to be applied
$sStimulusCode = $oApp['request_manipulator']->ReadParam('stimulus_code', '');
if (!empty($sStimulusCode))
$sStimulusCode = ($oRequestParams->get('stimulus_code') !== null && $oRequestParams->get('stimulus_code') !== '') ? $oRequestParams->get('stimulus_code') : null;
if ($sStimulusCode !== null)
{
$aFormData['validation']['redirection'] = array(
'url' => $oApp['url_generator']->generate('p_object_apply_stimulus', array('sObjectClass' => $sObjectClass, 'sObjectId' => $oFormManager->GetObject()->GetKey(), 'sStimulusCode' => $sStimulusCode)),
@@ -608,17 +598,17 @@ class ObjectController extends AbstractController
);
}
// Otherwise, we show the object if there is no default
// else
// {
else
{
// $aFormData['validation']['redirection'] = array(
// 'alternative_url' => $oApp['url_generator']->generate('p_object_edit', array('sObjectClass' => $sObjectClass, 'sObjectId' => $oFormManager->GetObject()->GetKey()))
// );
// }
}
}
break;
case 'update':
$oFormManager->OnUpdate(array('currentValues' => $oApp['request_manipulator']->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), 'formProperties' => $aFormProperties));
$oFormManager->OnUpdate(array('currentValues' => $oRequestParams->get('current_values'), 'formProperties' => $aFormProperties));
break;
case 'cancel':
@@ -637,11 +627,11 @@ class ObjectController extends AbstractController
// Preparing fields list regarding the operation
if ($sOperation === 'update')
{
$aRequestedFields = $oApp['request_manipulator']->ReadParam('requested_fields', array(), FILTER_UNSAFE_RAW);
$sFormPath = $oApp['request_manipulator']->ReadParam('form_path', '');
$aRequestedFields = $oRequestParams->get('requested_fields');
$sFormPath = $oRequestParams->get('form_path');
// Checking if the update was on a subform, if so we need to make the rendering for that part only
if ( !empty($sFormPath) && $sFormPath !== $oFormManager->GetForm()->GetId() )
if ($sFormPath !== null && $sFormPath !== $oFormManager->GetForm()->GetId())
{
$oSubForm = $oFormManager->GetForm()->FindSubForm($sFormPath);
$oSubFormRenderer = new BsFormRenderer($oSubForm);
@@ -726,8 +716,8 @@ class ObjectController extends AbstractController
//
// Note : The action rules must be a base64-encoded JSON object, this is just so users are tempted to changes values.
// But it would not be a security issue as it only presets values in the form.
$sActionRulesToken = $oApp['request_manipulator']->ReadParam('ar_token', '');
$aActionRules = (!empty($sActionRulesToken)) ? ContextManipulatorHelper::DecodeRulesToken($sActionRulesToken) : array();
$sActionRulesToken = $oRequest->get('ar_token');
$aActionRules = ($sActionRulesToken !== null) ? ContextManipulatorHelper::DecodeRulesToken($sActionRulesToken) : array();
// Preparing object
$oApp['context_manipulator']->PrepareObject($aActionRules, $oHostObject);
}
@@ -735,7 +725,7 @@ class ObjectController extends AbstractController
// Updating host object with form data / values
$sFormManagerClass = $aRequestContent['formmanager_class'];
$sFormManagerData = $aRequestContent['formmanager_data'];
if (!empty($sFormManagerClass) && !empty($sFormManagerData))
if ($sFormManagerClass !== null && $sFormManagerData !== null)
{
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
$oFormManager->SetApplication($oApp);
@@ -847,7 +837,7 @@ class ObjectController extends AbstractController
'sTargetAttCode' => $sTargetAttCode,
'sHostObjectClass' => $sHostObjectClass,
'sHostObjectId' => $sHostObjectId,
'sActionRulesToken' => $oApp['request_manipulator']->ReadParam('ar_token', ''),
'sActionRulesToken' => $oRequest->get('ar_token')
);
// Checking security layers
@@ -870,15 +860,16 @@ class ObjectController extends AbstractController
//
// Note : The action rules must be a base64-encoded JSON object, this is just so users are tempted to changes values.
// But it would not be a security issue as it only presets values in the form.
$aActionRules = !empty($aData['sActionRulesToken']) ? ContextManipulatorHelper::DecodeRulesToken($aData['sActionRulesToken']) : array();
$aActionRules = ($aData['sActionRulesToken'] !== null) ? ContextManipulatorHelper::DecodeRulesToken($aData['sActionRulesToken']) : array();
// Preparing object
$oApp['context_manipulator']->PrepareObject($aActionRules, $oHostObject);
}
// Updating host object with form data / values
$sFormManagerClass = $oApp['request_manipulator']->ReadParam('formmanager_class', '', FILTER_UNSAFE_RAW);
$sFormManagerData = $oApp['request_manipulator']->ReadParam('formmanager_data', '', FILTER_UNSAFE_RAW);
if ( !empty($sFormManagerClass) && !empty($sFormManagerData) )
$oRequestParams = $oRequest->request;
$sFormManagerClass = $oRequestParams->get('formmanager_class');
$sFormManagerData = $oRequestParams->get('formmanager_data');
if ($sFormManagerClass !== null && $sFormManagerData !== null)
{
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
$oFormManager->SetApplication($oApp);
@@ -894,18 +885,18 @@ class ObjectController extends AbstractController
}
// Updating host object
$oFormManager->OnUpdate(array('currentValues' => $oApp['request_manipulator']->ReadParam('current_values', array(), FILTER_UNSAFE_RAW)));
$oFormManager->OnUpdate(array('currentValues' => $oRequestParams->get('current_values')));
$oHostObject = $oFormManager->GetObject();
}
// Retrieving request parameters
$iPageNumber = $oApp['request_manipulator']->ReadParam('iPageNumber', static::DEFAULT_PAGE_NUMBER, FILTER_SANITIZE_NUMBER_INT);
$iListLength = $oApp['request_manipulator']->ReadParam('iListLength', static::DEFAULT_LIST_LENGTH, FILTER_SANITIZE_NUMBER_INT);
$bInitalPass = $oApp['request_manipulator']->HasParam('draw') ? false : true;
$sQuery = $oApp['request_manipulator']->ReadParam('sSearchValue', '');
$sFormPath = $oApp['request_manipulator']->ReadParam('sFormPath', '');
$sFieldId = $oApp['request_manipulator']->ReadParam('sFieldId', '');
$aObjectIdsToIgnore = $oApp['request_manipulator']->ReadParam('aObjectIdsToIgnore', null, FILTER_UNSAFE_RAW);
$iPageNumber = ($oRequest->get('iPageNumber') !== null) ? $oRequest->get('iPageNumber') : 1;
$iListLength = ($oRequest->get('iListLength') !== null) ? $oRequest->get('iListLength') : static::DEFAULT_LIST_LENGTH;
$bInitalPass = ($oRequest->get('draw') === null) ? true : false;
$sQuery = $oRequest->get('sSearchValue');
$sFormPath = $oRequest->get('sFormPath');
$sFieldId = $oRequest->get('sFieldId');
$aObjectIdsToIgnore = $oRequest->get('aObjectIdsToIgnore');
// Building search query
// - Retrieving target object class from attcode
@@ -986,7 +977,7 @@ class ObjectController extends AbstractController
// - Adding query condition
$aInternalParams['this'] = $oHostObject;
if (!empty($sQuery))
if ($sQuery !== null)
{
$oFullExpr = null;
for ($i = 0; $i < count($aAttCodes); $i++)
@@ -1361,9 +1352,9 @@ class ObjectController extends AbstractController
}
// Retrieving ormDocument's host object
$sObjectClass = $oApp['request_manipulator']->ReadParam('sObjectClass', '');
$sObjectId = $oApp['request_manipulator']->ReadParam('sObjectId', '');
$sObjectField = $oApp['request_manipulator']->ReadParam('sObjectField', '');
$sObjectClass = $oRequest->get('sObjectClass');
$sObjectId = $oRequest->get('sObjectId');
$sObjectField = $oRequest->get('sObjectField');
// When reaching to an Attachment, we have to check security on its host object instead of the Attachment itself
if($sObjectClass === 'Attachment')
@@ -1403,7 +1394,8 @@ class ObjectController extends AbstractController
}
else
{
$iCacheSec = $oApp['request_manipulator']->ReadParam('cache', 0, FILTER_SANITIZE_NUMBER_INT);
$sCache = $oRequest->get('cache');
$iCacheSec = ($sCache !== null) ? (int) $sCache : 0;
}
$aHeaders = array();
@@ -1444,16 +1436,16 @@ class ObjectController extends AbstractController
// Retrieving sOperation from request only if it wasn't forced (determined by the route)
if ($sOperation === null)
{
$sOperation = $oApp['request_manipulator']->ReadParam('operation', null);
$sOperation = $oRequest->get('operation');
}
switch ($sOperation)
{
case 'add':
$sFieldName = $oApp['request_manipulator']->ReadParam('field_name', '');
$sObjectClass = $oApp['request_manipulator']->ReadParam('object_class', '');
$sTempId = $oApp['request_manipulator']->ReadParam('temp_id', '');
$sFieldName = $oRequest->get('field_name');
$sObjectClass = $oRequest->get('object_class');
$sTempId = $oRequest->get('temp_id');
if (empty($sObjectClass) || empty($sTempId))
if (($sObjectClass === null) || ($sTempId === null))
{
$aData['error'] = Dict::Format('UI:Error:2ParametersMissing', 'object_class', 'temp_id');
}
@@ -1492,7 +1484,7 @@ class ObjectController extends AbstractController
// - Route
$aRouteParams = array(
'sObjectClass' => 'Attachment',
'sObjectId' => $oApp['request_manipulator']->ReadParam('sAttachmentId', null),
'sObjectId' => $oRequest->get('sAttachmentId'),
'sObjectField' => 'contents',
);
$sRedirectRoute = $oApp['url_generator']->generate('p_object_document_download', $aRouteParams);
@@ -1527,10 +1519,10 @@ class ObjectController extends AbstractController
$aData = array();
// Retrieving parameters
$sObjectClass = $oApp['request_manipulator']->ReadParam('sObjectClass', '');
$aObjectIds = $oApp['request_manipulator']->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW);
$aObjectAttCodes = $oApp['request_manipulator']->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW);
if ( empty($sObjectClass) || empty($aObjectIds) || empty($aObjectAttCodes) )
$sObjectClass = $oRequest->Get('sObjectClass');
$aObjectIds = $oRequest->Get('aObjectIds');
$aObjectAttCodes = $oRequest->Get('aObjectAttCodes');
if ($sObjectClass === null || $aObjectIds === null || $aObjectAttCodes === null)
{
IssueLog::Info(__METHOD__ . ' at line ' . __LINE__ . ' : sObjectClass, sObjectId and aObjectAttCodes expected, "' . $sObjectClass . '", "' . $sObjectId . '" given.');
$oApp->abort(500, 'Invalid request data, some informations are missing');
@@ -1598,7 +1590,7 @@ class ObjectController extends AbstractController
if ($oAttDef->IsExternalKey())
{
$aAttData['value'] = $oObject->GetAsHTML($oAttDef->GetCode() . '_friendlyname');
$aAttData['value'] = $oObject->Get($oAttDef->GetCode() . '_friendlyname');
// Checking if user can access object's external key
if (SecurityHelper::IsActionAllowed($oApp, UR_ACTION_READ, $oAttDef->GetTargetClass()))
@@ -1611,22 +1603,9 @@ class ObjectController extends AbstractController
// We skip it
continue;
}
elseif ($oAttDef instanceof AttributeImage)
{
$oOrmDoc = $oObject->Get($oAttDef->GetCode());
if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty())
{
$sUrl = $oApp['url_generator']->generate('p_object_document_display', array('sObjectClass' => get_class($oObject), 'sObjectId' => $oObject->GetKey(), 'sObjectField' => $oAttDef->GetCode(), 'cache' => 86400));
}
else
{
$sUrl = $oAttDef->Get('default_image');
}
$aAttData['value'] = '<img src="' . $sUrl . '" />';
}
else
{
$aAttData['value'] = $oAttDef->GetAsHTML($oObject->Get($oAttDef->GetCode()));
$aAttData['value'] = $oAttDef->GetValueLabel($oObject->Get($oAttDef->GetCode()));
if ($oAttDef instanceof AttributeFriendlyName)
{

View File

@@ -71,7 +71,7 @@ class UserProfileBrickController extends BrickController
// If this is ajax call, we are just submiting preferences or password forms
if ($oRequest->isXmlHttpRequest())
{
$aCurrentValues = $oApp['request_manipulator']->ReadParam('current_values', array(), FILTER_UNSAFE_RAW);
$aCurrentValues = $oRequest->request->get('current_values');
$sFormType = $aCurrentValues['form_type'];
if ($sFormType === PreferencesFormManager::FORM_TYPE)
{
@@ -120,9 +120,10 @@ class UserProfileBrickController extends BrickController
public function HandlePreferencesForm(Request $oRequest, Application $oApp, $sFormMode)
{
$aFormData = array();
$oRequestParams = $oRequest->request;
// Handling form
$sOperation = $oApp['request_manipulator']->ReadParam('operation', null);
$sOperation = $oRequestParams->get('operation');
// - Create
if ($sOperation === null)
{
@@ -142,8 +143,8 @@ class UserProfileBrickController extends BrickController
// - Submit
else if ($sOperation === 'submit')
{
$sFormManagerClass = $oApp['request_manipulator']->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW);
$sFormManagerData = $oApp['request_manipulator']->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW);
$sFormManagerClass = $oRequestParams->get('formmanager_class');
$sFormManagerData = $oRequestParams->get('formmanager_data');
if ($sFormManagerClass === null || $sFormManagerData === null)
{
IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameters formmanager_class and formamanager_data must be defined.');
@@ -153,7 +154,7 @@ class UserProfileBrickController extends BrickController
// Rebuilding manager from json
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
// Applying modification to object
$aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oApp['request_manipulator']->ReadParam('current_values', array(), FILTER_UNSAFE_RAW)));
$aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oRequestParams->get('current_values')));
// Reloading page only if preferences were changed
if (($aFormData['validation']['valid'] === true) && !empty($aFormData['validation']['messages']['success']))
{
@@ -187,9 +188,10 @@ class UserProfileBrickController extends BrickController
public function HandlePasswordForm(Request $oRequest, Application $oApp)
{
$aFormData = array();
$oRequestParams = $oRequest->request;
// Handling form
$sOperation = $oApp['request_manipulator']->ReadParam('operation', null);
$sOperation = $oRequestParams->get('operation');
// - Create
if ($sOperation === null)
{
@@ -204,8 +206,8 @@ class UserProfileBrickController extends BrickController
// - Submit
else if ($sOperation === 'submit')
{
$sFormManagerClass = $oApp['request_manipulator']->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW);
$sFormManagerData = $oApp['request_manipulator']->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW);
$sFormManagerClass = $oRequestParams->get('formmanager_class');
$sFormManagerData = $oRequestParams->get('formmanager_data');
if ($sFormManagerClass === null || $sFormManagerData === null)
{
IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameters formmanager_class and formamanager_data must be defined.');
@@ -215,7 +217,7 @@ class UserProfileBrickController extends BrickController
// Rebuilding manager from json
$oFormManager = $sFormManagerClass::FromJSON($sFormManagerData);
// Applying modification to object
$aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oApp['request_manipulator']->ReadParam('current_values', array(), FILTER_UNSAFE_RAW)));
$aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oRequestParams->get('current_values')));
}
else
{
@@ -242,10 +244,11 @@ class UserProfileBrickController extends BrickController
public function HandlePictureForm(Request $oRequest, Application $oApp, $sFormMode)
{
$aFormData = array();
$oRequestParams = $oRequest->request;
$sPictureAttCode = 'picture';
// Handling form
$sOperation = $oApp['request_manipulator']->ReadParam('operation', null);
$sOperation = $oRequestParams->get('operation');
// - No operation specified
if ($sOperation === null)
{

View File

@@ -1,119 +0,0 @@
<?php
/**
* Copyright (C) 2012-2018 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http://www.gnu.org/licenses/>
*/
namespace Combodo\iTop\Portal\Helper;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* RequestManipulatorHelper class
*
* Handle basic requests manipulation.
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @since 2.5.1
*/
class RequestManipulatorHelper
{
/** @var \Symfony\Component\HttpFoundation\RequestStack $oRequestStack */
protected $oRequestStack;
/**
* RequestManipulatorHelper constructor.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $oRequestStack
*/
public function __construct(RequestStack &$oRequestStack)
{
$this->oRequestStack = $oRequestStack;
}
/**
* @return \Symfony\Component\HttpFoundation\Request
*/
public function GetCurrentRequest()
{
return $this->oRequestStack->getCurrentRequest();
}
/**
* Returns if the request has a $sKey parameter.
* This looks in the GET arguments first, then PATH and finally the POST data.
*
* @param string $sKey
*
* @return bool
*/
public function HasParam($sKey)
{
if ($this->GetCurrentRequest()->query->has($sKey))
{
return true;
}
if ($this->GetCurrentRequest()->attributes->has($sKey))
{
return true;
}
if ($this->GetCurrentRequest()->request->has($sKey))
{
return true;
}
return false;
}
/**
* Returns the $sKey parameter from the request filtered with $iFilter.
* This looks in the GET arguments first, then the PATH and finally the POST data.
*
* Note: It is inspired by the \Symfony\Component\HttpFoundation\ParameterBag::filter() function and was necessary as we sometimes have parameters that can be either in the GET/PATH/POST arguments and need to be filtered. Silex only offer the possibility to filter parameter from a single ParameterBag, so we created this helper.
*
* @param string $sKey
* @param mixed $default
* @param int $iFilter Default is FILTER_SANITIZE_STRING
*
* @return mixed|null
*
* @since 2.5.1
*/
public function ReadParam($sKey, $default = null, $iFilter = FILTER_SANITIZE_STRING)
{
if ($this->GetCurrentRequest()->query->has($sKey))
{
return $this->GetCurrentRequest()->query->filter($sKey, $default, $iFilter);
}
if ($this->GetCurrentRequest()->attributes->has($sKey))
{
return $this->GetCurrentRequest()->attributes->filter($sKey, $default, $iFilter);
}
if ($this->GetCurrentRequest()->request->has($sKey))
{
return $this->GetCurrentRequest()->request->filter($sKey, $default, $iFilter);
}
return $default;
}
}

View File

@@ -1,60 +0,0 @@
<?php
/**
* Copyright (C) 2012-2018 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http://www.gnu.org/licenses/>
*/
namespace Combodo\iTop\Portal\Provider;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Combodo\iTop\Portal\Helper\RequestManipulatorHelper;
/**
* RequestManipulatorHelper service provider
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @since 2.5.1
*/
class RequestManipulatorServiceProvider implements ServiceProviderInterface
{
/**
* @param \Pimple\Container $oApp
*/
public function register(Container $oApp)
{
$oApp['request_manipulator'] = function ($oApp)
{
$oApp->flush();
$oRequestManipulatorHelper = new RequestManipulatorHelper($oApp['request_stack']);
return $oRequestManipulatorHelper;
};
}
/**
* @param \Pimple\Container $oApp
*/
public function boot(Container $oApp)
{
}
}

View File

@@ -36,8 +36,6 @@ require_once __DIR__ . '/../src/providers/urlgeneratorserviceprovider.class.inc.
require_once __DIR__ . '/../src/helpers/urlgeneratorhelper.class.inc.php';
require_once __DIR__ . '/../src/providers/contextmanipulatorserviceprovider.class.inc.php';
require_once __DIR__ . '/../src/helpers/contextmanipulatorhelper.class.inc.php';
require_once __DIR__ . '/../src/providers/requestmanipulatorserviceprovider.class.inc.php';
require_once __DIR__ . '/../src/helpers/requestmanipulatorhelper.class.inc.php';
require_once __DIR__ . '/../src/providers/scopevalidatorserviceprovider.class.inc.php';
require_once __DIR__ . '/../src/helpers/scopevalidatorhelper.class.inc.php';
require_once __DIR__ . '/../src/providers/lifecyclevalidatorserviceprovider.class.inc.php';
@@ -101,9 +99,6 @@ $oApp->before(function(Symfony\Component\HttpFoundation\Request $oRequest, Silex
die(Dict::S('Portal:ErrorNoContactForThisUser'));
}
// Register request manipulator now that the request has been created.
$oApp->register(new Combodo\iTop\Portal\Provider\RequestManipulatorServiceProvider());
// Enable archived data
utils::InitArchiveMode();

View File

@@ -79,10 +79,6 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Class:Service/Attribute:org_id+' => '',
'Class:Service/Attribute:organization_name' => 'Provider Name',
'Class:Service/Attribute:organization_name+' => '',
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
'Class:Service/Attribute:servicefamily_id+' => '',
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
'Class:Service/Attribute:servicefamily_name+' => '',
'Class:Service/Attribute:description' => 'Beschreibung',
'Class:Service/Attribute:description+' => '',
'Class:Service/Attribute:documents_list' => 'Dokumente',

View File

@@ -199,7 +199,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'Brick:Portal:OngoingRequests:Tab:OnGoing' => 'Offen',
'Brick:Portal:OngoingRequests:Tab:Resolved' => 'Gelöst',
'Brick:Portal:ClosedRequests:Title' => 'Geschlossene Störungen/Anfragen',
'Class:Ticket/Attribute:operational_status' => 'Betriebsstatus',
'Class:Ticket/Attribute:operational_status' => 'Status',
'Class:Ticket/Attribute:operational_status+' => 'Berechnet nach detailliertem Status',
'Class:Ticket/Attribute:operational_status/Value:ongoing' => 'In Bearbeitung',
'Class:Ticket/Attribute:operational_status/Value:ongoing+' => 'In Bearbeitung',

View File

@@ -1010,7 +1010,7 @@ Ved tilknytningen til en trigger, bliver hver handling tildelt et "rækkefølge"
'UI:ResetPwd-Error-Send' => 'email transport technical issue. Please Contact your administrator.~~',
'UI:ResetPwd-EmailSent' => 'Please check your email box and follow the instructions...~~',
'UI:ResetPwd-EmailSubject' => 'Reset your iTop password~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href="%1$s">enter a new password</a></p>.~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href=\"%1$s\">enter a new password</a></p>.~~',
'UI:ResetPwd-Title' => 'Reset password~~',
'UI:ResetPwd-Error-InvalidToken' => 'Sorry, either the password has already been reset, or you have received several emails. Please make sure that you use the link provided in the very last email received.~~',
'UI:ResetPwd-Error-EnterPassword' => 'Enter a new password for the account \'%1$s\'.~~',

View File

@@ -1177,7 +1177,6 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm
// Search form
'UI:Search:Toggle' => 'Ein-/Ausklappen',
'UI:Search:AutoSubmit:DisabledHint' => 'Automatische Eingabe für diese Klasse deaktiviert',
'UI:Search:NoAutoSubmit:ExplainText' => 'Fügen Sie ein Kriterium in das Suchfeld ein oder klicken Sie auf die Suchschaltfläche, um die Objekte anzuzeigen.',
'UI:Search:Criterion:MoreMenu:AddCriteria' => 'Kriterium hinzufügen',
// - Add new criteria button
'UI:Search:AddCriteria:List:RecentlyUsed:Title' => 'Kürzlich verwendet',

View File

@@ -1409,7 +1409,6 @@ When associated with a trigger, each action is given an "order" number, specifyi
// Search form
'UI:Search:Toggle' => 'Minimize / Expand',
'UI:Search:AutoSubmit:DisabledHint' => 'Auto submit has been disabled for this class',
'UI:Search:NoAutoSubmit:ExplainText' => 'Add some criterion on the search box or click the search button to view the objects.',
'UI:Search:Criterion:MoreMenu:AddCriteria' => 'Add new criteria',
// - Add new criteria button
'UI:Search:AddCriteria:List:RecentlyUsed:Title' => 'Recently used',

View File

@@ -1242,7 +1242,6 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé
// Search form
'UI:Search:Toggle' => 'Réduire / Ouvrir',
'UI:Search:AutoSubmit:DisabledHint' => 'La soumission automatique a été desactivée pour cette classe',
'UI:Search:NoAutoSubmit:ExplainText' => 'Ajoutez des critères dans le formulaire de recherche ou cliquez sur le bouton rechercher pour voir les objets.',
'UI:Search:Criterion:MoreMenu:AddCriteria' => 'Ajouter un critère',
// - Add new criteria button
'UI:Search:AddCriteria:List:RecentlyUsed:Title' => 'Récents',

View File

@@ -822,7 +822,7 @@ Akció kiváltó okhoz rendelésekor kap egy sorszámot , amely meghatározza az
'UI:ResetPwd-Error-Send' => 'email transport technical issue. Please Contact your administrator.~~',
'UI:ResetPwd-EmailSent' => 'Please check your email box and follow the instructions...~~',
'UI:ResetPwd-EmailSubject' => 'Reset your iTop password~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href="%1$s">enter a new password</a></p>.~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href=\"%1$s\">enter a new password</a></p>.~~',
'UI:ResetPwd-Title' => 'Reset password~~',
'UI:ResetPwd-Error-InvalidToken' => 'Sorry, either the password has already been reset, or you have received several emails. Please make sure that you use the link provided in the very last email received.~~',
'UI:ResetPwd-Error-EnterPassword' => 'Enter a new password for the account \'%1$s\'.~~',

View File

@@ -946,7 +946,7 @@ Quando è associata a un trigger, ad ogni azione è assegnato un numero "ordine"
'UI:ResetPwd-Error-Send' => 'email transport technical issue. Please Contact your administrator.~~',
'UI:ResetPwd-EmailSent' => 'Please check your email box and follow the instructions...~~',
'UI:ResetPwd-EmailSubject' => 'Reset your iTop password~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href="%1$s">enter a new password</a></p>.~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href=\"%1$s\">enter a new password</a></p>.~~',
'UI:ResetPwd-Title' => 'Reset password~~',
'UI:ResetPwd-Error-InvalidToken' => 'Sorry, either the password has already been reset, or you have received several emails. Please make sure that you use the link provided in the very last email received.~~',
'UI:ResetPwd-Error-EnterPassword' => 'Enter a new password for the account \'%1$s\'.~~',

View File

@@ -1007,7 +1007,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'UI:ResetPwd-Error-Send' => 'email transport technical issue. Please Contact your administrator.~~',
'UI:ResetPwd-EmailSent' => 'Please check your email box and follow the instructions...~~',
'UI:ResetPwd-EmailSubject' => 'Reset your iTop password~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href="%1$s">enter a new password</a></p>.~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href=\"%1$s\">enter a new password</a></p>.~~',
'UI:ResetPwd-Title' => 'Reset password~~',
'UI:ResetPwd-Error-InvalidToken' => 'Sorry, either the password has already been reset, or you have received several emails. Please make sure that you use the link provided in the very last email received.~~',
'UI:ResetPwd-Error-EnterPassword' => 'Enter a new password for the account \'%1$s\'.~~',

View File

@@ -930,7 +930,7 @@ Tetikleme gerçekleştiriğinde işlemler tanımlanan sıra numarası ile gerçe
'UI:ResetPwd-Error-Send' => 'email transport technical issue. Please Contact your administrator.~~',
'UI:ResetPwd-EmailSent' => 'Please check your email box and follow the instructions...~~',
'UI:ResetPwd-EmailSubject' => 'Reset your iTop password~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href="%1$s">enter a new password</a></p>.~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href=\"%1$s\">enter a new password</a></p>.~~',
'UI:ResetPwd-Title' => 'Reset password~~',
'UI:ResetPwd-Error-InvalidToken' => 'Sorry, either the password has already been reset, or you have received several emails. Please make sure that you use the link provided in the very last email received.~~',
'UI:ResetPwd-Error-EnterPassword' => 'Enter a new password for the account \'%1$s\'.~~',

View File

@@ -928,7 +928,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'UI:ResetPwd-Error-Send' => 'email transport technical issue. Please Contact your administrator.~~',
'UI:ResetPwd-EmailSent' => 'Please check your email box and follow the instructions...~~',
'UI:ResetPwd-EmailSubject' => 'Reset your iTop password~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href="%1$s">enter a new password</a></p>.~~',
'UI:ResetPwd-EmailBody' => '<body><p>You have requested to reset your iTop password.</p><p>Please follow this link (single usage) to <a href=\"%1$s\">enter a new password</a></p>.~~',
'UI:ResetPwd-Title' => 'Reset password~~',
'UI:ResetPwd-Error-InvalidToken' => 'Sorry, either the password has already been reset, or you have received several emails. Please make sure that you use the link provided in the very last email received.~~',
'UI:ResetPwd-Error-EnterPassword' => 'Enter a new password for the account \'%1$s\'.~~',

View File

@@ -193,7 +193,7 @@
var result;
if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() === q.toLowerCase() ) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
@@ -386,7 +386,6 @@
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
method: "POST",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,

View File

@@ -152,7 +152,7 @@ $(function()
_initChooseDefaultOperator: function()
{
//if the class has an index, in order to maximize the performance, we force the default operator to "equal"
if (this.options.field.has_index && typeof this.options.available_operators['='] == 'object' && this.options.values.length == 0)
if (this.options.field.has_index && typeof this.options.available_operators['='] == 'object')
{
this.options.operator = '=';
this.options.available_operators['='].rank = -1;//we want it to be the first displayed

View File

@@ -180,11 +180,17 @@ $(function()
$('body').on('update_history.itop', function(oEvent, oData) {
if (me.element.parents('.ui-dialog').length !== 0)
{
//search form in modal are forbidden to update history!
return;
}
// if (me.element.parents('.ui-dialog').length != 0)
// {
// //search form in modal are forbidden to update history!
// return;
// }
if ($('.ui-dialog:visible :itop-search_form_handler').length != 0)
{
//if a modal containing a search form is visible then the history update event come from it, whe do not want to update the history in this case! because search form in modal are forbidden to update history!
return;
}
var sNewUrl = GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=search';
sNewUrl = sNewUrl + '&filter='+oData['filter'];
@@ -229,39 +235,18 @@ $(function()
}]
};
// - Retrieve criterion
var iCurrentCriterionRow = 0;
this.elements.criterion_area.find('.sf_criterion_row').each(function (iDomCriterionRowIdx) {
var isFirstRow = (iDomCriterionRowIdx === 0),
oCriterionRowElem = $(this),
oCriteriaRowCriterias = oCriterionRowElem.find('.search_form_criteria');
this.elements.criterion_area.find('.sf_criterion_row').each(function(iIdx){
var oCriterionRowElem = $(this);
if (oCriteriaRowCriterias.length === 0)
{
if (!isFirstRow)
oCriterion['or'][iIdx] = {'and': []};
oCriterionRowElem.find('.search_form_criteria').each(function(){
var oCriteriaData = $(this).triggerHandler('itop.search.criteria.get_data');
if (null != oCriteriaData)
{
$(this).remove();
}
}
else
{
oCriteriaRowCriterias.each(function () {
var oCriteriaData = $(this).triggerHandler('itop.search.criteria.get_data');
if (null != oCriteriaData)
{
if (!oCriterion['or'][iCurrentCriterionRow])
{
oCriterion['or'][iCurrentCriterionRow] = {'and': []};
}
oCriterion['or'][iCurrentCriterionRow]['and'].push(oCriteriaData);
}
else
{
$(this).remove();
}
});
iCurrentCriterionRow++;
}
oCriterion['or'][iIdx]['and'].push(oCriteriaData);
}
});
});
// - Update search
this.options.search.criterion = oCriterion;
@@ -751,7 +736,9 @@ $(function()
// Make placeholder if nothing yet
if(oResultAreaElem.html() === '')
{
oResultAreaElem.html('<div class="sf_results_placeholder"><p>' + Dict.S('UI:Search:NoAutoSubmit:ExplainText') + '</p><p><button type="button">' + Dict.S('UI:Button:Search') + '<span class="fa fa-search"></span></button></p></div>');
// TODO: Make a good UI for this POC.
// TODO: Translate sentence.
oResultAreaElem.html('<div class="sf_results_placeholder"><p>Add some criterion on the search box or click the search button to view the objects.</p><p><button type="button">Search<span class="fa fa-search"></span></button></p></div>');
oResultAreaElem.find('button').on('click', function(){
// TODO: Bug: Open "Search for CI", change child classe in the dropdown, click the search button. It submit the search for the original child classe, not the current one; whereas a click on the upper right pictogram does. This might be due to the form reloading.
me._onSubmitClick();
@@ -1014,10 +1001,6 @@ $(function()
}
}
$.extend(oListParams, this.options.list_params);
if (me.element.parents('.ui-dialog').length !== 0)
{
oListParams.update_history = false;
}
oData.list_params = JSON.stringify(oListParams);
if (true === bAbortIfNoChange)

View File

@@ -1,342 +1,342 @@
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
*
* @param id String the dom identifier of the source input
* @param sTargetClass
* @param sAttCode
* @param oSearchWidgetElmt
* @param sFilter
* @param sTitle
* @constructor
*/
function SearchFormForeignKeys(id, sTargetClass, sAttCode, oSearchWidgetElmt, sFilter, sTitle)
{
this.id = id;
//this.sOriginalTargetClass = sTargetClass;
this.sTargetClass = sTargetClass;
this.sFilter = sFilter;
this.sTitle = sTitle;
this.sAttCode = sAttCode;
this.oSearchWidgetElmt = oSearchWidgetElmt;
this.emptyHtml = ''; // content to be displayed when the search results are empty (when opening the dialog)
this.emptyOnClose = true; // Workaround for the JQuery dialog being very slow when opening and closing if the content contains many INPUT tags
this.ajax_request = null;
// this.bSelectMode = bSelectMode; // true if the edited field is a SELECT, false if it's an autocomplete
// this.bSearchMode = bSearchMode; // true if selecting a value in the context of a search form
var me = this;
this.Init = function()
{
// make sure that the form is clean
$('#linkedset_'+this.id+' .selection').each( function() { this.checked = false; });
$('#'+this.id+'_btnRemove').prop('disabled', false);
$('<div id="dlg_'+me.id+'"></div>').appendTo(document.body);
// me.trace(dialog);
//TODO : check and remove all unneded code bellow this line!!
$('#'+this.id+'_linksToRemove').val('');
$('#linkedset_'+me.id).on('remove', function() {
// prevent having the dlg div twice
$('#dlg_'+me.id).remove();
});
$('#'+this.iInputId).closest('form').submit(function() {
return me.OnFormSubmit();
});
};
this.StopPendingRequest = function()
{
if (me.ajax_request)
{
me.ajax_request.abort();
me.ajax_request = null;
}
};
this.ShowModalSearchForeignKeys = function()
{
// // Query the server to get the form to search for target objects
// if (me.bSelectMode)
// {
// $('#fstatus_'+me.id).html('<img src="../images/indicator.gif" />');
// }
// else
// {
// $('#label_'+me.id).addClass('dlg_loading');
// }
$('#label_'+me.id).addClass('dlg_loading');
var theMap = {
sAttCode: me.sAttCode,
iInputId: me.id,
sTitle: me.sTitle,
sTargetClass: me.sTargetClass,
// bSearchMode: me.bSearchMode,
operation: 'ShowModalSearchForeignKeys'
};
// Make sure that we cancel any pending request before issuing another
// since responses may arrive in arbitrary order
me.StopPendingRequest();
// Run the query and get the result back directly in HTML
me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap,
function(data)
{
// $('#dlg_'+me.id).html(data);
$('#dlg_'+me.id).empty().append($(data)); // $(data).filter(':not(script)'));
$('#dlg_'+me.id).dialog('open');
me.UpdateSizes();
me.UpdateButtons();
me.ajax_request = null;
me.ListResultsSearchForeignKeys();
},
'html'
);
};
this.UpdateSizes = function()
{
var dlg = $('#dlg_'+me.id);
// Adjust the dialog's size to fit into the screen
if (dlg.width() > ($(window).width()-40))
{
dlg.width($(window).width()-40);
}
if (dlg.height() > ($(window).height()-70))
{
dlg.height($(window).height()-70);
}
var searchForm = dlg.find('div.display_block:first'); // Top search form, enclosing display_block
var results = $('#SearchResultsToAdd_'+me.id);
var oPadding = {};
var aKeys = ['top', 'right', 'bottom', 'left'];
for(k in aKeys)
{
oPadding[aKeys[k]] = 0;
if (dlg.css('padding-'+aKeys[k]))
{
oPadding[aKeys[k]] = parseInt(dlg.css('padding-'+aKeys[k]).replace('px', ''));
}
}
//var width = dlg.innerWidth() - oPadding['right'] - oPadding['left'] - 22; // 5 (margin-left) + 5 (padding-left) + 5 (padding-right) + 5 (margin-right) + 2 for rounding !
var height = dlg.innerHeight()-oPadding['top']-oPadding['bottom']-22;
var form_height = searchForm.outerHeight();
results.height(height - form_height - 40); // Leave some space for the buttons
};
this.UpdateButtons = function()
{
var okBtn = $('#btn_ok_'+me.id);
if ($('#count_'+me.id).val() > 0)
{
okBtn.removeAttr('disabled');
}
else
{
okBtn.prop('disabled', 'disabled');
}
};
/**
* @return {boolean}
*/
this.ListResultsSearchForeignKeys = function ()
{
var theMap = {
sTargetClass: me.sTargetClass,
iInputId: me.id,
sFilter: me.sFilter
// bSearchMode: me.bSearchMode
};
// Gather the parameters from the search form
$('#fs_'+me.id+' :input').each( function() {
if (this.name !== '')
{
var val = $(this).val(); // supports multiselect as well
if (val !== null)
{
theMap[this.name] = val;
}
}
});
theMap['sRemoteClass'] = theMap['class']; // swap 'class' (defined in the form) and 'remoteClass'
theMap.operation = 'ListResultsSearchForeignKeys'; // Override what is defined in the form itself
theMap.sAttCode = me.sAttCode;
var sSearchAreaId = '#SearchResultsToAdd_'+me.id;
//$(sSearchAreaId).html('<div style="text-align:center;width:100%;height:24px;vertical-align:middle;"><img src="../images/indicator.gif" /></div>');
$(sSearchAreaId).block();
me.UpdateButtons();
// Make sure that we cancel any pending request before issuing another
// since responses may arrive in arbitrary order
me.StopPendingRequest();
// Run the query and display the results
me.ajax_request = $.post(AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap,
function(data)
{
$(sSearchAreaId).html(data);
$(sSearchAreaId+' .listResults').tableHover();
$('#fr_'+me.id+' input:radio').click(function() { me.UpdateButtons(); });
me.UpdateButtons();
me.ajax_request = null;
$('#count_'+me.id).change(function(){
me.UpdateButtons();
});
me.UpdateSizes();
},
'html'
);
return false; // Don't submit the form, stay in the current page !
};
/**
* @return {boolean}
*/
this.DoAddObjects = function () {
// Gather the parameters from the search form
var theMap = {};
var context = $('#SearchResultsToAdd_'+me.id);
var selectionMode = $(':input[name="selectionMode"]', context);
if (selectionMode.length > 0) {
// Paginated table retrieve the mode and the exceptions
theMap['selectionMode'] = (selectionMode.val() == 'negative') ? 'negative' : 'positive';
$('#fs_SearchFormToAdd_'+me.id+' :input').each(function () {
theMap[this.name] = this.value;
});
$(':input[name="storedSelection[]"]', context).each(function () {
if (typeof theMap[this.name] === "undefined") {
theMap[this.name] = [];
}
theMap[this.name].push(this.value);
$(this).remove(); // Remove the selection for the next time the dialog re-opens
});
}
// Normal table, retrieve all the checked check-boxes
$(':checked[name="selectObject[]"]', context).each(
function () {
if ((this.name !== '') && ((this.type !== 'checkbox') || (this.checked))) {
var arrayExpr = /\[\]$/;
if (arrayExpr.test(this.name)) {
// Array
if (typeof theMap[this.name] === "undefined") {
theMap[this.name] = [];
}
theMap[this.name].push(this.value);
}
else {
theMap[this.name] = this.value;
}
}
$(this).parents('tr:first').remove(); // Remove the whole line, so that, next time the dialog gets displayed it's no longer there
}
);
theMap["class"] = me.sTargetClass;
theMap['operation'] = 'GetFullListForeignKeysFromSelection';
$('#busy_'+me.iInputId).html('&nbsp;<img src="../images/indicator.gif"/>');
// Run the query and display the results
$.ajax(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {
"data": theMap,
"method": "POST"
})
.done(function (data) {
if (Object.keys(data).length > 0) {
me.oSearchWidgetElmt.trigger("itop.search.criteria_enum.add_selected_values", data);
}
})
.fail(function (data) {
try {
console.error(data);
} catch (e) {
}
})
;
$('#dlg_'+me.id).dialog('close');
return false;
};
// Workaround for a ui.jquery limitation: if the content of
// the dialog contains many INPUTs, closing and opening the
// dialog is very slow. So empty it each time.
this.OnClose = function()
{
me.StopPendingRequest();
// called by the dialog, so in the context 'this' points to the jQueryObject
if (me.emptyOnClose)
{
$('#SearchResultsToAdd_'+me.id).html(me.emptyHtml);
}
$('#label_'+me.id).removeClass('dlg_loading');
$('#label_'+me.id).focus();
me.ajax_request = null;
};
this.DoSelectObjectClass = function()
{
// Retrieving selected value
var oSelectedClass = $('#ac_create_'+me.id+' select');
if(oSelectedClass.length !== 1) return;
// Setting new target class
me.sTargetClass = oSelectedClass.val();
// Opening real creation form
$('#ac_create_'+me.id).dialog('close');
me.CreateObject();
};
this.Update = function()
{
if ($('#'+me.id).prop('disabled'))
{
$('#v_'+me.id).html('');
$('#label_'+me.id).prop('disabled', 'disabled');
$('#label_'+me.id).css({'background': 'transparent'});
$('#mini_add_'+me.id).hide();
$('#mini_tree_'+me.id).hide();
$('#mini_search_'+me.id).hide();
}
else
{
$('#label_'+me.id).removeAttr('disabled');
$('#label_'+me.id).css({'background': '#fff url(../images/ac-background.gif) no-repeat right'});
$('#mini_add_'+me.id).show();
$('#mini_tree_'+me.id).show();
$('#mini_search_'+me.id).show();
}
};
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
*
* @param id String the dom identifier of the source input
* @param sTargetClass
* @param sAttCode
* @param oSearchWidgetElmt
* @param sFilter
* @param sTitle
* @constructor
*/
function SearchFormForeignKeys(id, sTargetClass, sAttCode, oSearchWidgetElmt, sFilter, sTitle)
{
this.id = id;
//this.sOriginalTargetClass = sTargetClass;
this.sTargetClass = sTargetClass;
this.sFilter = sFilter;
this.sTitle = sTitle;
this.sAttCode = sAttCode;
this.oSearchWidgetElmt = oSearchWidgetElmt;
this.emptyHtml = ''; // content to be displayed when the search results are empty (when opening the dialog)
this.emptyOnClose = true; // Workaround for the JQuery dialog being very slow when opening and closing if the content contains many INPUT tags
this.ajax_request = null;
// this.bSelectMode = bSelectMode; // true if the edited field is a SELECT, false if it's an autocomplete
// this.bSearchMode = bSearchMode; // true if selecting a value in the context of a search form
var me = this;
this.Init = function()
{
// make sure that the form is clean
$('#linkedset_'+this.id+' .selection').each( function() { this.checked = false; });
$('#'+this.id+'_btnRemove').prop('disabled', false);
$('<div id="dlg_'+me.id+'"></div>').appendTo(document.body);
// me.trace(dialog);
//TODO : check and remove all unneded code bellow this line!!
$('#'+this.id+'_linksToRemove').val('');
$('#linkedset_'+me.id).on('remove', function() {
// prevent having the dlg div twice
$('#dlg_'+me.id).remove();
});
$('#'+this.iInputId).closest('form').submit(function() {
return me.OnFormSubmit();
});
};
this.StopPendingRequest = function()
{
if (me.ajax_request)
{
me.ajax_request.abort();
me.ajax_request = null;
}
};
this.ShowModalSearchForeignKeys = function()
{
// // Query the server to get the form to search for target objects
// if (me.bSelectMode)
// {
// $('#fstatus_'+me.id).html('<img src="../images/indicator.gif" />');
// }
// else
// {
// $('#label_'+me.id).addClass('dlg_loading');
// }
$('#label_'+me.id).addClass('dlg_loading');
var theMap = {
sAttCode: me.sAttCode,
iInputId: me.id,
sTitle: me.sTitle,
sTargetClass: me.sTargetClass,
// bSearchMode: me.bSearchMode,
operation: 'ShowModalSearchForeignKeys'
};
// Make sure that we cancel any pending request before issuing another
// since responses may arrive in arbitrary order
me.StopPendingRequest();
// Run the query and get the result back directly in HTML
me.ajax_request = $.post( AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap,
function(data)
{
// $('#dlg_'+me.id).html(data);
$('#dlg_'+me.id).empty().append($(data)); // $(data).filter(':not(script)'));
$('#dlg_'+me.id).dialog('open');
me.UpdateSizes();
me.UpdateButtons();
me.ajax_request = null;
me.ListResultsSearchForeignKeys();
},
'html'
);
};
this.UpdateSizes = function()
{
var dlg = $('#dlg_'+me.id);
// Adjust the dialog's size to fit into the screen
if (dlg.width() > ($(window).width()-40))
{
dlg.width($(window).width()-40);
}
if (dlg.height() > ($(window).height()-70))
{
dlg.height($(window).height()-70);
}
var searchForm = dlg.find('div.display_block:first'); // Top search form, enclosing display_block
var results = $('#SearchResultsToAdd_'+me.id);
var oPadding = {};
var aKeys = ['top', 'right', 'bottom', 'left'];
for(k in aKeys)
{
oPadding[aKeys[k]] = 0;
if (dlg.css('padding-'+aKeys[k]))
{
oPadding[aKeys[k]] = parseInt(dlg.css('padding-'+aKeys[k]).replace('px', ''));
}
}
//var width = dlg.innerWidth() - oPadding['right'] - oPadding['left'] - 22; // 5 (margin-left) + 5 (padding-left) + 5 (padding-right) + 5 (margin-right) + 2 for rounding !
var height = dlg.innerHeight()-oPadding['top']-oPadding['bottom']-22;
var form_height = searchForm.outerHeight();
results.height(height - form_height - 40); // Leave some space for the buttons
};
this.UpdateButtons = function()
{
var okBtn = $('#btn_ok_'+me.id);
if ($('#count_'+me.id).val() > 0)
{
okBtn.removeAttr('disabled');
}
else
{
okBtn.prop('disabled', 'disabled');
}
};
/**
* @return {boolean}
*/
this.ListResultsSearchForeignKeys = function ()
{
var theMap = {
sTargetClass: me.sTargetClass,
iInputId: me.id,
sFilter: me.sFilter
// bSearchMode: me.bSearchMode
};
// Gather the parameters from the search form
$('#fs_'+me.id+' :input').each( function() {
if (this.name !== '')
{
var val = $(this).val(); // supports multiselect as well
if (val !== null)
{
theMap[this.name] = val;
}
}
});
theMap['sRemoteClass'] = theMap['class']; // swap 'class' (defined in the form) and 'remoteClass'
theMap.operation = 'ListResultsSearchForeignKeys'; // Override what is defined in the form itself
theMap.sAttCode = me.sAttCode;
var sSearchAreaId = '#SearchResultsToAdd_'+me.id;
//$(sSearchAreaId).html('<div style="text-align:center;width:100%;height:24px;vertical-align:middle;"><img src="../images/indicator.gif" /></div>');
$(sSearchAreaId).block();
me.UpdateButtons();
// Make sure that we cancel any pending request before issuing another
// since responses may arrive in arbitrary order
me.StopPendingRequest();
// Run the query and display the results
me.ajax_request = $.post(AddAppContext(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php'), theMap,
function(data)
{
$(sSearchAreaId).html(data);
$(sSearchAreaId+' .listResults').tableHover();
$('#fr_'+me.id+' input:radio').click(function() { me.UpdateButtons(); });
me.UpdateButtons();
me.ajax_request = null;
$('#count_'+me.id).change(function(){
me.UpdateButtons();
});
me.UpdateSizes();
},
'html'
);
return false; // Don't submit the form, stay in the current page !
};
/**
* @return {boolean}
*/
this.DoAddObjects = function () {
// Gather the parameters from the search form
var theMap = {};
var context = $('#SearchResultsToAdd_'+me.id);
var selectionMode = $(':input[name="selectionMode"]', context);
if (selectionMode.length > 0) {
// Paginated table retrieve the mode and the exceptions
theMap['selectionMode'] = selectionMode.val();
$('#fs_SearchFormToAdd_'+me.id+' :input').each(function () {
theMap[this.name] = this.value;
});
$(':input[name="storedSelection[]"]', context).each(function () {
if (typeof theMap[this.name] === "undefined") {
theMap[this.name] = [];
}
theMap[this.name].push(this.value);
$(this).remove(); // Remove the selection for the next time the dialog re-opens
});
}
// Normal table, retrieve all the checked check-boxes
$(':checked[name="selectObject[]"]', context).each(
function () {
if ((this.name !== '') && ((this.type !== 'checkbox') || (this.checked))) {
var arrayExpr = /\[\]$/;
if (arrayExpr.test(this.name)) {
// Array
if (typeof theMap[this.name] === "undefined") {
theMap[this.name] = [];
}
theMap[this.name].push(this.value);
}
else {
theMap[this.name] = this.value;
}
}
$(this).parents('tr:first').remove(); // Remove the whole line, so that, next time the dialog gets displayed it's no longer there
}
);
theMap["class"] = me.sTargetClass;
theMap['operation'] = 'GetFullListForeignKeysFromSelection';
$('#busy_'+me.iInputId).html('&nbsp;<img src="../images/indicator.gif"/>');
// Run the query and display the results
$.ajax(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {
"data": theMap,
"method": "POST"
})
.done(function (data) {
if (Object.keys(data).length > 0) {
me.oSearchWidgetElmt.trigger("itop.search.criteria_enum.add_selected_values", data);
}
})
.fail(function (data) {
try {
console.error(data);
} catch (e) {
}
})
;
$('#dlg_'+me.id).dialog('close');
return false;
};
// Workaround for a ui.jquery limitation: if the content of
// the dialog contains many INPUTs, closing and opening the
// dialog is very slow. So empty it each time.
this.OnClose = function()
{
me.StopPendingRequest();
// called by the dialog, so in the context 'this' points to the jQueryObject
if (me.emptyOnClose)
{
$('#SearchResultsToAdd_'+me.id).html(me.emptyHtml);
}
$('#label_'+me.id).removeClass('dlg_loading');
$('#label_'+me.id).focus();
me.ajax_request = null;
};
this.DoSelectObjectClass = function()
{
// Retrieving selected value
var oSelectedClass = $('#ac_create_'+me.id+' select');
if(oSelectedClass.length !== 1) return;
// Setting new target class
me.sTargetClass = oSelectedClass.val();
// Opening real creation form
$('#ac_create_'+me.id).dialog('close');
me.CreateObject();
};
this.Update = function()
{
if ($('#'+me.id).prop('disabled'))
{
$('#v_'+me.id).html('');
$('#label_'+me.id).prop('disabled', 'disabled');
$('#label_'+me.id).css({'background': 'transparent'});
$('#mini_add_'+me.id).hide();
$('#mini_tree_'+me.id).hide();
$('#mini_search_'+me.id).hide();
}
else
{
$('#label_'+me.id).removeAttr('disabled');
$('#label_'+me.id).css({'background': '#fff url(../images/ac-background.gif) no-repeat right'});
$('#mini_add_'+me.id).show();
$('#mini_tree_'+me.id).show();
$('#mini_search_'+me.id).show();
}
};
}

View File

@@ -428,7 +428,11 @@ $(function()
event.stopImmediatePropagation();
var jMe = $(this);
$(this).data('openTimeoutId', setTimeout(function() {
jMe.tooltip('open');
var sDataId = jMe.attr('data-attcode');
if ($('.tooltip-close-button[data-attcode="'+sDataId+'"]').length == 0)
{
jMe.tooltip('open');
}
}, 500));
})
.on( "mouseout", function(event){

View File

@@ -409,12 +409,8 @@ function ToggleDurationField(field_id) {
function PropagateCheckBox(bCurrValue, aFieldsList, bCheck) {
if (bCurrValue == bCheck) {
for (var i = 0; i < aFieldsList.length; i++) {
var sFieldId = aFieldsList[i];
$('#enable_'+sFieldId).attr('checked', bCheck);
ToogleField(bCheck, sFieldId);
// Cascade propagation
$('#enable_'+sFieldId).trigger('change');
$('#enable_'+aFieldsList[i]).attr('checked', bCheck);
ToogleField(bCheck, aFieldsList[i]);
}
}
}

View File

@@ -1205,8 +1205,6 @@ EOF
$aExpectedAttributes = MetaModel::GetTransitionAttributes($sClass, $sStimulus, $sState);
$aDetails = array();
$sFormId = 'apply_stimulus';
$sFormPrefix = $sFormId.'_';
$iFieldIndex = 0;
$aFieldsMap = array();
$aValues = array();
@@ -1222,7 +1220,6 @@ EOF
$sReadyScript = '';
foreach($aExpectedAttributes as $sAttCode => $iExpectCode)
{
$sFieldInputId = $sFormPrefix.$sAttCode;
// Prompt for an attribute if
// - the attribute must be changed or must be displayed to the user for confirmation
// - or the field is mandatory and currently empty
@@ -1235,19 +1232,19 @@ EOF
if (count($aPrerequisites) > 0)
{
// When 'enabling' a field, all its prerequisites must be enabled too
$sFieldList = "['{$sFormPrefix}".implode("','{$sFormPrefix}", $aPrerequisites)."']";
$oP->add_ready_script("$('#enable_{$sFieldInputId}').bind('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, $sFieldList, true); } );\n");
$sFieldList = "['".implode("','", $aPrerequisites)."']";
$oP->add_ready_script("$('#enable_{$sAttCode}').bind('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, $sFieldList, true); } );\n");
}
$aDependents = MetaModel::GetDependentAttributes($sClass, $sAttCode); // List of attributes that are needed for the current one
if (count($aDependents) > 0)
{
// When 'disabling' a field, all its dependent fields must be disabled too
$sFieldList = "['{$sFormPrefix}".implode("','{$sFormPrefix}", $aDependents)."']";
$oP->add_ready_script("$('#enable_{$sFieldInputId}').bind('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, $sFieldList, false); } );\n");
$sFieldList = "['".implode("','", $aDependents)."']";
$oP->add_ready_script("$('#enable_{$sAttCode}').bind('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, $sFieldList, false); } );\n");
}
$aArgs = array('this' => $oObj);
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $oObj->Get($sAttCode), $oObj->GetEditValue($sAttCode), $sFieldInputId, '', $iExpectCode, $aArgs);
$sComments = '<input type="checkbox" checked id="enable_'.$sFieldInputId.'" onClick="ToogleField(this.checked, \''.$sFieldInputId.'\')"/>';
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $oObj->Get($sAttCode), $oObj->GetEditValue($sAttCode), $sAttCode, '', $iExpectCode, $aArgs);
$sComments = '<input type="checkbox" checked id="enable_'.$sAttCode.'" onClick="ToogleField(this.checked, \''.$sAttCode.'\')"/>';
if (!isset($aValues[$sAttCode]))
{
$aValues[$sAttCode] = array();
@@ -1275,11 +1272,11 @@ EOF
}
$sTip .= "</ul></p>";
$sTip = addslashes($sTip);
$sReadyScript .= "$('#multi_values_$sFieldInputId').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );\n";
$sComments .= '<div class="multi_values" id="multi_values_'.$sFieldInputId.'">'.count($aValues[$sAttCode]).'</div>';
$sReadyScript .= "$('#multi_values_$sAttCode').qtip( { content: '$sTip', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );\n";
$sComments .= '<div class="multi_values" id="multi_values_'.$sAttCode.'">'.count($aValues[$sAttCode]).'</div>';
}
$aDetails[] = array('label' => '<span>'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_$sFieldInputId\">$sHTMLValue</span>", 'comments' => $sComments);
$aFieldsMap[$sAttCode] = $sFieldInputId;
$aDetails[] = array('label' => '<span>'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_$sAttCode\">$sHTMLValue</span>", 'comments' => $sComments);
$aFieldsMap[$sAttCode] = $sAttCode;
$iFieldIndex++;
}
}
@@ -1292,7 +1289,7 @@ EOF
$oP->add('</div>');
}
$oP->add("<div class=\"wizContainer\">\n");
$oP->add("<form id=\"{$sFormId}\" method=\"post\" onSubmit=\"return OnSubmit('{$sFormId}');\">\n");
$oP->add("<form id=\"apply_stimulus\" method=\"post\" onSubmit=\"return OnSubmit('apply_stimulus');\">\n");
$oP->add("<table><tr><td>\n");
$oP->details($aDetails);
$oP->add("</td></tr></table>\n");
@@ -1331,7 +1328,7 @@ EOF
$oP->add_ready_script(
<<<EOF
// Starts the validation when the page is ready
CheckFields('{$sFormId}', false);
CheckFields('apply_stimulus', false);
$sReadyScript
EOF
);
@@ -1488,7 +1485,8 @@ EOF
'stimulus' => $sStimulus,
'origin' => 'console'
);
$oObj->DisplayStimulusForm($oP, $sStimulus, $aPrefillFormParam);
$oObj->PrefillForm('state_change', $aPrefillFormParam);
$oObj->DisplayStimulusForm($oP, $sStimulus);
}
else
{

View File

@@ -170,7 +170,7 @@ try
$oP->add("<form method=\"post\">\n");
$oP->add(Dict::S('UI:RunQuery:ExpressionToEvaluate')."<br/>\n");
$oP->add("<textarea cols=\"120\" rows=\"8\" id=\"expression\" name=\"expression\">".htmlentities($sExpression, ENT_QUOTES, 'UTF-8')."</textarea>\n");
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot()."/js/jquery.hotkeys.js");
$oP->add_linked_script(utils::GetDefaultUrlAppRoot()."/js/jquery.hotkeys.js");
$oP->add_ready_script(<<<EOF
$("#expression").select();
$("#expression").on("keydown", null, "ctrl+return", function() {

View File

@@ -1,7 +1,7 @@
iTop - version 2.5.1 - 10-Oct-2018
iTop - version 2.5.0 - 27-jun-2018
Readme file
iTop 2.5.1 is the 35th release of iTop.
iTop 2.5.0 is the 33rd release of iTop.
Changes since the previous version
-------------------------------------------------------------------

View File

@@ -235,20 +235,18 @@ if (class_exists('ZipArchive')) // The setup must be able to start even if the "
/**
* Create a normalized backup name, depending on the current date/time and Database
*
* @param string sMySQLBinDir Name and path, eventually containing itop placeholders + time formatting specs
* @param sNameSpec string Name and path, eventually containing itop placeholders + time formatting specs
*/
public function SetMySQLBinDir($sMySQLBinDir)
{
$this->sMySQLBinDir = $sMySQLBinDir;
}
/**
* Create a normalized backup name, depending on the current date/time and Database
*
* @param string sNameSpec Name and path, eventually containing itop placeholders + time formatting specs
*
* @return string
*/
/**
* Create a normalized backup name, depending on the current date/time and Database
*
* @param string sNameSpec Name and path, eventually containing itop placeholders + time formatting specs
*/
public function MakeName($sNameSpec = "__DB__-%Y-%m-%d")
{
$sFileName = $sNameSpec;
@@ -648,7 +646,7 @@ if (class_exists('ZipArchive')) // The setup must be able to start even if the "
{
if (empty($sData))
{
return '';
return;
}
return ' --'.$sCliArgName.'='.self::EscapeShellArg($sData);

View File

@@ -54,7 +54,7 @@ class SetupUtils
const MYSQL_MIN_VERSION = '5.5.3'; // 5.5 branch that is shipped with most distribution, and 5.5.3 to have utf8mb4 (see N°942)
// -- versions that will be the minimum in next iTop major release (warning if not met)
const PHP_NEXT_MIN_VERSION = ''; // no new PHP requirement for now in iTop 2.6
const MYSQL_NEXT_MIN_VERSION = '5.6.0'; // 5.6 to have fulltext on InnoDB for Tags fields (N°931)
const MYSQL_NEXT_MIN_VERSION = ''; // no new MySQL requirement for now in iTop 2.6
// -- First recent version that is not yet validated by Combodo (warning)
const PHP_NOT_VALIDATED_VERSION = '7.3.0';

View File

@@ -680,7 +680,7 @@ class ArchiveTar
*/
public function _error($p_message)
{
IssueLog::Error($p_message);
$this->error_object = $this->raiseError($p_message);
}
/**
@@ -688,7 +688,7 @@ class ArchiveTar
*/
public function _warning($p_message)
{
IssueLog::Warning($p_message);
$this->error_object = $this->raiseError($p_message);
}
/**

View File

@@ -309,16 +309,11 @@ class SearchForm
$aSelectedClasses = $oSearch->GetSelectedClasses();
foreach($aSelectedClasses as $sAlias => $sClassName)
{
if(array_key_exists($sAlias.'_zlist', $aAllFields))
{
$aAllFields['zlist'] = array_merge($aAllFields['zlist'], $aAllFields[$sAlias.'_zlist']);
unset($aAllFields[$sAlias.'_zlist']);
}
if(array_key_exists($sAlias.'_others', $aAllFields))
{
$aAllFields['others'] = array_merge($aAllFields['others'], $aAllFields[$sAlias.'_others']);
unset($aAllFields[$sAlias.'_others']);
}
$aAllFields['zlist'] = array_merge($aAllFields['zlist'], $aAllFields[$sAlias.'_zlist']);
unset($aAllFields[$sAlias.'_zlist']);
$aAllFields['others'] = array_merge($aAllFields['others'], $aAllFields[$sAlias.'_others']);
unset($aAllFields[$sAlias.'_others']);
}
return $aAllFields;
@@ -405,7 +400,7 @@ class SearchForm
protected function IsSubAttribute($oAttDef)
{
return (($oAttDef instanceof AttributeFriendlyName) || ($oAttDef instanceof AttributeSubItem));
return (($oAttDef instanceof AttributeFriendlyName) || ($oAttDef instanceof AttributeExternalField) || ($oAttDef instanceof AttributeSubItem));
}
/**
@@ -485,12 +480,13 @@ class SearchForm
{
$aOrCriterion = array();
$bIsEmptyExpression = true;
$aArgs = MetaModel::PrepareQueryArguments($aArgs, $oSearch->GetInternalParams());
if (method_exists($oSearch, 'GetCriteria'))
{
$oExpression = $oSearch->GetCriteria();
$aArgs = MetaModel::PrepareQueryArguments($aArgs, $oSearch->GetInternalParams());
if (!empty($aArgs))
{
try
@@ -525,50 +521,12 @@ class SearchForm
}
}
// Context induced criteria are read-only
$oAppContext = new ApplicationContext();
$sClass = $oSearch->GetClass();
$aCallSpec = array($sClass, 'MapContextParam');
$aContextParams = array();
if (is_callable($aCallSpec))
{
foreach($oAppContext->GetNames() as $sContextParam)
{
$sParamCode = call_user_func($aCallSpec, $sContextParam); //Map context parameter to the value/filter code depending on the class
if (!is_null($sParamCode))
{
$sParamValue = $oAppContext->GetCurrentValue($sContextParam, null);
if (!is_null($sParamValue))
{
$aContextParams[$sParamCode] = $sParamValue;
}
}
}
}
if ($bIsEmptyExpression)
{
// Add default criterion
$aOrCriterion = $this->GetDefaultCriterion($oSearch, $aContextParams);
$aOrCriterion = $this->GetDefaultCriterion($oSearch);
}
foreach($aContextParams as $sParamCode => $sParamValue)
{
// Add Context criteria in read only mode
$sAlias = $oSearch->GetClassAlias();
$oFieldExpression = new FieldExpression($sParamCode, $sAlias);
$oScalarExpression = new \ScalarExpression($sParamValue);
$oExpression = new \BinaryExpression($oFieldExpression, '=', $oScalarExpression);
$aCriterion = $oExpression->GetCriterion($oSearch, $aArgs);
$aCriterion['is_removable'] = false;
foreach($aOrCriterion as &$aAndExpression)
{
$aAndExpression['and'][] = $aCriterion;
}
}
return array('or' => $aOrCriterion);
}
@@ -682,11 +640,9 @@ class SearchForm
/**
* @param DBObjectSearch $oSearch
* @param $aContextParams
*
* @return array
*/
protected function GetDefaultCriterion($oSearch, &$aContextParams = array())
protected function GetDefaultCriterion($oSearch)
{
$aAndCriterion = array();
$sClass = $oSearch->GetClass();
@@ -705,20 +661,8 @@ class SearchForm
$sAlias = $oSearch->GetClassAlias();
foreach($aList as $sAttCode)
{
$oExpression = new FieldExpression($sAttCode, $sAlias);
$bIsRemovable = true;
if (isset($aContextParams[$sAttCode]))
{
// When a context parameter exists, use it with the default search criteria
$oFieldExpression = $oExpression;
$oScalarExpression = new \ScalarExpression($aContextParams[$sAttCode]);
$oExpression = new \BinaryExpression($oFieldExpression, '=', $oScalarExpression);
unset($aContextParams[$sAttCode]);
// Read only mode for search criteria from context
$bIsRemovable = false;
}
$aCriterion = $oExpression->GetCriterion($oSearch);
$aCriterion['is_removable'] = $bIsRemovable;
$oFieldExpression = new FieldExpression($sAttCode, $sAlias);
$aCriterion = $oFieldExpression->GetCriterion($oSearch);
if (isset($aCriterion['widget']) && ($aCriterion['widget'] != AttributeDefinition::SEARCH_WIDGET_TYPE_RAW))
{
$aAndCriterion[] = $aCriterion;

View File

@@ -29,8 +29,6 @@ use \Combodo\iTop\Form\Field\TextField;
* Description of TextAreaField
*
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
* @package \Combodo\iTop\Form\Field
* @since 2.3.0
*/
class TextAreaField extends TextField
{
@@ -115,7 +113,7 @@ class TextAreaField extends TextField
{
if ($this->GetFormat() == TextAreaField::ENUM_FORMAT_TEXT)
{
$sValue = \Str::pure2html($this->GetCurrentValue());
$sValue = $this->GetCurrentValue();
$sValue = AttributeText::RenderWikiHtml($sValue);
return "<div>".str_replace("\n", "<br>\n", $sValue).'</div>';
}

View File

@@ -576,7 +576,6 @@ EOF
);
// Target object others attributes
// TODO: Support for AttriubteImage, AttributeBlob
foreach ($this->oField->GetAttributesToDisplay(true) as $sAttCode)
{
if ($sAttCode !== 'id')
@@ -599,7 +598,7 @@ EOF
}
else
{
$aAttProperties['value'] = $oAttDef->GetAsHTML($oRemoteItem->Get($sAttCode));
$aAttProperties['value'] = $oAttDef->GetValueLabel($oRemoteItem->Get($sAttCode));
if ($oAttDef instanceof AttributeFriendlyName)
{

View File

@@ -112,26 +112,6 @@ class ItopDataTestCase extends ItopTestCase
return $oMyObj;
}
/**
* @param string $sClass
* @param $iKey
* @param array $aParams
*
* @return DBObject
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
*/
protected static function updateObject($sClass, $iKey, $aParams)
{
$oMyObj = MetaModel::GetObject($sClass, $iKey);
foreach($aParams as $sAttCode => $oValue)
{
$oMyObj->Set($sAttCode, $oValue);
}
$oMyObj->DBUpdate();
return $oMyObj;
}
/**
* Create an Organization in database

View File

@@ -26,8 +26,9 @@
namespace Combodo\iTop\Test\UnitTest\Core;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use DBObject;
use PHPUnit\Framework\TestCase;
/**
@@ -35,7 +36,7 @@ use DBObject;
* @preserveGlobalState disabled
* @backupGlobals disabled
*/
class DBObjectTest extends ItopDataTestCase
class DBObjectTest extends ItopTestCase
{
protected function setUp()
{
@@ -49,7 +50,7 @@ class DBObjectTest extends ItopDataTestCase
*/
public function testGetUIPage()
{
static::assertEquals('UI.php', DBObject::GetUIPage());
$this->assertEquals('UI.php', DBObject::GetUIPage());
}
/**
@@ -60,7 +61,7 @@ class DBObjectTest extends ItopDataTestCase
*/
public function testIsValidPKeyOK($key, $res)
{
static::assertEquals(DBObject::IsValidPKey($key), $res);
$this->assertEquals(DBObject::IsValidPKey($key), $res);
}
public function keyProviderOK()
@@ -79,11 +80,4 @@ class DBObjectTest extends ItopDataTestCase
array('PHP_INT_MIN', false));
}
public function testGetOriginal()
{
$oObject = $this->CreateUserRequest(190664);
static::assertNull($oObject->GetOriginal('sla_tto_passed'));
}
}

View File

@@ -731,18 +731,9 @@ try
$sMimeType = $oExporter->GetMimeType();
if ($sMimeType == 'text/html')
{
// Note: Using NiceWebPage only for HTML export as it includes JS scripts & files, which makes no sense in other export formats. More over, it breaks Excel spreadsheet import.
if($oExporter instanceof HTMLBulkExport)
{
$oP = new NiceWebPage('iTop export');
$oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});");
}
else
{
$oP = new WebPage('iTop export');
$oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell !
}
$oP = new NiceWebPage('iTop export');
$oP->add_style("body { overflow: auto; }");
$oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});");
}
else
{