mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-15 16:34:11 +01:00
Compare commits
1 Commits
feature/25
...
issue/6218
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74e87ed8e3 |
@@ -79,8 +79,6 @@ Then, **for a method** of an eligible class:
|
||||
|
||||
## Installation
|
||||
|
||||
Note : PHP7 is required. Migrating to PHP8 requires some additional work which is questionable as an alternative way to generate a documentation is being considered.
|
||||
|
||||
```
|
||||
cd .doc
|
||||
composer require phpdocumentor/phpdocumentor:~2 --dev
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 MiB |
@@ -1,14 +1,7 @@
|
||||
# iTop version history
|
||||
|
||||
```mermaid
|
||||
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'themeVariables': {
|
||||
'git0': 'lawngreen',
|
||||
'git3': 'dodgerblue',
|
||||
'git4': 'grey',
|
||||
'git5': 'grey',
|
||||
'git6': 'grey',
|
||||
'git7': 'grey'
|
||||
}, 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
|
||||
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
|
||||
gitGraph
|
||||
commit id: "2016-07-06" tag: "2.3.0" type: HIGHLIGHT
|
||||
branch support/2.3 order: 900
|
||||
@@ -75,30 +68,6 @@ gitGraph
|
||||
branch support/3.1 order: 840
|
||||
checkout support/3.1
|
||||
commit id: "2023-08-09" tag: "3.1.0-2"
|
||||
checkout support/2.7
|
||||
commit id: "2023-08-10" tag: "2.7.9"
|
||||
checkout support/3.1
|
||||
commit id: "2023-12-20" tag: "3.1.1"
|
||||
checkout develop
|
||||
commit id: "2024-01-15" tag: "Start 3.2" type: HIGHLIGHT
|
||||
branch support/3.2 order: 830
|
||||
checkout support/2.7
|
||||
commit id: "2024-01-17a" tag: "2.7.10"
|
||||
checkout support/3.0
|
||||
commit id: "2024-01-17b" tag: "3.0.4"
|
||||
checkout support/2.7
|
||||
commit id: "2024-09-28" tag: "2.7.11"
|
||||
checkout support/3.1
|
||||
commit id: "2024-09-27" tag: "3.1.2"
|
||||
checkout support/3.2
|
||||
commit id: "2024-06-25" tag: "3.2.0-beta1" type: REVERSE
|
||||
commit id: "2024-08-07" tag: "3.2.0"
|
||||
checkout support/2.7
|
||||
commit id: "2025-02-25" tag: "2.7.12"
|
||||
checkout support/3.1
|
||||
commit id: "2025-02-25 " tag: "3.1.3"
|
||||
checkout support/3.2
|
||||
commit id: "2025-02-25 " tag: "3.2.1"
|
||||
```
|
||||
|
||||
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
$(document).ready(function() {
|
||||
$("#viewer").iviewer({src: '{{ path('graphs/classes.svg') }}', zoom_animation: false});
|
||||
$('#viewer img').on('dragstart', function(event){
|
||||
$('#viewer img').bind('dragstart', function(event){
|
||||
event.preventDefault();
|
||||
});
|
||||
$(window).resize();
|
||||
|
||||
83
.github/pull_request_template.md
vendored
83
.github/pull_request_template.md
vendored
@@ -1,83 +0,0 @@
|
||||
<!--
|
||||
|
||||
IMPORTANT: Please follow the guidelines within this PR template before submitting it, it will greatly help us process your PR. 🙏
|
||||
|
||||
Any PRs not following the guidelines or with missing information will not be considered.
|
||||
|
||||
-->
|
||||
|
||||
## Base information
|
||||
| Question | Answer
|
||||
|---------------------------------------------------------------|--------
|
||||
| Related to a SourceForge thead / Another PR / Combodo ticket? | <!-- Put the URL -->
|
||||
| Type of change? | Bug fix / Enhancement / Translations
|
||||
|
||||
|
||||
## Symptom (bug) / Objective (enhancement)
|
||||
<!--
|
||||
If it's a bug
|
||||
- Explain the symptom in details
|
||||
- If possible put error messages, logs or screenshots (you can paste image directly in this editor).
|
||||
|
||||
If it's an enhancement
|
||||
- Describe what is blocking you, what is the objective with as much details as possible.
|
||||
- Add screenshots if it's related to UI.
|
||||
-->
|
||||
|
||||
|
||||
## Reproduction procedure (bug)
|
||||
<!--
|
||||
Remove this section only if it's NOT a bug.
|
||||
|
||||
Otherwise, explain step by step how to reproduce the issue on a standard iTop Community.
|
||||
|
||||
If it requires a custom datamodel, provide the minimal XML delta to reproduce it on a standard iTop Community.
|
||||
-->
|
||||
|
||||
1. On iTop x.y.z <!-- Put complete iTop version (eg. 3.1.0-2) -->
|
||||
2. With PHP x.y.z <!-- Put complete PHP version (eg. 8.1.24) -->
|
||||
2. First go there
|
||||
2. Then do that
|
||||
3. ...
|
||||
4. Finally, see that...
|
||||
|
||||
|
||||
## Cause (bug)
|
||||
<!--
|
||||
Remove this section only if it's NOT a bug.
|
||||
|
||||
Otherwise, explain what is the cause of the issue (where in the code and why)
|
||||
-->
|
||||
|
||||
|
||||
## Proposed solution (bug and enhancement)
|
||||
<!--
|
||||
Explain in details how you are proposing to solve this:
|
||||
- What did you do in the code and why
|
||||
- If you changed something in the UI, put before / after screenshots (you can paste image directly in this editor)
|
||||
-->
|
||||
|
||||
|
||||
## Checklist before requesting a review
|
||||
<!--
|
||||
Don't remove these lines, check them once done.
|
||||
-->
|
||||
- [ ] I have performed a self-review of my code
|
||||
- [ ] I have tested all changes I made on an iTop instance
|
||||
- [ ] I have added a unit test, otherwise I have explained why I couldn't
|
||||
- [ ] Is the PR clear and detailed enough so anyone can understand digging in the code?
|
||||
|
||||
## Checklist of things to do before PR is ready to merge
|
||||
<!--
|
||||
Things that needs to be done in the PR before it can be considered as ready to be merged
|
||||
|
||||
Examples:
|
||||
- Changes requested in the review
|
||||
- Unit test to add
|
||||
- Dictionary entries to translate
|
||||
- ...
|
||||
-->
|
||||
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
43
.github/workflows/action.yml
vendored
43
.github/workflows/action.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: Add PRs to Combodo PRs Dashboard
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
add-to-project:
|
||||
name: Add PR to Combodo Project
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if author is a member of the organization
|
||||
id: check-membership
|
||||
run: |
|
||||
ORG="Combodo"
|
||||
AUTHOR=$(jq -r .pull_request.user.login "$GITHUB_EVENT_PATH")
|
||||
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \
|
||||
"https://api.github.com/orgs/$ORG/members/$AUTHOR")
|
||||
if [ "$RESPONSE" == "404" ]; then
|
||||
echo "project_url=https://github.com/orgs/Combodo/projects/5" >> $GITHUB_ENV
|
||||
echo "is_member=false" >> $GITHUB_ENV
|
||||
else
|
||||
echo "project_url=https://github.com/orgs/Combodo/projects/4" >> $GITHUB_ENV
|
||||
echo "is_member=true" >> $GITHUB_ENV
|
||||
|
||||
fi
|
||||
|
||||
- name: Add internal tag if member
|
||||
if: env.is_member == 'true'
|
||||
run: |
|
||||
curl -X POST -H "Authorization: token ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/repos/Combodo/iTop/issues/${{ github.event.pull_request.number }}/labels \
|
||||
-d '{"labels":["internal"]}'
|
||||
env:
|
||||
is_member: ${{ env.is_member }}
|
||||
|
||||
- name: Add PR to the appropriate project
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.project_url }}
|
||||
github-token: ${{ secrets.PR_AUTOMATICALLY_ADD_TO_PROJECT }}
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -47,12 +47,6 @@ tests/*/vendor/*
|
||||
!/log/index.php
|
||||
!/log/web.config
|
||||
|
||||
# NPM: `jquery-ui` package is just there for vulnerability scans, so we don't want to version its files (only `jquery-ui-dist` is used within the code base)
|
||||
/node_modules/jquery-ui/**
|
||||
|
||||
# Symfony: Local env file
|
||||
/resources/symfony/.env.local
|
||||
|
||||
# PHPUnit: Cache file, local XML working copies
|
||||
/tests/php-unit-tests/.phpunit.result.cache
|
||||
/tests/php-unit-tests/phpunit.xml
|
||||
|
||||
@@ -4,7 +4,7 @@ $iBeginTime = time();
|
||||
chdir(__DIR__);
|
||||
|
||||
$aCommands = [
|
||||
'php composer/rmUnnecessaryFolders.php',
|
||||
'php composer/rmDeniedTestDir.php',
|
||||
'php build/commands/setupCssCompiler.php',
|
||||
// 'bash /tmp/gabuzomeu.sh',
|
||||
];
|
||||
@@ -22,13 +22,13 @@ $iElapsed = time() - $iBeginTime;
|
||||
|
||||
if (count($aFailedCommands))
|
||||
{
|
||||
fwrite(STDERR, "\nafterBuild execution failed! (in {$iElapsed}s)\n");
|
||||
fwrite(STDERR, "\nafterBuild execution failed! (in ${iElapsed}s)\n");
|
||||
fwrite(STDERR, "List of failling commands:\n - " . implode("\n - ", $aFailedCommands) . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
echo "\nDone ({$iElapsed}s)\n";
|
||||
echo "\nDone (${iElapsed}s)\n";
|
||||
exit(0);
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ function ExecCommand($cmd) {
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "| elapsed:{$iElapsed}s \n";
|
||||
echo "| elapsed:${iElapsed}s \n";
|
||||
}
|
||||
|
||||
if (!empty($stderr))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2010-2024 Combodo SAS
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -27,7 +27,7 @@ $iTopFolder = __DIR__."/../../../";
|
||||
require_once("$iTopFolder/approot.inc.php");
|
||||
require_once(APPROOT."/application/utils.inc.php");
|
||||
|
||||
if (PHP_SAPI !== 'cli')
|
||||
if (php_sapi_name() !== 'cli')
|
||||
{
|
||||
throw new \Exception('This script can only run from CLI');
|
||||
}
|
||||
@@ -48,4 +48,4 @@ if (!file_exists($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "Failed to compile $sCssFile, exiting.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2024 Combodo SAS
|
||||
* Copyright (C) 2010-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
@@ -26,7 +26,7 @@
|
||||
* @link https://getcomposer.org/doc/03-cli.md#show
|
||||
*/
|
||||
|
||||
$iTopFolder = __DIR__."/../../../";
|
||||
$iTopFolder = __DIR__."/../../";
|
||||
|
||||
require_once("$iTopFolder/approot.inc.php");
|
||||
$sApproot = APPROOT;
|
||||
73
.make/composer/rmDeniedTestDir.php
Normal file
73
.make/composer/rmDeniedTestDir.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2023 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/>
|
||||
*
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Composer\iTopComposer;
|
||||
|
||||
$iTopFolder = __DIR__ . "/../../" ;
|
||||
|
||||
require_once ("$iTopFolder/approot.inc.php");
|
||||
require_once (APPROOT."/setup/setuputils.class.inc.php");
|
||||
|
||||
if (php_sapi_name() !== 'cli')
|
||||
{
|
||||
throw new \Exception('This script can only run from CLI');
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
|
||||
$oiTopComposer = new iTopComposer();
|
||||
$aDeniedButStillPresent = $oiTopComposer->ListDeniedButStillPresent();
|
||||
|
||||
echo "\n";
|
||||
foreach ($aDeniedButStillPresent as $sDir)
|
||||
{
|
||||
if (false === iTopComposer::IsTestDir($sDir))
|
||||
{
|
||||
echo "ERROR found INVALID denied test dir: '$sDir'\n";
|
||||
throw new \Exception("$sDir must end with /Test/ or /test/");
|
||||
}
|
||||
|
||||
if (false === file_exists($sDir)) {
|
||||
echo "INFO $sDir is in denied list, but not existing on disk => skipping !\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
SetupUtils::rrmdir($sDir);
|
||||
echo "OK Remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
echo "\nFAILED to remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$aAllowedAndDeniedDirs = array_merge(
|
||||
$oiTopComposer->ListAllowedTestDir(),
|
||||
$oiTopComposer->ListDeniedTestDir()
|
||||
);
|
||||
$aExistingDirs = $oiTopComposer->ListAllTestDir();
|
||||
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
|
||||
if (false === empty($aMissing)) {
|
||||
echo "Some new tests dirs exists !\n"
|
||||
.' They must be declared either in the allowed or denied list in '.iTopComposer::class." (see N°2651).\n"
|
||||
.' List of dirs:'."\n".var_export($aMissing, true);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
||||
courier.php
|
||||
courierb.php
|
||||
courierbi.php
|
||||
courieri.php
|
||||
dejavusans.ctg.z
|
||||
dejavusans.php
|
||||
dejavusans.z
|
||||
dejavusansb.ctg.z
|
||||
dejavusansb.php
|
||||
dejavusansb.z
|
||||
dejavusansbi.ctg.z
|
||||
dejavusansbi.php
|
||||
dejavusansbi.z
|
||||
dejavusanscondensed.ctg.z
|
||||
dejavusanscondensed.php
|
||||
dejavusanscondensed.z
|
||||
dejavusanscondensedb.ctg.z
|
||||
dejavusanscondensedb.php
|
||||
dejavusanscondensedb.z
|
||||
dejavusanscondensedbi.ctg.z
|
||||
dejavusanscondensedbi.php
|
||||
dejavusanscondensedbi.z
|
||||
dejavusanscondensedi.ctg.z
|
||||
dejavusanscondensedi.php
|
||||
dejavusanscondensedi.z
|
||||
dejavusansextralight.ctg.z
|
||||
dejavusansextralight.php
|
||||
dejavusansextralight.z
|
||||
dejavusansi.ctg.z
|
||||
dejavusansi.php
|
||||
dejavusansi.z
|
||||
dejavusansmono.ctg.z
|
||||
dejavusansmono.php
|
||||
dejavusansmono.z
|
||||
dejavusansmonob.ctg.z
|
||||
dejavusansmonob.php
|
||||
dejavusansmonob.z
|
||||
dejavusansmonobi.ctg.z
|
||||
dejavusansmonobi.php
|
||||
dejavusansmonobi.z
|
||||
dejavusansmonoi.ctg.z
|
||||
dejavusansmonoi.php
|
||||
dejavusansmonoi.z
|
||||
droidsansfallback.ctg.z
|
||||
droidsansfallback.php
|
||||
droidsansfallback.z
|
||||
helvetica.php
|
||||
helveticab.php
|
||||
helveticabi.php
|
||||
helveticai.php
|
||||
symbol.php
|
||||
times.php
|
||||
timesb.php
|
||||
timesbi.php
|
||||
timesi.php
|
||||
zapfdingbats.php
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This script will copy custom fonts in the TCPDF lib fonts directory.
|
||||
* If you need to add other files :
|
||||
* - add the corresponding files in this script directory
|
||||
* - modify this script to copy also your files
|
||||
*
|
||||
* @since 2.7.0 N°1947 add DroidSansFallback font (see also PR #49 in the links below)
|
||||
* @since 2.7.0 N°2435 TCPPDF lib forked and added in composer.json (at that time the lib was announced as deprecated and rewritten in tecnickcom/tc-lib-pdf)
|
||||
* @since 3.2.0 N°7175 switch back to TCPDF original lib (which is finally still maintained, tecnickcom/tc-lib-pdf us still under dev), script creation to keep custom DroidSansFallback font
|
||||
*
|
||||
* @link https://github.com/Combodo/iTop/pull/49 add DroidSansFallback font
|
||||
* @link https://github.com/tecnickcom/TCPDF?tab=readme-ov-file#note TCPDF is in support only mode
|
||||
*/
|
||||
|
||||
$sItopRootFolder = realpath(__DIR__ . "/../../../../");
|
||||
$sCurrentScriptFileName = basename(__FILE__);
|
||||
|
||||
|
||||
require_once ("$sItopRootFolder/lib/autoload.php");
|
||||
|
||||
|
||||
$sTcPdfRootFolder = $sItopRootFolder.'/lib/tecnickcom/tcpdf';
|
||||
if (false === file_exists($sTcPdfRootFolder)) {
|
||||
echo $sCurrentScriptFileName.": No TCPDF lib detected, exiting !\n";
|
||||
return;
|
||||
}
|
||||
$sTcPdfFontsFolder = $sTcPdfRootFolder.'/fonts/';
|
||||
|
||||
|
||||
/**
|
||||
* 1) Cleaning up the fonts directory to keep only the ones we want in iTop
|
||||
*/
|
||||
echo $sCurrentScriptFileName.": ---1) Cleaning up the fonts files\n";
|
||||
$aTcpdfDefaultFontsToKeepInItop = file(__DIR__.'/tcpdfDefaultFontsToKeepInItop.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
|
||||
$aTcpdfFontsDirContent = scandir($sTcPdfFontsFolder);
|
||||
foreach ($aTcpdfFontsDirContent as $sTcpdfFontResourceName) {
|
||||
if ($sTcpdfFontResourceName === '.') {
|
||||
continue;
|
||||
}
|
||||
if ($sTcpdfFontResourceName === '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array($sTcpdfFontResourceName, $aTcpdfDefaultFontsToKeepInItop, true)) {
|
||||
echo $sCurrentScriptFileName.": Removing $sTcpdfFontResourceName !\n";
|
||||
|
||||
$sTcpdfFontResourceFullPath = $sTcPdfFontsFolder.$sTcpdfFontResourceName;
|
||||
if (is_file($sTcpdfFontResourceFullPath)) {
|
||||
unlink($sTcpdfFontResourceFullPath);
|
||||
} elseif (is_dir($sTcpdfFontResourceFullPath)) {
|
||||
rrmdir($sTcpdfFontResourceFullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2) Then adding the DroidSansFallback font (useful for CJK data for example)
|
||||
*/
|
||||
echo $sCurrentScriptFileName.": ---2) Copying font files to TCPDF ($sTcPdfFontsFolder)...\n";
|
||||
$aFontFilesToCopy = glob(__DIR__.'\droidsansfallback.*');
|
||||
foreach ($aFontFilesToCopy as $sFontFileToCopy) {
|
||||
$sFontFileName = basename($sFontFileToCopy);
|
||||
echo $sCurrentScriptFileName.': copying '.$sFontFileName."\n";
|
||||
copy($sFontFileToCopy, $sTcPdfFontsFolder.$sFontFileName);
|
||||
}
|
||||
echo $sCurrentScriptFileName.": Done !\n";
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Recursively delete a directory and its content
|
||||
*
|
||||
* @param $sDirToRemovePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function rrmdir($sDirToRemovePath):void
|
||||
{
|
||||
if (is_dir($sDirToRemovePath)) {
|
||||
$objects = scandir($sDirToRemovePath);
|
||||
foreach ($objects as $object) {
|
||||
if ($object != "." && $object != "..") {
|
||||
if (filetype($sDirToRemovePath."/".$object) == "dir") {
|
||||
rrmdir($sDirToRemovePath."/".$object);
|
||||
} else {
|
||||
unlink($sDirToRemovePath."/".$object);
|
||||
}
|
||||
}
|
||||
}
|
||||
reset($objects);
|
||||
rmdir($sDirToRemovePath);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2024 Combodo SAS
|
||||
*
|
||||
* 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/>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensure that the files for folder browsing protection (.htaccess, web.config) are kept after an "npm install/update" command
|
||||
*/
|
||||
|
||||
$iTopFolder = __DIR__."/../../../";
|
||||
|
||||
require_once("$iTopFolder/approot.inc.php");
|
||||
|
||||
$sDependenciesRootFolderAbsPath = APPROOT . "node_modules/";
|
||||
$aFilesToCheck = [
|
||||
".htaccess",
|
||||
"web.config",
|
||||
];
|
||||
|
||||
echo "This command aims at ensuring that folder browsing protection files (.htaccess, web.config) are present in the dependencies folder even after an install/upgrade command\n";
|
||||
echo "Checking files:\n";
|
||||
|
||||
foreach($aFilesToCheck as $sFileToCheck) {
|
||||
if (file_exists($sDependenciesRootFolderAbsPath . $sFileToCheck)) {
|
||||
echo "✔️ $sFileToCheck is present\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// If missing, copy the one from /lib as it contains the necessary allow/deny directives for third-parties
|
||||
copy(APPROOT . "lib/$sFileToCheck", $sDependenciesRootFolderAbsPath . $sFileToCheck);
|
||||
echo "✔️ $sFileToCheck was missing and has been re-created\n";
|
||||
}
|
||||
|
||||
// Ensure separation with following scripts
|
||||
echo "\n";
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2024 Combodo SAS
|
||||
*
|
||||
* 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/>
|
||||
*
|
||||
*/
|
||||
|
||||
$iTopFolder = __DIR__ . "/../../" ;
|
||||
|
||||
require_once ("$iTopFolder/approot.inc.php");
|
||||
require_once (APPROOT."/setup/setuputils.class.inc.php");
|
||||
|
||||
if (php_sapi_name() !== 'cli')
|
||||
{
|
||||
throw new \Exception('This script can only run from CLI');
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
|
||||
// Read params
|
||||
$key = array_search("--manager", $argv);
|
||||
if (false === $key || false === isset($argv[$key + 1]) ) {
|
||||
throw new \InvalidArgumentException("Usage: " . __FILE__ . " --manager composer|npm");
|
||||
}
|
||||
$sDependenciesHandlerCode = $argv[$key + 1];
|
||||
|
||||
switch ($sDependenciesHandlerCode) {
|
||||
case "composer":
|
||||
$sDependenciesHandlerFQCN = \Combodo\iTop\Dependencies\Composer\iTopComposer::class;
|
||||
break;
|
||||
|
||||
case "npm":
|
||||
$sDependenciesHandlerFQCN = \Combodo\iTop\Dependencies\NPM\iTopNPM::class;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception("Invalid dependencies handler code, $sDependenciesHandlerCode given, expected composer|npm");
|
||||
}
|
||||
|
||||
// Start handler
|
||||
$oDependenciesHandler = new $sDependenciesHandlerFQCN();
|
||||
$aDeniedButStillPresent = $oDependenciesHandler->ListDeniedButStillPresentFilesAbsPaths();
|
||||
|
||||
echo "\n";
|
||||
foreach ($aDeniedButStillPresent as $sDir)
|
||||
{
|
||||
if (false === $oDependenciesHandler::IsQuestionnableFile($sDir))
|
||||
{
|
||||
echo "ERROR found INVALID denied test dir: '$sDir'\n";
|
||||
throw new \RuntimeException("$sDir is in the denied list but doesn't comply with the rule (see IsQuestionnableFolder method)");
|
||||
}
|
||||
|
||||
if (false === file_exists($sDir)) {
|
||||
echo "INFO $sDir is in denied list, but not existing on disk => skipping !\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if(is_dir($sDir)){
|
||||
SetupUtils::rrmdir($sDir);
|
||||
}
|
||||
else{
|
||||
unlink($sDir);
|
||||
}
|
||||
echo "✔️ Remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
echo "\n❌ FAILED to remove denied test dir: '$sDir'\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$aAllowedAndDeniedDirs = array_merge(
|
||||
$oDependenciesHandler->ListAllowedFilesAbsPaths(),
|
||||
$oDependenciesHandler->ListDeniedFilesAbsPaths()
|
||||
);
|
||||
$aExistingDirs = $oDependenciesHandler->ListAllFilesAbsPaths();
|
||||
$aMissing = array_diff($aExistingDirs, $aAllowedAndDeniedDirs);
|
||||
if (false === empty($aMissing)) {
|
||||
echo "Some new tests dirs exists !\n"
|
||||
." They must be declared either in the allowed or denied list in {$sDependenciesHandlerFQCN}\n"
|
||||
.' List of dirs:'."\n".var_export($aMissing, true)."\n";
|
||||
}
|
||||
|
||||
// Ensure separation with following scripts
|
||||
echo "\n";
|
||||
@@ -25,34 +25,12 @@
|
||||
|
||||
|
||||
if (count($argv) === 1) {
|
||||
echo "⚠ You must pass the base tag/sha1 as parameter\n";
|
||||
echo '⚠ You must pass the base tag/sha1 as parameter';
|
||||
exit(1);
|
||||
}
|
||||
$sBaseReference = $argv[1];
|
||||
|
||||
|
||||
/**
|
||||
* Replace the Github emojis codes by their UTF-8 character equivalent
|
||||
*/
|
||||
function ReplaceGitmojis(string $sLine)
|
||||
{
|
||||
static $aGitmojis = null;
|
||||
|
||||
if ($aGitmojis === null) {
|
||||
$aRawGitmojis = json_decode(trim(file_get_contents(__DIR__.'/gitmojis.json')), true);
|
||||
if ($aRawGitmojis === false) {
|
||||
echo "\nFailed to parse ".__DIR__."/gitmojis.json, emoji codes will not be replaced by their unicode equivalent.\n";
|
||||
} else {
|
||||
foreach($aRawGitmojis["gitmojis"] as $aGitmoji) {
|
||||
$aGitmojis[$aGitmoji['code']] = $aGitmoji['emoji'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_array($aGitmojis)) {
|
||||
return str_replace(array_keys($aGitmojis), array_values($aGitmojis), $sLine);
|
||||
}
|
||||
}
|
||||
|
||||
//--- Get log
|
||||
$sGitLogCommand = 'git log --decorate --pretty="%h;%s" --date-order --no-merges '.$sBaseReference.'..HEAD';
|
||||
$sGitLogRaw = shell_exec($sGitLogCommand);
|
||||
@@ -95,5 +73,5 @@ echo "\n";
|
||||
echo "# Logs line without bug referenced\n";
|
||||
echo "sha1;subject\n";
|
||||
foreach ($aLogLineNoBug as $sLogLine) {
|
||||
echo ReplaceGitmojis($sLogLine)."\n";
|
||||
}
|
||||
echo "$sLogLine\n";
|
||||
}
|
||||
@@ -1,589 +0,0 @@
|
||||
{
|
||||
"$schema": "https://gitmoji.dev/api/gitmojis/schema",
|
||||
"gitmojis": [
|
||||
{
|
||||
"emoji": "🎨",
|
||||
"entity": "🎨",
|
||||
"code": ":art:",
|
||||
"description": "Improve structure / format of the code.",
|
||||
"name": "art",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "⚡️",
|
||||
"entity": "⚡",
|
||||
"code": ":zap:",
|
||||
"description": "Improve performance.",
|
||||
"name": "zap",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔥",
|
||||
"entity": "🔥",
|
||||
"code": ":fire:",
|
||||
"description": "Remove code or files.",
|
||||
"name": "fire",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🐛",
|
||||
"entity": "🐛",
|
||||
"code": ":bug:",
|
||||
"description": "Fix a bug.",
|
||||
"name": "bug",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🚑️",
|
||||
"entity": "🚑",
|
||||
"code": ":ambulance:",
|
||||
"description": "Critical hotfix.",
|
||||
"name": "ambulance",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "✨",
|
||||
"entity": "✨",
|
||||
"code": ":sparkles:",
|
||||
"description": "Introduce new features.",
|
||||
"name": "sparkles",
|
||||
"semver": "minor"
|
||||
},
|
||||
{
|
||||
"emoji": "📝",
|
||||
"entity": "📝",
|
||||
"code": ":memo:",
|
||||
"description": "Add or update documentation.",
|
||||
"name": "memo",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🚀",
|
||||
"entity": "🚀",
|
||||
"code": ":rocket:",
|
||||
"description": "Deploy stuff.",
|
||||
"name": "rocket",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "💄",
|
||||
"entity": "&#ff99cc;",
|
||||
"code": ":lipstick:",
|
||||
"description": "Add or update the UI and style files.",
|
||||
"name": "lipstick",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🎉",
|
||||
"entity": "🎉",
|
||||
"code": ":tada:",
|
||||
"description": "Begin a project.",
|
||||
"name": "tada",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "✅",
|
||||
"entity": "✅",
|
||||
"code": ":white_check_mark:",
|
||||
"description": "Add, update, or pass tests.",
|
||||
"name": "white-check-mark",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🔒️",
|
||||
"entity": "🔒",
|
||||
"code": ":lock:",
|
||||
"description": "Fix security or privacy issues.",
|
||||
"name": "lock",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔐",
|
||||
"entity": "🔐",
|
||||
"code": ":closed_lock_with_key:",
|
||||
"description": "Add or update secrets.",
|
||||
"name": "closed-lock-with-key",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🔖",
|
||||
"entity": "🔖",
|
||||
"code": ":bookmark:",
|
||||
"description": "Release / Version tags.",
|
||||
"name": "bookmark",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🚨",
|
||||
"entity": "🚨",
|
||||
"code": ":rotating_light:",
|
||||
"description": "Fix compiler / linter warnings.",
|
||||
"name": "rotating-light",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🚧",
|
||||
"entity": "🚧",
|
||||
"code": ":construction:",
|
||||
"description": "Work in progress.",
|
||||
"name": "construction",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "💚",
|
||||
"entity": "💚",
|
||||
"code": ":green_heart:",
|
||||
"description": "Fix CI Build.",
|
||||
"name": "green-heart",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "⬇️",
|
||||
"entity": "⬇️",
|
||||
"code": ":arrow_down:",
|
||||
"description": "Downgrade dependencies.",
|
||||
"name": "arrow-down",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "⬆️",
|
||||
"entity": "⬆️",
|
||||
"code": ":arrow_up:",
|
||||
"description": "Upgrade dependencies.",
|
||||
"name": "arrow-up",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "📌",
|
||||
"entity": "📌",
|
||||
"code": ":pushpin:",
|
||||
"description": "Pin dependencies to specific versions.",
|
||||
"name": "pushpin",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "👷",
|
||||
"entity": "👷",
|
||||
"code": ":construction_worker:",
|
||||
"description": "Add or update CI build system.",
|
||||
"name": "construction-worker",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "📈",
|
||||
"entity": "📈",
|
||||
"code": ":chart_with_upwards_trend:",
|
||||
"description": "Add or update analytics or track code.",
|
||||
"name": "chart-with-upwards-trend",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "♻️",
|
||||
"entity": "♻",
|
||||
"code": ":recycle:",
|
||||
"description": "Refactor code.",
|
||||
"name": "recycle",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "➕",
|
||||
"entity": "➕",
|
||||
"code": ":heavy_plus_sign:",
|
||||
"description": "Add a dependency.",
|
||||
"name": "heavy-plus-sign",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "➖",
|
||||
"entity": "➖",
|
||||
"code": ":heavy_minus_sign:",
|
||||
"description": "Remove a dependency.",
|
||||
"name": "heavy-minus-sign",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔧",
|
||||
"entity": "🔧",
|
||||
"code": ":wrench:",
|
||||
"description": "Add or update configuration files.",
|
||||
"name": "wrench",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔨",
|
||||
"entity": "🔨",
|
||||
"code": ":hammer:",
|
||||
"description": "Add or update development scripts.",
|
||||
"name": "hammer",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🌐",
|
||||
"entity": "🌐",
|
||||
"code": ":globe_with_meridians:",
|
||||
"description": "Internationalization and localization.",
|
||||
"name": "globe-with-meridians",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "✏️",
|
||||
"entity": "",
|
||||
"code": ":pencil2:",
|
||||
"description": "Fix typos.",
|
||||
"name": "pencil2",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "💩",
|
||||
"entity": "",
|
||||
"code": ":poop:",
|
||||
"description": "Write bad code that needs to be improved.",
|
||||
"name": "poop",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "⏪️",
|
||||
"entity": "⏪",
|
||||
"code": ":rewind:",
|
||||
"description": "Revert changes.",
|
||||
"name": "rewind",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔀",
|
||||
"entity": "🔀",
|
||||
"code": ":twisted_rightwards_arrows:",
|
||||
"description": "Merge branches.",
|
||||
"name": "twisted-rightwards-arrows",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "📦️",
|
||||
"entity": "F4E6;",
|
||||
"code": ":package:",
|
||||
"description": "Add or update compiled files or packages.",
|
||||
"name": "package",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "👽️",
|
||||
"entity": "F47D;",
|
||||
"code": ":alien:",
|
||||
"description": "Update code due to external API changes.",
|
||||
"name": "alien",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🚚",
|
||||
"entity": "F69A;",
|
||||
"code": ":truck:",
|
||||
"description": "Move or rename resources (e.g.: files, paths, routes).",
|
||||
"name": "truck",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "📄",
|
||||
"entity": "F4C4;",
|
||||
"code": ":page_facing_up:",
|
||||
"description": "Add or update license.",
|
||||
"name": "page-facing-up",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "💥",
|
||||
"entity": "💥",
|
||||
"code": ":boom:",
|
||||
"description": "Introduce breaking changes.",
|
||||
"name": "boom",
|
||||
"semver": "major"
|
||||
},
|
||||
{
|
||||
"emoji": "🍱",
|
||||
"entity": "F371",
|
||||
"code": ":bento:",
|
||||
"description": "Add or update assets.",
|
||||
"name": "bento",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "♿️",
|
||||
"entity": "♿",
|
||||
"code": ":wheelchair:",
|
||||
"description": "Improve accessibility.",
|
||||
"name": "wheelchair",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "💡",
|
||||
"entity": "💡",
|
||||
"code": ":bulb:",
|
||||
"description": "Add or update comments in source code.",
|
||||
"name": "bulb",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🍻",
|
||||
"entity": "🍻",
|
||||
"code": ":beers:",
|
||||
"description": "Write code drunkenly.",
|
||||
"name": "beers",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "💬",
|
||||
"entity": "💬",
|
||||
"code": ":speech_balloon:",
|
||||
"description": "Add or update text and literals.",
|
||||
"name": "speech-balloon",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🗃️",
|
||||
"entity": "🗃",
|
||||
"code": ":card_file_box:",
|
||||
"description": "Perform database related changes.",
|
||||
"name": "card-file-box",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔊",
|
||||
"entity": "🔊",
|
||||
"code": ":loud_sound:",
|
||||
"description": "Add or update logs.",
|
||||
"name": "loud-sound",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🔇",
|
||||
"entity": "🔇",
|
||||
"code": ":mute:",
|
||||
"description": "Remove logs.",
|
||||
"name": "mute",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "👥",
|
||||
"entity": "👥",
|
||||
"code": ":busts_in_silhouette:",
|
||||
"description": "Add or update contributor(s).",
|
||||
"name": "busts-in-silhouette",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🚸",
|
||||
"entity": "🚸",
|
||||
"code": ":children_crossing:",
|
||||
"description": "Improve user experience / usability.",
|
||||
"name": "children-crossing",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🏗️",
|
||||
"entity": "f3d7;",
|
||||
"code": ":building_construction:",
|
||||
"description": "Make architectural changes.",
|
||||
"name": "building-construction",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "📱",
|
||||
"entity": "📱",
|
||||
"code": ":iphone:",
|
||||
"description": "Work on responsive design.",
|
||||
"name": "iphone",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🤡",
|
||||
"entity": "🤡",
|
||||
"code": ":clown_face:",
|
||||
"description": "Mock things.",
|
||||
"name": "clown-face",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🥚",
|
||||
"entity": "🥚",
|
||||
"code": ":egg:",
|
||||
"description": "Add or update an easter egg.",
|
||||
"name": "egg",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🙈",
|
||||
"entity": "bdfe7;",
|
||||
"code": ":see_no_evil:",
|
||||
"description": "Add or update a .gitignore file.",
|
||||
"name": "see-no-evil",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "📸",
|
||||
"entity": "📸",
|
||||
"code": ":camera_flash:",
|
||||
"description": "Add or update snapshots.",
|
||||
"name": "camera-flash",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "⚗️",
|
||||
"entity": "⚗",
|
||||
"code": ":alembic:",
|
||||
"description": "Perform experiments.",
|
||||
"name": "alembic",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🔍️",
|
||||
"entity": "🔍",
|
||||
"code": ":mag:",
|
||||
"description": "Improve SEO.",
|
||||
"name": "mag",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🏷️",
|
||||
"entity": "🏷",
|
||||
"code": ":label:",
|
||||
"description": "Add or update types.",
|
||||
"name": "label",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🌱",
|
||||
"entity": "🌱",
|
||||
"code": ":seedling:",
|
||||
"description": "Add or update seed files.",
|
||||
"name": "seedling",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🚩",
|
||||
"entity": "🚩",
|
||||
"code": ":triangular_flag_on_post:",
|
||||
"description": "Add, update, or remove feature flags.",
|
||||
"name": "triangular-flag-on-post",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🥅",
|
||||
"entity": "🥅",
|
||||
"code": ":goal_net:",
|
||||
"description": "Catch errors.",
|
||||
"name": "goal-net",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "💫",
|
||||
"entity": "💫",
|
||||
"code": ":dizzy:",
|
||||
"description": "Add or update animations and transitions.",
|
||||
"name": "dizzy",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🗑️",
|
||||
"entity": "🗑",
|
||||
"code": ":wastebasket:",
|
||||
"description": "Deprecate code that needs to be cleaned up.",
|
||||
"name": "wastebasket",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🛂",
|
||||
"entity": "🛂",
|
||||
"code": ":passport_control:",
|
||||
"description": "Work on code related to authorization, roles and permissions.",
|
||||
"name": "passport-control",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🩹",
|
||||
"entity": "🩹",
|
||||
"code": ":adhesive_bandage:",
|
||||
"description": "Simple fix for a non-critical issue.",
|
||||
"name": "adhesive-bandage",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🧐",
|
||||
"entity": "🧐",
|
||||
"code": ":monocle_face:",
|
||||
"description": "Data exploration/inspection.",
|
||||
"name": "monocle-face",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "⚰️",
|
||||
"entity": "⚰",
|
||||
"code": ":coffin:",
|
||||
"description": "Remove dead code.",
|
||||
"name": "coffin",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🧪",
|
||||
"entity": "🧪",
|
||||
"code": ":test_tube:",
|
||||
"description": "Add a failing test.",
|
||||
"name": "test-tube",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "👔",
|
||||
"entity": "👔",
|
||||
"code": ":necktie:",
|
||||
"description": "Add or update business logic.",
|
||||
"name": "necktie",
|
||||
"semver": "patch"
|
||||
},
|
||||
{
|
||||
"emoji": "🩺",
|
||||
"entity": "🩺",
|
||||
"code": ":stethoscope:",
|
||||
"description": "Add or update healthcheck.",
|
||||
"name": "stethoscope",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🧱",
|
||||
"entity": "🧱",
|
||||
"code": ":bricks:",
|
||||
"description": "Infrastructure related changes.",
|
||||
"name": "bricks",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🧑💻",
|
||||
"entity": "🧑‍💻",
|
||||
"code": ":technologist:",
|
||||
"description": "Improve developer experience.",
|
||||
"name": "technologist",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "💸",
|
||||
"entity": "💸",
|
||||
"code": ":money_with_wings:",
|
||||
"description": "Add sponsorships or money related infrastructure.",
|
||||
"name": "money-with-wings",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🧵",
|
||||
"entity": "🧵",
|
||||
"code": ":thread:",
|
||||
"description": "Add or update code related to multithreading or concurrency.",
|
||||
"name": "thread",
|
||||
"semver": null
|
||||
},
|
||||
{
|
||||
"emoji": "🦺",
|
||||
"entity": "🦺",
|
||||
"code": ":safety_vest:",
|
||||
"description": "Add or update code related to validation.",
|
||||
"name": "safety-vest",
|
||||
"semver": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -140,7 +140,7 @@ When your code is working, please:
|
||||
* Pull request description: mind to add all the information useful to understand why you're suggesting this modification and anything necessary to dive into your work. Especially:
|
||||
- Bugfixes: exact steps to reproduce the bug (given/when/then), description of the bug cause and what solution is implemented
|
||||
- Enhancements: use cases, implementation details if needed
|
||||
* Mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option ! (note that if you are working with an org fork, this option [won't be available](https://github.com/orgs/community/discussions/5634))
|
||||
* Mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option !
|
||||
|
||||
|
||||
## 🙏 We are thankful
|
||||
@@ -159,6 +159,6 @@ We have one sticker per contribution type. You might get multiple stickers with
|
||||
* Beta tester: Test and give feedback on beta releases
|
||||
* Extension developer: Develop and publish an extension
|
||||
|
||||
Here is the design of each stickers for year 2024:
|
||||
Here is the design of each stickers for year 2022:
|
||||
|
||||

|
||||

|
||||
|
||||
34
README.md
34
README.md
@@ -1,9 +1,5 @@
|
||||
<p align="center"><a href="https://combodo.com" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="/images/logos/logo-itop-baseline-light.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="/images/logos/logo-itop-baseline-dark.svg">
|
||||
<img src="/images/logos/logo-itop-baseline-light.svg" width="350" alt="Logo iTop with baseline" />
|
||||
</picture>
|
||||
<p align="center"><a href="https://www.combodo.com/itop-193" target="_blank">
|
||||
<img src="https://www.combodo.com/logos/logo-itop-baseline.svg" width=350>
|
||||
</a></p>
|
||||
|
||||
|
||||
@@ -80,9 +76,7 @@ We would like to give a special thank you 🤗 to the people from the community
|
||||
|
||||
### Names
|
||||
|
||||
- Al Hallak, Amr (a.k.a [@v4yne1](https://github.com/v4yne1))
|
||||
- Alves, David
|
||||
- Audon, Florian
|
||||
- Beck, Pedro
|
||||
- Beer, Christian (a.k.a [@ChristianBeer](https://www.github.com/ChristianBeer))
|
||||
- Bilger, Jean-François
|
||||
@@ -93,45 +87,29 @@ We would like to give a special thank you 🤗 to the people from the community
|
||||
- Castro, Randall Badilla
|
||||
- Colantoni, Maria Laura
|
||||
- Couronné, Guy
|
||||
- Dejin, Bie (a.k.a [@bdejin](https://github.com/bdejin))
|
||||
- Delicado, Elodie
|
||||
- Dvořák, Lukáš
|
||||
- Goethals, Stefan
|
||||
- Giuva, Vincenzo Katriel (a.k.a [@DarkNight97boss](https://github.com/DarkNight97boss))
|
||||
- Gumble, David
|
||||
- Heloir, Arthur
|
||||
- Janssens, Jelle (a.k.a [@janssensjelle](https://github.com/janssensjelle))
|
||||
- Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb))
|
||||
- Kaltefleiter, Lars (a.k.a [@larhip](https://www.github.com/larhip))
|
||||
- Khamit, Shamil
|
||||
- Kincel, Martin
|
||||
- Konečný, Kamil
|
||||
- Kunin, Vladimir
|
||||
- Lassiter, Denis (a.k.a [@delassiter](https://github.com/delassiter))
|
||||
- Lassiter, Dennis
|
||||
- Lazcano, Federico
|
||||
- Lucas, Jonathan
|
||||
- Malik, Remie
|
||||
- Mantel, Ina
|
||||
- Martin, Pierre (a.k.a [@Worty](https://github.com/worty-syn))
|
||||
- Melchiorre, Romain
|
||||
- Mindêllo de Andrade, Lucas (a.k.a [@rokam](https://www.github.com/rokam))
|
||||
- Mozart de Oliveira, Eduardo (a.k.a [@eduardomozart](https://github.com/eduardomozart))
|
||||
- Raenker, Martin
|
||||
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
|
||||
- Rosenke, Stephan
|
||||
- Rossi, Tommaso (a.k.a [@tomrss](https://www.github.com/tomrss))
|
||||
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
|
||||
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
|
||||
- Seki, Shoji
|
||||
- Shilov, Vladimir
|
||||
- Stetina, Pavel (a.k.a [@Stetinac](https://github.com/Stetinac))
|
||||
- Stukalov, Ilya (a.k.a [@ilya](https://www.github.com/ilya-stukalov))
|
||||
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
|
||||
- Toraya, Chairat (a.k.a [@Kyokito1412](https://github.com/Kyokito1412))
|
||||
- Stukalov, Ilya (a.k.a [@ilya](https://www.github.com/ilya)-stukalov)
|
||||
- Tulio, Marco
|
||||
- Turrubiates, Miguel
|
||||
- Višnjić, Aldin (a.k.a[@viliald](https://github.com/viliald))
|
||||
- Vlk, Karel (a.k.a [@vlk-charles](https://www.github.com/vlk-charles))
|
||||
|
||||
### Aliases
|
||||
|
||||
@@ -152,6 +130,4 @@ We would like to give a special thank you 🤗 to the people from the community
|
||||
- [ITOMIG](https://www.itomig.de/)
|
||||
- [Pimkie](https://www.pimkie.com/)
|
||||
- [Super-Visions](https://www.super-visions.com/)
|
||||
- [Defence Tech Cyber Security - Malware Lab](https://github.com/DefenceTechSecurity)
|
||||
- Orange Cyberdefense
|
||||
- MipihSIB
|
||||
|
||||
|
||||
362
addons/userrights/userrightsmatrix.class.inc.php
Normal file
362
addons/userrights/userrightsmatrix.class.inc.php
Normal file
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2023 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/>
|
||||
|
||||
/**
|
||||
* UserRightsMatrix (User management Module)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
class UserRightsMatrixClassGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixclasses",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
}
|
||||
}
|
||||
|
||||
class UserRightsMatrixClassStimulusGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixclassesstimulus",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
}
|
||||
}
|
||||
|
||||
class UserRightsMatrixAttributeGrant extends DBObject
|
||||
{
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "addon/userrights",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
"reconc_keys" => array(),
|
||||
"db_table" => "priv_ur_matrixattributes",
|
||||
"db_key_field" => "id",
|
||||
"db_finalclass_field" => "",
|
||||
);
|
||||
MetaModel::Init_Params($aParams);
|
||||
//MetaModel::Init_InheritAttributes();
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey("userid", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"userid", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalField("login", array("allowed_values"=>null, "extkey_attcode"=> 'userid', "target_attcode"=>"login")));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("attcode", array("allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("action", array("allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
{
|
||||
static public $m_aActionCodes = array(
|
||||
UR_ACTION_READ => 'read',
|
||||
UR_ACTION_MODIFY => 'modify',
|
||||
UR_ACTION_DELETE => 'delete',
|
||||
UR_ACTION_BULK_READ => 'bulk read',
|
||||
UR_ACTION_BULK_MODIFY => 'bulk modify',
|
||||
UR_ACTION_BULK_DELETE => 'bulk delete',
|
||||
);
|
||||
|
||||
// Installation: create the very first user
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||
{
|
||||
// Maybe we should check that no other user with userid == 0 exists
|
||||
$oUser = new UserLocal();
|
||||
$oUser->Set('login', $sAdminUser);
|
||||
$oUser->Set('password', $sAdminPwd);
|
||||
$oUser->Set('contactid', 1); // one is for root !
|
||||
$oUser->Set('language', $sLanguage); // Language was chosen during the installation
|
||||
|
||||
// Now record the admin user object
|
||||
$iUserId = $oUser->DBInsertNoReload();
|
||||
$this->SetupUser($iUserId, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsAdministrator($oUser)
|
||||
{
|
||||
return ($oUser->GetKey() == 1);
|
||||
}
|
||||
|
||||
public function IsPortalUser($oUser)
|
||||
{
|
||||
return ($oUser->GetKey() == 1);
|
||||
}
|
||||
|
||||
// Deprecated - create a new module !
|
||||
public function Setup()
|
||||
{
|
||||
// Users must be added manually
|
||||
// This procedure will then update the matrix when a new user is found or a new class/attribute appears
|
||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT User"));
|
||||
while ($oUser = $oUserSet->Fetch())
|
||||
{
|
||||
$this->SetupUser($oUser->GetKey());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function SetupUser($iUserId, $bNewUser = false)
|
||||
{
|
||||
foreach(array('bizmodel', 'application', 'gui', 'core/cmdb') as $sCategory)
|
||||
{
|
||||
foreach (MetaModel::GetClasses($sCategory) as $sClass)
|
||||
{
|
||||
foreach (self::$m_aActionCodes as $iActionCode => $sAction)
|
||||
{
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = $iUserId"));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
{
|
||||
// Create a new entry
|
||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassGrant");
|
||||
$oMyClassGrant->Set("userid", $iUserId);
|
||||
$oMyClassGrant->Set("class", $sClass);
|
||||
$oMyClassGrant->Set("action", $sAction);
|
||||
$oMyClassGrant->Set("permission", "yes");
|
||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
||||
{
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = $iUserId"));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
{
|
||||
// Create a new entry
|
||||
$oMyClassGrant = MetaModel::NewObject("UserRightsMatrixClassStimulusGrant");
|
||||
$oMyClassGrant->Set("userid", $iUserId);
|
||||
$oMyClassGrant->Set("class", $sClass);
|
||||
$oMyClassGrant->Set("stimulus", $sStimulusCode);
|
||||
$oMyClassGrant->Set("permission", "yes");
|
||||
$iId = $oMyClassGrant->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
foreach (MetaModel::GetAttributesList($sClass) as $sAttCode)
|
||||
{
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND userid = $iUserId"));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
{
|
||||
foreach (array('read', 'modify') as $sAction)
|
||||
{
|
||||
// Create a new entry
|
||||
$oMyAttGrant = MetaModel::NewObject("UserRightsMatrixAttributeGrant");
|
||||
$oMyAttGrant->Set("userid", $iUserId);
|
||||
$oMyAttGrant->Set("class", $sClass);
|
||||
$oMyAttGrant->Set("attcode", $sAttCode);
|
||||
$oMyAttGrant->Set("action", $sAction);
|
||||
$oMyAttGrant->Set("permission", "yes");
|
||||
$iId = $oMyAttGrant->DBInsertNoReload();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Create the "My Bookmarks" menu item (parent_id = 0, rank = 6)
|
||||
if ($bNewUser)
|
||||
{
|
||||
$bAddMenu = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT menuNode WHERE type = 'user' AND parent_id = 0 AND user_id = $iUserId"));
|
||||
$bAddMenu = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddMenu)
|
||||
{
|
||||
$oMenu = MetaModel::NewObject('menuNode');
|
||||
$oMenu->Set('type', 'user');
|
||||
$oMenu->Set('parent_id', 0); // It's a toplevel entry
|
||||
$oMenu->Set('rank', 6); // Located just above the Admin Tools section (=7)
|
||||
$oMenu->Set('name', 'My Bookmarks');
|
||||
$oMenu->Set('label', 'My Favorite Items');
|
||||
$oMenu->Set('hyperlink', 'UI.php');
|
||||
$oMenu->Set('template', '<p></p><p></p><p style="text-align:center; font-family:Georgia, Times, serif; font-size:32px;">My bookmarks</p><p style="text-align:center; font-family:Georgia, Times, serif; font-size:14px;"><i>This section contains my most favorite search results</i></p>');
|
||||
$oMenu->Set('user_id', $iUserId);
|
||||
$oMenu->DBInsert();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public function Init()
|
||||
{
|
||||
// Could be loaded in a shared memory (?)
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassGrant WHERE class = '$sClass' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixAttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND action = '$sAction' AND userid = '{$oUser->GetKey()}'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixClassStimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND userid = '{$oUser->GetKey()}'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function FlushPrivileges()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
UserRights::SelectModule('UserRightsMatrix');
|
||||
|
||||
?>
|
||||
78
addons/userrights/userrightsnull.class.inc.php
Normal file
78
addons/userrights/userrightsnull.class.inc.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2023 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/>
|
||||
|
||||
/**
|
||||
* UserRightsNull
|
||||
* User management Module - say Yeah! to everything
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
class UserRightsNull extends UserRightsAddOnAPI
|
||||
{
|
||||
// Installation: create the very first user
|
||||
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsAdministrator($oUser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IsPortalUser($oUser)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function FlushPrivileges()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
UserRights::SelectModule('UserRightsNull');
|
||||
|
||||
?>
|
||||
@@ -1,11 +1,9 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
define('ADMIN_PROFILE_NAME', 'Administrator');
|
||||
define('PORTAL_PROFILE_NAME', 'Portal user');
|
||||
|
||||
@@ -825,37 +823,48 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
{
|
||||
// We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading
|
||||
// We have to answer NO for objects shared for reading purposes
|
||||
if (self::HasSharing() && SharedObject::GetSharedClassProperties($sClass)) {
|
||||
// This class is shared, GetSelectFilter may allow some objects for read only
|
||||
// But currently we are checking whether the objects might be written...
|
||||
// Let's exclude the objects based on the relevant criteria
|
||||
if (self::HasSharing())
|
||||
{
|
||||
$aClassProps = SharedObject::GetSharedClassProperties($sClass);
|
||||
if ($aClassProps)
|
||||
{
|
||||
// This class is shared, GetSelectFilter may allow some objects for read only
|
||||
// But currently we are checking wether the objects might be written...
|
||||
// Let's exclude the objects based on the relevant criteria
|
||||
|
||||
// Use $oInstanceSet only if sClass is the main class
|
||||
if (!is_a($oInstanceSet->GetClass(), $sClass, true)) {
|
||||
/** @var \DBObjectSet $oInstanceSet */
|
||||
throw new CoreException(__FUNCTION__.': Expecting object set to be of class '.$sClass.' but it is of class '.$oInstanceSet->GetClass(), ['OQL_Query' => $oInstanceSet->GetFilter()->ToOQL(), 'classes' => $oInstanceSet->GetSelectedClasses()]);
|
||||
}
|
||||
$sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
||||
if (!is_null($sOrgAttCode)) {
|
||||
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
||||
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) {
|
||||
$iCountNO = 0;
|
||||
$iCountYES = 0;
|
||||
$oInstanceSet->Rewind();
|
||||
while ($oObject = $oInstanceSet->Fetch()) {
|
||||
$iOrg = $oObject->Get($sOrgAttCode);
|
||||
if (in_array($iOrg, $aUserOrgs)) {
|
||||
$iCountYES++;
|
||||
} else {
|
||||
$iCountNO++;
|
||||
$sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass);
|
||||
if (!is_null($sOrgAttCode))
|
||||
{
|
||||
$aUserOrgs = $this->GetUserOrgs($oUser, $sClass);
|
||||
if (!is_null($aUserOrgs) && count($aUserOrgs) > 0)
|
||||
{
|
||||
$iCountNO = 0;
|
||||
$iCountYES = 0;
|
||||
$oInstanceSet->Rewind();
|
||||
while($oObject = $oInstanceSet->Fetch())
|
||||
{
|
||||
$iOrg = $oObject->Get($sOrgAttCode);
|
||||
if (in_array($iOrg, $aUserOrgs))
|
||||
{
|
||||
$iCountYES++;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCountNO++;
|
||||
}
|
||||
}
|
||||
if ($iCountNO == 0)
|
||||
{
|
||||
$iPermission = UR_ALLOWED_YES;
|
||||
}
|
||||
elseif ($iCountYES == 0)
|
||||
{
|
||||
$iPermission = UR_ALLOWED_NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iPermission = UR_ALLOWED_DEPENDS;
|
||||
}
|
||||
}
|
||||
if ($iCountNO == 0) {
|
||||
$iPermission = UR_ALLOWED_YES;
|
||||
} elseif ($iCountYES == 0) {
|
||||
$iPermission = UR_ALLOWED_NO;
|
||||
} else {
|
||||
$iPermission = UR_ALLOWED_DEPENDS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -924,9 +933,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @return string|null Find out which attribute is corresponding the dimension 'owner org'
|
||||
* returns null if no such attribute has been found (no filtering should occur)
|
||||
* Find out which attribute is corresponding the the dimension 'owner org'
|
||||
* returns null if no such attribute has been found (no filtering should occur)
|
||||
*/
|
||||
public static function GetOwnerOrganizationAttCode($sClass)
|
||||
{
|
||||
@@ -971,3 +979,4 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
|
||||
UserRights::SelectModule('UserRightsProfile');
|
||||
|
||||
?>
|
||||
|
||||
1057
addons/userrights/userrightsprofile.db.class.inc.php
Normal file
1057
addons/userrights/userrightsprofile.db.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
1215
addons/userrights/userrightsprojection.class.inc.php
Normal file
1215
addons/userrights/userrightsprojection.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
29
app.php
29
app.php
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Kernel;
|
||||
|
||||
require_once __DIR__.'/lib/autoload_runtime.php';
|
||||
|
||||
require_once('approot.inc.php');
|
||||
require_once('application/startup.inc.php');
|
||||
|
||||
return function (array $context) {
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
331
application/Html2Text.php
Normal file
331
application/Html2Text.php
Normal file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
namespace Html2Text;
|
||||
|
||||
if (!function_exists('mb_split'))
|
||||
{
|
||||
function mb_split($pattern, $subject, $limit = -1)
|
||||
{
|
||||
return preg_split('/'.$pattern.'/', $subject, $limit);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Replace all occurrences of the search string with the replacement string.
|
||||
*
|
||||
* @author Sean Murphy <sean@iamseanmurphy.com>
|
||||
* @copyright Copyright 2012 Sean Murphy. All rights reserved.
|
||||
* @license http://creativecommons.org/publicdomain/zero/1.0/
|
||||
* @link http://php.net/manual/function.str-replace.php
|
||||
*
|
||||
* @param mixed $search
|
||||
* @param mixed $replace
|
||||
* @param mixed $subject
|
||||
* @param int $count
|
||||
* @return mixed
|
||||
*/
|
||||
function mb_str_replace($search, $replace, $subject, &$count = 0) {
|
||||
if (!is_array($subject)) {
|
||||
// Normalize $search and $replace so they are both arrays of the same length
|
||||
$searches = is_array($search) ? array_values($search) : array($search);
|
||||
$replacements = is_array($replace) ? array_values($replace) : array($replace);
|
||||
$replacements = array_pad($replacements, count($searches), '');
|
||||
foreach ($searches as $key => $search) {
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
if (is_array($parts))
|
||||
{
|
||||
$count += count($parts) - 1;
|
||||
$subject = implode($replacements[$key], $parts);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Call mb_str_replace for each subject in array, recursively
|
||||
foreach ($subject as $key => $value) {
|
||||
$subject[$key] = mb_str_replace($search, $replace, $value, $count);
|
||||
}
|
||||
}
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2010 Jevon Wright and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* or
|
||||
*
|
||||
* LGPL which is available at http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
* Jevon Wright - initial API and implementation
|
||||
* Denis Flaven - some fixes for properly handling UTF-8 characters
|
||||
****************************************************************************/
|
||||
|
||||
class Html2Text {
|
||||
|
||||
/**
|
||||
* Tries to convert the given HTML into a plain text format - best suited for
|
||||
* e-mail display, etc.
|
||||
*
|
||||
* <p>In particular, it tries to maintain the following features:
|
||||
* <ul>
|
||||
* <li>Links are maintained, with the 'href' copied over
|
||||
* <li>Information in the <head> is lost
|
||||
* </ul>
|
||||
*
|
||||
* @param string html the input HTML
|
||||
* @return string the HTML converted, as best as possible, to text
|
||||
* @throws Html2TextException if the HTML could not be loaded as a {@link DOMDocument}
|
||||
*/
|
||||
static function convert($html) {
|
||||
// replace with spaces
|
||||
|
||||
$html = str_replace(" ", " ", $html);
|
||||
$html = mb_str_replace("\xc2\xa0", " ", $html); // DO NOT USE str_replace since it breaks the "à" character which is \xc3 \xa0 in UTF-8
|
||||
|
||||
$html = static::fixNewlines($html);
|
||||
|
||||
$doc = new \DOMDocument();
|
||||
if (!@$doc->loadHTML('<?xml encoding="UTF-8">'.$html)) // Forces the UTF-8 character set for HTML fragments
|
||||
{
|
||||
throw new Html2TextException("Could not load HTML - badly formed?", $html);
|
||||
}
|
||||
|
||||
$output = static::iterateOverNode($doc);
|
||||
|
||||
// remove leading and trailing spaces on each line
|
||||
$output = preg_replace("/[ \t]*\n[ \t]*/im", "\n", $output);
|
||||
$output = preg_replace("/ *\t */im", "\t", $output);
|
||||
|
||||
// remove unnecessary empty lines
|
||||
$output = preg_replace("/\n\n\n*/im", "\n\n", $output);
|
||||
|
||||
// remove leading and trailing whitespace
|
||||
$output = trim($output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unify newlines; in particular, \r\n becomes \n, and
|
||||
* then \r becomes \n. This means that all newlines (Unix, Windows, Mac)
|
||||
* all become \ns.
|
||||
*
|
||||
* @param string text text with any number of \r, \r\n and \n combinations
|
||||
* @return string the fixed text
|
||||
*/
|
||||
static function fixNewlines($text) {
|
||||
// replace \r\n to \n
|
||||
$text = str_replace("\r\n", "\n", $text);
|
||||
// remove \rs
|
||||
$text = str_replace("\r", "\n", $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
static function nextChildName($node) {
|
||||
// get the next child
|
||||
$nextNode = $node->nextSibling;
|
||||
while ($nextNode != null) {
|
||||
if ($nextNode instanceof \DOMElement) {
|
||||
break;
|
||||
}
|
||||
$nextNode = $nextNode->nextSibling;
|
||||
}
|
||||
$nextName = null;
|
||||
if ($nextNode instanceof \DOMElement && $nextNode != null) {
|
||||
$nextName = strtolower($nextNode->nodeName);
|
||||
}
|
||||
|
||||
return $nextName;
|
||||
}
|
||||
|
||||
static function prevChildName($node) {
|
||||
// get the previous child
|
||||
$nextNode = $node->previousSibling;
|
||||
while ($nextNode != null) {
|
||||
if ($nextNode instanceof \DOMElement) {
|
||||
break;
|
||||
}
|
||||
$nextNode = $nextNode->previousSibling;
|
||||
}
|
||||
$nextName = null;
|
||||
if ($nextNode instanceof \DOMElement && $nextNode != null) {
|
||||
$nextName = strtolower($nextNode->nodeName);
|
||||
}
|
||||
|
||||
return $nextName;
|
||||
}
|
||||
|
||||
static function iterateOverNode($node) {
|
||||
if ($node instanceof \DOMText) {
|
||||
// Replace whitespace characters with a space (equivilant to \s)
|
||||
return preg_replace("/[\\t\\n\\f\\r ]+/im", " ", $node->wholeText);
|
||||
}
|
||||
if ($node instanceof \DOMDocumentType) {
|
||||
// ignore
|
||||
return "";
|
||||
}
|
||||
|
||||
$nextName = static::nextChildName($node);
|
||||
$prevName = static::prevChildName($node);
|
||||
|
||||
$name = strtolower($node->nodeName);
|
||||
|
||||
// start whitespace
|
||||
switch ($name) {
|
||||
case "hr":
|
||||
return "---------------------------------------------------------------\n";
|
||||
|
||||
case "style":
|
||||
case "head":
|
||||
case "title":
|
||||
case "meta":
|
||||
case "script":
|
||||
// ignore these tags
|
||||
return "";
|
||||
|
||||
case "h1":
|
||||
case "h2":
|
||||
case "h3":
|
||||
case "h4":
|
||||
case "h5":
|
||||
case "h6":
|
||||
case "ol":
|
||||
case "ul":
|
||||
// add two newlines, second line is added below
|
||||
$output = "\n";
|
||||
break;
|
||||
|
||||
case "td":
|
||||
case "th":
|
||||
// add tab char to separate table fields
|
||||
$output = "\t";
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
case "p":
|
||||
case "div":
|
||||
// add one line
|
||||
$output = "\n";
|
||||
break;
|
||||
|
||||
case "li":
|
||||
$output = "- ";
|
||||
break;
|
||||
|
||||
default:
|
||||
// print out contents of unknown tags
|
||||
$output = "";
|
||||
break;
|
||||
}
|
||||
|
||||
// debug
|
||||
//$output .= "[$name,$nextName]";
|
||||
|
||||
if (isset($node->childNodes)) {
|
||||
for ($i = 0; $i < $node->childNodes->length; $i++) {
|
||||
$n = $node->childNodes->item($i);
|
||||
|
||||
$text = static::iterateOverNode($n);
|
||||
|
||||
$output .= $text;
|
||||
}
|
||||
}
|
||||
|
||||
// end whitespace
|
||||
switch ($name) {
|
||||
case "h1":
|
||||
case "h2":
|
||||
case "h3":
|
||||
case "h4":
|
||||
case "h5":
|
||||
case "h6":
|
||||
$output .= "\n";
|
||||
break;
|
||||
|
||||
case "p":
|
||||
case "br":
|
||||
// add one line
|
||||
if ($nextName != "div")
|
||||
$output .= "\n";
|
||||
break;
|
||||
|
||||
case "div":
|
||||
// add one line only if the next child isn't a div
|
||||
if ($nextName != "div" && $nextName != null)
|
||||
$output .= "\n";
|
||||
break;
|
||||
|
||||
case "a":
|
||||
// links are returned in [text](link) format
|
||||
$href = $node->getAttribute("href");
|
||||
|
||||
$output = trim($output);
|
||||
|
||||
// remove double [[ ]] s from linking images
|
||||
if (substr($output, 0, 1) == "[" && substr($output, -1) == "]") {
|
||||
$output = substr($output, 1, strlen($output) - 2);
|
||||
|
||||
// for linking images, the title of the <a> overrides the title of the <img>
|
||||
if ($node->getAttribute("title")) {
|
||||
$output = $node->getAttribute("title");
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no link text, but a title attr
|
||||
if (!$output && $node->getAttribute("title")) {
|
||||
$output = $node->getAttribute("title");
|
||||
}
|
||||
|
||||
if ($href == null) {
|
||||
// it doesn't link anywhere
|
||||
if ($node->getAttribute("name") != null) {
|
||||
$output = "[$output]";
|
||||
}
|
||||
} else {
|
||||
if ($href == $output || $href == "mailto:$output" || $href == "http://$output" || $href == "https://$output") {
|
||||
// link to the same address: just use link
|
||||
$output;
|
||||
} else {
|
||||
// replace it
|
||||
if ($output) {
|
||||
$output = "[$output]($href)";
|
||||
} else {
|
||||
// empty string
|
||||
$output = $href;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// does the next node require additional whitespace?
|
||||
switch ($nextName) {
|
||||
case "h1": case "h2": case "h3": case "h4": case "h5": case "h6":
|
||||
$output .= "\n";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case "img":
|
||||
if ($node->getAttribute("title")) {
|
||||
$output = "[" . $node->getAttribute("title") . "]";
|
||||
} elseif ($node->getAttribute("alt")) {
|
||||
$output = "[" . $node->getAttribute("alt") . "]";
|
||||
} else {
|
||||
$output = "";
|
||||
}
|
||||
break;
|
||||
|
||||
case "li":
|
||||
$output .= "\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
28
application/Html2TextException.php
Normal file
28
application/Html2TextException.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2010 Jevon Wright and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* or
|
||||
*
|
||||
* LGPL which is available at http://www.gnu.org/licenses/lgpl.html
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
* Jevon Wright - initial API and implementation
|
||||
****************************************************************************/
|
||||
|
||||
namespace Html2Text;
|
||||
|
||||
class Html2TextException extends \Exception {
|
||||
var $more_info;
|
||||
|
||||
public function __construct($message = "", $more_info = "") {
|
||||
parent::__construct($message);
|
||||
$this->more_info = $more_info;
|
||||
}
|
||||
}
|
||||
24
application/ajaxwebpage.class.inc.php
Normal file
24
application/ajaxwebpage.class.inc.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
// cannot notify depreciation for now as this is still load in autoloader
|
||||
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader');
|
||||
|
||||
/**
|
||||
* Class ajax_page
|
||||
*
|
||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to AjaxPage
|
||||
*/
|
||||
class ajax_page extends AjaxPage
|
||||
{
|
||||
function __construct($s_title)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('ajax_page is deprecated. Please use AjaxPage instead');
|
||||
parent::__construct($s_title);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -20,7 +20,7 @@
|
||||
/**
|
||||
* Class ApplicationContext
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -195,31 +195,16 @@ class ApplicationContext
|
||||
/**
|
||||
* Returns the context as string with the format name1=value1&name2=value2....
|
||||
* @return string The context as a string to be appended to an href property
|
||||
*
|
||||
*/
|
||||
public function GetForLink(bool $bWithLeadingAmpersand = false)
|
||||
public function GetForLink()
|
||||
{
|
||||
// If there are no parameters, return an empty string
|
||||
if(empty($this->aValues)){
|
||||
return '';
|
||||
}
|
||||
|
||||
// Build the query string with ampersand separated parameters
|
||||
$aParams = array();
|
||||
foreach($this->aValues as $sName => $sValue)
|
||||
{
|
||||
$aParams[] = "c[$sName]".'='.urlencode($sValue);
|
||||
}
|
||||
$sReturnValue = implode('&', $aParams);
|
||||
|
||||
// add the leading ampersand if requested
|
||||
if($bWithLeadingAmpersand){
|
||||
$sReturnValue = '&' . $sReturnValue;
|
||||
}
|
||||
|
||||
return $sReturnValue;
|
||||
return implode("&", $aParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0 N°2534 - dashboard: bug with autorefresh that deactivates filtering on organisation
|
||||
* Returns the params as c[menu]:..., c[org_id]:....
|
||||
@@ -397,7 +382,7 @@ class ApplicationContext
|
||||
$sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
|
||||
if (utils::StrLen($sUrl) > 0) {
|
||||
if ($bWithNavigationContext) {
|
||||
return $sUrl.$oAppContext->GetForLink(true);
|
||||
return $sUrl."&".$oAppContext->GetForLink();
|
||||
} else {
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
|
||||
* @package ORMExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnIsModified($oObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnCheckToWrite($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnCheckToDelete($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDBUpdate($oObject, $oChange = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDBInsert($oObject, $oChange = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDBDelete($oObject, $oChange = null)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDisplayProperties($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnDisplayRelations($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnFormSubmit($oObject, $sFormPrefix = '')
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function OnFormCancel($sTempId)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function EnumUsedAttributes($oObject)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetIcon($oObject)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetHilightClass($oObject)
|
||||
{
|
||||
return HILIGHT_CLASS_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function EnumAllowedActions(DBObjectSet $oSet)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of iPageUIBlockExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package UIBlockExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetBannerBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetHeaderBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetFooterBlock()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package PreferencesExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractPreferencesExtension implements iPreferencesExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function DisplayPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function ApplyPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage, $sOperation)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Inherit from this class to provide messages to be displayed in the "Welcome Popup"
|
||||
*
|
||||
* @api
|
||||
* @since 3.2.0
|
||||
*/
|
||||
abstract class AbstractWelcomePopupExtension implements iWelcomePopupExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetIconRelPath(): string
|
||||
{
|
||||
return \Combodo\iTop\Application\Branding::$aLogoPaths[\Combodo\iTop\Application\Branding::ENUM_LOGO_TYPE_MAIN_LOGO_COMPACT]['default'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetMessages(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function AcknowledgeMessage(string $sMessageId): void
|
||||
{
|
||||
// No need to process the acknowledgment notice by default
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Base class for the various types of custom menus
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class ApplicationPopupMenuItem
|
||||
{
|
||||
/** @ignore */
|
||||
protected $sUID;
|
||||
/** @ignore */
|
||||
protected $sLabel;
|
||||
/** @ignore */
|
||||
protected $sTooltip;
|
||||
/** @ignore */
|
||||
protected $sIconClass;
|
||||
/** @ignore */
|
||||
protected $aCssClasses;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @api
|
||||
*/
|
||||
public function __construct($sUID, $sLabel)
|
||||
{
|
||||
$this->sUID = $sUID;
|
||||
$this->sLabel = $sLabel;
|
||||
$this->sTooltip = '';
|
||||
$this->sIconClass = '';
|
||||
$this->aCssClasses = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UID
|
||||
*
|
||||
* @return string The unique identifier
|
||||
* @ignore
|
||||
*/
|
||||
public function GetUID()
|
||||
{
|
||||
return $this->sUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label
|
||||
*
|
||||
* @return string The label
|
||||
* @ignore
|
||||
*/
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->sLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CSS classes
|
||||
*
|
||||
* @return array
|
||||
* @ignore
|
||||
*/
|
||||
public function GetCssClasses()
|
||||
{
|
||||
return $this->aCssClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aCssClasses
|
||||
* @api
|
||||
*/
|
||||
public function SetCssClasses($aCssClasses)
|
||||
{
|
||||
$this->aCssClasses = $aCssClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a CSS class to the CSS classes that will be put on the menu item
|
||||
*
|
||||
* @param $sCssClass
|
||||
* @api
|
||||
*/
|
||||
public function AddCssClass($sCssClass)
|
||||
{
|
||||
$this->aCssClasses[] = $sCssClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $sTooltip
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function SetTooltip($sTooltip)
|
||||
{
|
||||
$this->sTooltip = $sTooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function GetTooltip()
|
||||
{
|
||||
return $this->sTooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sIconClass
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function SetIconClass($sIconClass)
|
||||
{
|
||||
$this->sIconClass = $sIconClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @api
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function GetIconClass()
|
||||
{
|
||||
return $this->sIconClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the components to create a popup menu item in HTML
|
||||
*
|
||||
* @return array A hash array: array('label' => , 'url' => , 'target' => , 'onclick' => )
|
||||
* @ignore
|
||||
*/
|
||||
abstract public function GetMenuItem();
|
||||
|
||||
/** @ignore */
|
||||
public function GetLinkedScripts()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item as a button that runs some JS code
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class JSButtonItem extends JSPopupMenuItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item into a popup menu that triggers some Javascript code
|
||||
*
|
||||
* Note: This works only in the backoffice, {@see \JSButtonItem} for the end-user portal
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class JSPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
/** @ignore */
|
||||
protected $sJsCode;
|
||||
/** @ignore */
|
||||
protected $sUrl;
|
||||
/** @ignore */
|
||||
protected $aIncludeJSFiles;
|
||||
|
||||
/**
|
||||
* Class for adding an item that triggers some Javascript code
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sJSCode In case the menu consists in executing some havascript code inside the page, pass it here. If supplied $sURL
|
||||
* ans $sTarget will be ignored
|
||||
* @param array $aIncludeJSFiles An array of file URLs to be included (once) to provide some JS libraries for the page.
|
||||
* @api
|
||||
*/
|
||||
public function __construct($sUID, $sLabel, $sJSCode, $aIncludeJSFiles = array())
|
||||
{
|
||||
parent::__construct($sUID, $sLabel);
|
||||
$this->sJsCode = $sJSCode;
|
||||
$this->sUrl = '#';
|
||||
$this->aIncludeJSFiles = $aIncludeJSFiles;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
// Note: the semicolumn is a must here!
|
||||
return array(
|
||||
'label' => $this->GetLabel(),
|
||||
'onclick' => $this->GetJsCode() . '; return false;',
|
||||
'url' => $this->GetUrl(),
|
||||
'css_classes' => $this->GetCssClasses(),
|
||||
'icon_class' => $this->sIconClass,
|
||||
'tooltip' => $this->sTooltip
|
||||
);
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetLinkedScripts()
|
||||
{
|
||||
return $this->aIncludeJSFiles;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetJsCode()
|
||||
{
|
||||
return $this->sJsCode;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetUrl()
|
||||
{
|
||||
return $this->sUrl;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding a separator (horizontal line, not selectable) the output
|
||||
* will automatically reduce several consecutive separators to just one
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class SeparatorPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
static $idx = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @api
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('_separator_' . (self::$idx++), '');
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array('label' => '<hr class="menu-separator">', 'url' => '', 'css_classes' => $this->aCssClasses);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item as a button that browses to the given URL
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class URLButtonItem extends URLPopupMenuItem
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for adding an item into a popup menu that browses to the given URL
|
||||
*
|
||||
* Note: This works only in the backoffice, {@see \URLButtonItem} for the end-user portal
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
class URLPopupMenuItem extends ApplicationPopupMenuItem
|
||||
{
|
||||
/** @ignore */
|
||||
protected $sUrl;
|
||||
/** @ignore */
|
||||
protected $sTarget;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
|
||||
* @param string $sLabel The display label of the menu (must be localized)
|
||||
* @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here
|
||||
* @param string $sTarget In case the menu is an hyperlink and a specific target is needed (_blank for example), pass it here
|
||||
* @api
|
||||
*/
|
||||
public function __construct($sUID, $sLabel, $sUrl, $sTarget = '_top')
|
||||
{
|
||||
parent::__construct($sUID, $sLabel);
|
||||
$this->sUrl = $sUrl;
|
||||
$this->sTarget = $sTarget;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetMenuItem()
|
||||
{
|
||||
return array('label' => $this->GetLabel(),
|
||||
'url' => $this->GetUrl(),
|
||||
'target' => $this->GetTarget(),
|
||||
'css_classes' => $this->aCssClasses,
|
||||
'icon_class' => $this->sIconClass,
|
||||
'tooltip' => $this->sTooltip
|
||||
);
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetUrl()
|
||||
{
|
||||
return $this->sUrl;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
public function GetTarget()
|
||||
{
|
||||
return $this->sTarget;
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to perform specific operations when objects are manipulated
|
||||
*
|
||||
* Note that those methods will be called when objects are manipulated, either in a programmatic way
|
||||
* or through the GUI.
|
||||
*
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method. More details on each method PHPDoc.
|
||||
* @package ORMExtensibilityAPI
|
||||
*/
|
||||
interface iApplicationObjectExtension
|
||||
{
|
||||
/**
|
||||
* Invoked to determine whether an object has been modified in memory
|
||||
*
|
||||
* The GUI calls this verb to determine the message that will be displayed to the end-user.
|
||||
* Anyhow, this API can be called in other contexts such as the CSV import tool.
|
||||
*
|
||||
* If the extension returns false, then the framework will perform the usual evaluation.
|
||||
* Otherwise, the answer is definitively "yes, the object has changed".
|
||||
*
|
||||
* @param /cmdbAbstractObject $oObject The target object
|
||||
*
|
||||
* @return boolean True if something has changed for the target object
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 No alternative available, this API was unstable and is abandoned
|
||||
*/
|
||||
public function OnIsModified($oObject);
|
||||
|
||||
/**
|
||||
* Invoked to determine whether an object can be written to the database
|
||||
*
|
||||
* The GUI calls this verb and reports any issue.
|
||||
* Anyhow, this API can be called in other contexts such as the CSV import tool.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
*
|
||||
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_WRITE event instead
|
||||
*/
|
||||
public function OnCheckToWrite($oObject);
|
||||
|
||||
/**
|
||||
* Invoked to determine wether an object can be deleted from the database
|
||||
*
|
||||
* The GUI calls this verb and stops the deletion process if any issue is reported.
|
||||
*
|
||||
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
*
|
||||
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
|
||||
* @api
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_DELETE event instead
|
||||
*/
|
||||
public function OnCheckToDelete($oObject);
|
||||
|
||||
/**
|
||||
* Invoked when an object is updated into the database. The method is called right <b>after</b> the object has been written to the
|
||||
* database.
|
||||
*
|
||||
* Useful methods you can call on $oObject :
|
||||
*
|
||||
* * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change
|
||||
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
|
||||
* once for all the changes made within the current page
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
|
||||
* @api
|
||||
* @since 2.7.0 N°2293 can access object changes by calling {@see DBObject::ListPreviousValuesForUpdatedAttributes()} on $oObject
|
||||
*/
|
||||
public function OnDBUpdate($oObject, $oChange = null);
|
||||
|
||||
/**
|
||||
* Invoked when an object is created into the database
|
||||
*
|
||||
* The method is called right <b>after</b> the object has been written to the database.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
|
||||
* once for all the changes made within the current page
|
||||
*
|
||||
* @return void
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
|
||||
* @api
|
||||
*/
|
||||
public function OnDBInsert($oObject, $oChange = null);
|
||||
|
||||
/**
|
||||
* Invoked when an object is deleted from the database
|
||||
*
|
||||
* The method is called right <b>before</b> the object will be deleted from the database.
|
||||
*
|
||||
* @param \cmdbAbstractObject $oObject The target object
|
||||
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
|
||||
* once for all the changes made within the current page
|
||||
*
|
||||
* @return void
|
||||
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_DELETE event instead
|
||||
* @api
|
||||
*/
|
||||
public function OnDBDelete($oObject, $oChange = null);
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to change the behavior of the GUI for some objects.
|
||||
*
|
||||
* All methods are invoked by iTop for a given object. There are basically two usages:
|
||||
*
|
||||
* 1) To tweak the form of an object, you will have to implement a specific behavior within:
|
||||
*
|
||||
* * OnDisplayProperties (bEditMode = true)
|
||||
* * OnFormSubmit
|
||||
* * OnFormCancel
|
||||
*
|
||||
* 2) To tune the display of the object details, you can use:
|
||||
*
|
||||
* * OnDisplayProperties
|
||||
* * OnDisplayRelations
|
||||
* * GetIcon
|
||||
* * GetHilightClass
|
||||
*
|
||||
* Please note that some of the APIs can be called several times for a single page displayed.
|
||||
* Therefore it is not recommended to perform too many operations, such as querying the database.
|
||||
* A recommended pattern is to cache data by the mean of static members.
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
*/
|
||||
interface iApplicationUIExtension
|
||||
{
|
||||
/**
|
||||
* Invoked when an object is being displayed (wiew or edit)
|
||||
*
|
||||
* The method is called right after the main tab has been displayed.
|
||||
* You can add output to the page, either to change the display, or to add a form input
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* if ($bEditMode)
|
||||
* {
|
||||
* $oPage->p('Age of the captain: <input type="text" name="captain_age"/>');
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* $oPage->p('Age of the captain: '.$iCaptainAge);
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* @api
|
||||
*
|
||||
*@param \Combodo\iTop\Application\WebPage\WebPage $oPage The output context
|
||||
* @param boolean $bEditMode True if the edition form is being displayed
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function OnDisplayProperties($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false);
|
||||
|
||||
/**
|
||||
* Invoked when an object is being displayed (wiew or edit)
|
||||
*
|
||||
* The method is called rigth after all the tabs have been displayed
|
||||
*
|
||||
* @api
|
||||
*
|
||||
*@param \Combodo\iTop\Application\WebPage\WebPage $oPage The output context
|
||||
* @param boolean $bEditMode True if the edition form is being displayed
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function OnDisplayRelations($oObject, \Combodo\iTop\Application\WebPage\WebPage $oPage, $bEditMode = false);
|
||||
|
||||
/**
|
||||
* Invoked when the end-user clicks on Modify from the object edition form
|
||||
*
|
||||
* The method is called after the changes from the standard form have been
|
||||
* taken into account, and before saving the changes into the database.
|
||||
*
|
||||
* @param DBObject $oObject The object being edited
|
||||
* @param string $sFormPrefix Prefix given to the HTML form inputs
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function OnFormSubmit($oObject, $sFormPrefix = '');
|
||||
|
||||
/**
|
||||
* Invoked when the end-user clicks on Cancel from the object edition form
|
||||
*
|
||||
* Implement here any cleanup. This is necessary when you have injected some
|
||||
* javascript into the edition form, and if that code requires to store temporary data
|
||||
* (this is the case when a file must be uploaded).
|
||||
*
|
||||
* @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function OnFormCancel($sTempId);
|
||||
|
||||
/**
|
||||
* Not yet called by the framework!
|
||||
*
|
||||
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return string[] desc
|
||||
* @api
|
||||
*/
|
||||
public function EnumUsedAttributes($oObject); // Not yet implemented
|
||||
|
||||
/**
|
||||
* Not yet called by the framework!
|
||||
*
|
||||
* Sorry, the verb has been reserved. You must implement it, but it is not called as of now.
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return string Path of the icon, relative to the modules directory.
|
||||
* @api
|
||||
*/
|
||||
public function GetIcon($oObject); // Not yet implemented
|
||||
|
||||
/**
|
||||
* Invoked when the object is displayed alone or within a list
|
||||
*
|
||||
* Returns a value influencing the appearance of the object depending on its
|
||||
* state.
|
||||
*
|
||||
* Possible values are:
|
||||
*
|
||||
* * HILIGHT_CLASS_CRITICAL
|
||||
* * HILIGHT_CLASS_WARNING
|
||||
* * HILIGHT_CLASS_OK
|
||||
* * HILIGHT_CLASS_NONE
|
||||
*
|
||||
* @param DBObject $oObject The object being displayed
|
||||
*
|
||||
* @return integer The value representing the mood of the object
|
||||
* @api
|
||||
*/
|
||||
public function GetHilightClass($oObject);
|
||||
|
||||
/**
|
||||
* Called when building the Actions menu for a single object or a list of objects
|
||||
*
|
||||
* Use this to add items to the Actions menu. You will have to specify a label and an URL.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $oObject = $oSet->fetch();
|
||||
* if ($oObject instanceof Sheep)
|
||||
* {
|
||||
* return array('View in my app' => 'http://myserver/view_sheeps?id='.$oObject->Get('name'));
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* return array();
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* See also iPopupMenuExtension for greater flexibility
|
||||
*
|
||||
* @param DBObjectSet $oSet A set of persistent objects (DBObject)
|
||||
*
|
||||
* @return array
|
||||
* @api
|
||||
*/
|
||||
public function EnumAllowedActions(DBObjectSet $oSet);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add Dict entries
|
||||
*
|
||||
* @see \iTopWebPage::$a_dict_entries
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeDictEntriesExtension
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
* @see \iTopWebPage::a_dict_entries
|
||||
* @api
|
||||
*/
|
||||
public function GetDictEntries(): array;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add Dict entries prefixes
|
||||
*
|
||||
* @see \iTopWebPage::$a_dict_entries_prefixes
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeDictEntriesPrefixesExtension
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
* @see \iTopWebPage::a_dict_entries_prefixes
|
||||
* @api
|
||||
*/
|
||||
public function GetDictEntriesPrefixes(): array;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages' head.
|
||||
* Will be executed first, BEFORE the DOM interpretation.
|
||||
*
|
||||
* @see \iTopWebPage::$a_early_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeEarlyScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_early_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetEarlyScript(): string;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed right when the DOM is ready.
|
||||
*
|
||||
* @see \iTopWebPage::$a_init_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeInitScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_init_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetInitScript(): string;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add script (JS) files to the backoffice pages
|
||||
*
|
||||
* @see \iTopWebPage::$a_linked_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeLinkedScriptsExtension
|
||||
{
|
||||
/**
|
||||
* Each script will be included using this property
|
||||
* @return array An array of absolute URLs to the files to include
|
||||
* @see \iTopWebPage::$a_linked_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetLinkedScriptsAbsUrls(): array;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add stylesheets (CSS) to the backoffice pages
|
||||
*
|
||||
* @see \iTopWebPage::$a_linked_stylesheets
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeLinkedStylesheetsExtension
|
||||
{
|
||||
/**
|
||||
* @return array An array of absolute URLs to the files to include
|
||||
* @see \iTopWebPage::$a_linked_stylesheets
|
||||
* @api
|
||||
*/
|
||||
public function GetLinkedStylesheetsAbsUrls(): array;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed slightly AFTER the DOM is ready (just after the init. scripts).
|
||||
*
|
||||
* @see \iTopWebPage::$a_ready_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeReadyScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_ready_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetReadyScript(): string;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add sass file (SCSS) to the backoffice pages.
|
||||
* example: return "css/setup.scss"
|
||||
*
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.3.0
|
||||
*/
|
||||
interface iBackofficeSassExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_styles
|
||||
* @api
|
||||
*/
|
||||
public function GetSass(): string;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline script (JS) to the backoffice pages that will be executed immediately, without waiting for the DOM to be ready.
|
||||
*
|
||||
* @see \iTopWebPage::$a_scripts
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeScriptExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_scripts
|
||||
* @api
|
||||
*/
|
||||
public function GetScript(): string;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add inline style (CSS) to the backoffice pages' head.
|
||||
*
|
||||
* @see \iTopWebPage::$a_styles
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iBackofficeStyleExtension
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
* @see \iTopWebPage::$a_styles
|
||||
* @api
|
||||
*/
|
||||
public function GetStyle(): string;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to register a new field renderer mapping to either:
|
||||
* - Add the rendering of a new attribute type
|
||||
* - Overload the default rendering of an attribute type
|
||||
*
|
||||
* @since 3.1.0 N°6041
|
||||
*
|
||||
* @experimental Form / Field / Renderer should be used in more places in next iTop releases, which may introduce major API changes
|
||||
*/
|
||||
interface iFieldRendererMappingsExtension
|
||||
{
|
||||
/**
|
||||
* @return array {
|
||||
* array: {
|
||||
* field: string,
|
||||
* form_renderer: string,
|
||||
* field_renderer: string
|
||||
* }
|
||||
* } List of field renderer mapping: FQCN field class, FQCN Form Renderer class, FQCN Field Renderer class
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
|
||||
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Console\ConsoleFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
|
||||
* ['field' => 'FQCN\FieldA', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererA'],
|
||||
* ['field' => 'FQCN\FieldB', 'form_renderer' => 'Combodo\iTop\Renderer\Bootstrap\BsFormRenderer', 'field_renderer' => 'FQCN\FieldRendererB'],
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
public static function RegisterSupportedFields(): array;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add content to any iTopWebPage
|
||||
*
|
||||
* There are 3 places where content can be added:
|
||||
*
|
||||
* * The north pane: (normaly empty/hidden) at the top of the page, spanning the whole
|
||||
* width of the page
|
||||
* * The south pane: (normaly empty/hidden) at the bottom of the page, spanning the whole
|
||||
* width of the page
|
||||
* * The admin banner (two tones gray background) at the left of the global search.
|
||||
* Limited space, use it for short messages
|
||||
*
|
||||
* Each of the methods of this interface is supposed to return the HTML to be inserted at
|
||||
* the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions
|
||||
*
|
||||
* @api
|
||||
* @package BackofficeUIExtensibilityAPI
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface iPageUIBlockExtension
|
||||
{
|
||||
/**
|
||||
* Add content to the "admin banner"
|
||||
*
|
||||
* @api
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetBannerBlock();
|
||||
|
||||
/**
|
||||
* Add content to the header of the page
|
||||
*
|
||||
* @api
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetHeaderBlock();
|
||||
|
||||
/**
|
||||
* Add content to the footer of the page
|
||||
*
|
||||
* @api
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock|null The Block to add into the page
|
||||
*/
|
||||
public function GetFooterBlock();
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* New extension to add menu items in the "popup" menus inside iTop. Provides a greater flexibility than
|
||||
* iApplicationUIExtension::EnumAllowedActions.
|
||||
*
|
||||
* To add some menus into iTop, declare a class that implements this interface, it will be called automatically
|
||||
* by the application, as long as the class definition is included somewhere in the code
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.0
|
||||
*/
|
||||
interface iPopupMenuExtension
|
||||
{
|
||||
/**
|
||||
* Insert an item into the Actions menu of a list
|
||||
*
|
||||
* $param is a DBObjectSet containing the list of objects
|
||||
* @api
|
||||
*/
|
||||
const MENU_OBJLIST_ACTIONS = 1;
|
||||
/**
|
||||
* Insert an item into the Toolkit menu of a list
|
||||
*
|
||||
* $param is a DBObjectSet containing the list of objects
|
||||
* @api
|
||||
*/
|
||||
const MENU_OBJLIST_TOOLKIT = 2;
|
||||
/**
|
||||
* Insert an item into the Actions menu on an object details page
|
||||
*
|
||||
* $param is a DBObject instance: the object currently displayed
|
||||
* @api
|
||||
*/
|
||||
const MENU_OBJDETAILS_ACTIONS = 3;
|
||||
/**
|
||||
* Insert an item into the Dashboard menu
|
||||
*
|
||||
* The dashboad menu is shown on the top right corner when a dashboard
|
||||
* is being displayed.
|
||||
*
|
||||
* $param is a Dashboard instance: the dashboard currently displayed
|
||||
* @api
|
||||
*/
|
||||
const MENU_DASHBOARD_ACTIONS = 4;
|
||||
/**
|
||||
* Insert an item into the User menu (upper right corner)
|
||||
*
|
||||
* $param is null
|
||||
* @api
|
||||
*/
|
||||
const MENU_USER_ACTIONS = 5;
|
||||
/**
|
||||
* Insert an item into the Action menu on an object item in an objects list in the portal
|
||||
*
|
||||
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on
|
||||
* the current line)
|
||||
* @api
|
||||
*/
|
||||
const PORTAL_OBJLISTITEM_ACTIONS = 7;
|
||||
/**
|
||||
* Insert an item into the Action menu on an object details page in the portal
|
||||
*
|
||||
* $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object
|
||||
* currently displayed)
|
||||
* @api
|
||||
*/
|
||||
const PORTAL_OBJDETAILS_ACTIONS = 8;
|
||||
|
||||
/**
|
||||
* Insert an item into the Actions menu of a list in the portal
|
||||
* Note: This is not implemented yet !
|
||||
*
|
||||
* $param is an array('portal_id' => $sPortalId, 'object_set' => $oSet) containing DBObjectSet containing the list of objects
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
const PORTAL_OBJLIST_ACTIONS = 6;
|
||||
/**
|
||||
* Insert an item into the user menu of the portal
|
||||
* Note: This is not implemented yet !
|
||||
*
|
||||
* $param is the portal id
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
const PORTAL_USER_ACTIONS = 9;
|
||||
/**
|
||||
* Insert an item into the navigation menu of the portal
|
||||
* Note: This is not implemented yet !
|
||||
*
|
||||
* $param is the portal id
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
const PORTAL_MENU_ACTIONS = 10;
|
||||
|
||||
/**
|
||||
* Get the list of items to be added to a menu.
|
||||
*
|
||||
* This method is called by the framework for each menu.
|
||||
* The items will be inserted in the menu in the order of the returned array.
|
||||
*
|
||||
* @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx
|
||||
* @param mixed $param Depends on $iMenuId, see the constants defined above
|
||||
*
|
||||
* @return object[] An array of ApplicationPopupMenuItem or an empty array if no action is to be added to the menu
|
||||
* @api
|
||||
*/
|
||||
public static function EnumItems($iMenuId, $param);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package PreferencesExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iPreferencesExtension
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
*
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
|
||||
*
|
||||
*/
|
||||
public function DisplayPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage);
|
||||
|
||||
/**
|
||||
* @api
|
||||
*
|
||||
* @param string $sOperation
|
||||
*
|
||||
* @param \Combodo\iTop\Application\WebPage\WebPage $oPage
|
||||
*
|
||||
* @return bool true if the operation has been used
|
||||
*/
|
||||
public function ApplyPreferences(\Combodo\iTop\Application\WebPage\WebPage $oPage, $sOperation);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interface to provide messages to be displayed in the "Welcome Popup"
|
||||
*
|
||||
* @api
|
||||
* @since 3.2.0
|
||||
*/
|
||||
interface iWelcomePopupExtension
|
||||
{
|
||||
// Importance for ordering messages
|
||||
// Just two levels since less important messages have nothing to do in the welcome popup
|
||||
public const ENUM_IMPORTANCE_CRITICAL = 0;
|
||||
public const ENUM_IMPORTANCE_HIGH = 1;
|
||||
public const DEFAULT_IMPORTANCE = self::ENUM_IMPORTANCE_HIGH;
|
||||
|
||||
/**
|
||||
* Overload this method if you need to display an icon representing the provider (eg. your own company logo, module icon, ...)
|
||||
*
|
||||
* @return string Relative path (from app. root) of the icon representing the provider
|
||||
* @api
|
||||
*/
|
||||
public function GetIconRelPath(): string;
|
||||
|
||||
/**
|
||||
* @return \Combodo\iTop\Application\WelcomePopup\Message[]
|
||||
* @api
|
||||
*/
|
||||
public function GetMessages(): array;
|
||||
|
||||
/**
|
||||
* Overload this method if the provider needs to do some additional processing after the message ($sMessageId) has been acknowledged by the current user
|
||||
*
|
||||
* @param string $sMessageId
|
||||
* @api
|
||||
*/
|
||||
public function AcknowledgeMessage(string $sMessageId): void;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add files to the backup
|
||||
*
|
||||
* @api
|
||||
* @since 3.2.0
|
||||
*/
|
||||
interface iBackupExtraFilesExtension
|
||||
{
|
||||
/**
|
||||
* @return string[] Array of relative paths (from app root) for files and directories to be included in the backup
|
||||
* @api
|
||||
*/
|
||||
public function GetExtraFilesRelPaths(): array;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* KPI logging extensibility point
|
||||
*
|
||||
* KPI Logger extension
|
||||
*/
|
||||
interface iKPILoggerExtension
|
||||
{
|
||||
/**
|
||||
* Init the statistics collected
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function InitStats();
|
||||
|
||||
/**
|
||||
* Add a new KPI to the stats
|
||||
*
|
||||
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKpiLogData
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function LogOperation($oKpiLogData);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Helpers for modules extensibility, with discover performed by the MetaModel.
|
||||
*
|
||||
*
|
||||
* @api
|
||||
* @package Extensibility
|
||||
*/
|
||||
interface iModuleExtension
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function __construct();
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Login finite state machine
|
||||
*
|
||||
* Execute the action corresponding to the current login state.
|
||||
*
|
||||
* * If a page is displayed, the action must exit at this point
|
||||
* * if LoginWebPage::LOGIN_FSM_RETURN_ERROR is returned $iErrorCode must be set
|
||||
* * if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
|
||||
* * if LoginWebPage::LOGIN_FSM_CONTINUE is returned then the FSM will proceed to next plugin or to next state
|
||||
*
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
abstract public function ListSupportedLoginModes();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function LoginAction($sLoginState, &$iErrorCode)
|
||||
{
|
||||
switch ($sLoginState) {
|
||||
case LoginWebPage::LOGIN_STATE_START:
|
||||
return $this->OnStart($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_MODE_DETECTION:
|
||||
return $this->OnModeDetection($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_READ_CREDENTIALS:
|
||||
return $this->OnReadCredentials($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_CHECK_CREDENTIALS:
|
||||
return $this->OnCheckCredentials($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_CREDENTIALS_OK:
|
||||
return $this->OnCredentialsOK($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_USER_OK:
|
||||
return $this->OnUsersOK($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_CONNECTED:
|
||||
return $this->OnConnected($iErrorCode);
|
||||
|
||||
case LoginWebPage::LOGIN_STATE_ERROR:
|
||||
return $this->OnError($iErrorCode);
|
||||
}
|
||||
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnStart(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect login mode explicitly without respecting configured order (legacy mode)
|
||||
* In most case do nothing here
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnModeDetection(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the credentials either if login mode is empty or set to yours.
|
||||
* This step can be called multiple times by the FSM:
|
||||
* for example:
|
||||
* 1 - display login form
|
||||
* 2 - read the values posted by the user (store that in session)
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnReadCredentials(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Control the validity of the data from the session
|
||||
* Automatic user provisioning can be done here
|
||||
*
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnCheckCredentials(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnCredentialsOK(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnUsersOK(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnConnected(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
protected function OnError(&$iErrorCode)
|
||||
{
|
||||
return LoginWebPage::LOGIN_FSM_CONTINUE;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLoginExtension
|
||||
{
|
||||
/**
|
||||
* Return the list of supported login modes for this plugin
|
||||
*
|
||||
* @return array of supported login modes
|
||||
* @api
|
||||
*/
|
||||
public function ListSupportedLoginModes();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLoginFSMExtension extends iLoginExtension
|
||||
{
|
||||
/**
|
||||
* Execute action for this login state
|
||||
* If a page is displayed, the action must exit at this point
|
||||
* if LoginWebPage::LOGIN_FSM_RETURN_ERROR is returned $iErrorCode must be set
|
||||
* if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated
|
||||
* if LoginWebPage::LOGIN_FSM_CONTINUE is returned then the FSM will proceed to next plugin or state
|
||||
*
|
||||
* @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...)
|
||||
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
|
||||
*
|
||||
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_CONTINUE
|
||||
* @api
|
||||
*/
|
||||
public function LoginAction($sLoginState, &$iErrorCode);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Login page extensibility
|
||||
*
|
||||
* @api
|
||||
* @package UIExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLoginUIExtension extends iLoginExtension
|
||||
{
|
||||
/**
|
||||
* @return LoginTwigContext
|
||||
* @api
|
||||
*/
|
||||
public function GetTwigContext();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @package LoginExtensibilityAPI
|
||||
* @since 2.7.0
|
||||
*/
|
||||
interface iLogoutExtension extends iLoginExtension
|
||||
{
|
||||
/**
|
||||
* Execute all actions to log out properly
|
||||
* @api
|
||||
*/
|
||||
public function LogoutAction();
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Extend this class instead of iPortalUIExtension if you don't need to overload all methods
|
||||
*
|
||||
* @api
|
||||
* @package PortalExtensibilityAPI
|
||||
* @since 2.4.0
|
||||
*/
|
||||
abstract class AbstractPortalUIExtension implements iPortalUIExtension
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetCSSInline(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetJSInline(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetBodyHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetMainContentHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetNavigationMenuHTML(\Symfony\Component\DependencyInjection\Container $oContainer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add content to any enhanced portal page
|
||||
*
|
||||
* @api
|
||||
* @package PortalExtensibilityAPI
|
||||
*
|
||||
* @since 2.4.0 interface creation
|
||||
* @since 2.7.0 change method signatures due to Silex to Symfony migration
|
||||
*/
|
||||
interface iPortalUIExtension
|
||||
{
|
||||
const ENUM_PORTAL_EXT_UI_BODY = 'Body';
|
||||
const ENUM_PORTAL_EXT_UI_NAVIGATION_MENU = 'NavigationMenu';
|
||||
const ENUM_PORTAL_EXT_UI_MAIN_CONTENT = 'MainContent';
|
||||
|
||||
/**
|
||||
* Returns an array of CSS file urls
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return array
|
||||
* @api
|
||||
*/
|
||||
public function GetCSSFiles(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns inline (raw) CSS
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetCSSInline(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns an array of JS file urls
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return array
|
||||
* @api
|
||||
*/
|
||||
public function GetJSFiles(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw JS code
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetJSInline(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw HTML code to put at the end of the <body> tag
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetBodyHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw HTML code to put at the end of the #main-wrapper element
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetMainContentHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
|
||||
/**
|
||||
* Returns raw HTML code to put at the end of the #topbar and #sidebar elements
|
||||
*
|
||||
* @param \Symfony\Component\DependencyInjection\Container $oContainer
|
||||
*
|
||||
* @return string
|
||||
* @api
|
||||
*/
|
||||
public function GetNavigationMenuHTML(\Symfony\Component\DependencyInjection\Container $oContainer);
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Minimal REST response structure. Derive this structure to add response data and error codes.
|
||||
*
|
||||
* @api
|
||||
* @package RESTAPI
|
||||
* @since 2.0.1
|
||||
*/
|
||||
class RestResult
|
||||
{
|
||||
/**
|
||||
* Result: no issue has been encountered
|
||||
* @api
|
||||
*/
|
||||
const OK = 0;
|
||||
/**
|
||||
* Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation
|
||||
* @api
|
||||
*/
|
||||
const UNAUTHORIZED = 1;
|
||||
/**
|
||||
* Result: the parameter 'version' is missing
|
||||
* @api
|
||||
*/
|
||||
const MISSING_VERSION = 2;
|
||||
/**
|
||||
* Result: the parameter 'json_data' is missing
|
||||
* @api
|
||||
*/
|
||||
const MISSING_JSON = 3;
|
||||
/**
|
||||
* Result: the input structure is not a valid JSON string
|
||||
* @api
|
||||
*/
|
||||
const INVALID_JSON = 4;
|
||||
/**
|
||||
* Result: the parameter 'auth_user' is missing, authentication aborted
|
||||
* @api
|
||||
*/
|
||||
const MISSING_AUTH_USER = 5;
|
||||
/**
|
||||
* Result: the parameter 'auth_pwd' is missing, authentication aborted
|
||||
* @api
|
||||
*/
|
||||
const MISSING_AUTH_PWD = 6;
|
||||
/**
|
||||
* Result: no operation is available for the specified version
|
||||
* @api
|
||||
*/
|
||||
const UNSUPPORTED_VERSION = 10;
|
||||
/**
|
||||
* Result: the requested operation is not valid for the specified version
|
||||
* @api
|
||||
*/
|
||||
const UNKNOWN_OPERATION = 11;
|
||||
/**
|
||||
* Result: the requested operation cannot be performed because it can cause data (integrity) loss
|
||||
* @api
|
||||
*/
|
||||
const UNSAFE = 12;
|
||||
/**
|
||||
* Result: the request page number is not valid. It must be an integer greater than 0
|
||||
* @api
|
||||
*/
|
||||
const INVALID_PAGE = 13;
|
||||
/**
|
||||
* Result: the operation could not be performed, see the message for troubleshooting
|
||||
* @api
|
||||
*/
|
||||
const INTERNAL_ERROR = 100;
|
||||
|
||||
/**
|
||||
* Default constructor - ok!
|
||||
* @api
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->code = RestResult::OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result code
|
||||
* @var int
|
||||
* @api
|
||||
*/
|
||||
public $code;
|
||||
/**
|
||||
* Result message
|
||||
* @var string
|
||||
* @api
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Sanitize the content of this result to hide sensitive information
|
||||
*/
|
||||
public function SanitizeContent()
|
||||
{
|
||||
// The default implementation does nothing
|
||||
}
|
||||
}
|
||||
@@ -1,368 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Helpers for implementing REST services
|
||||
*
|
||||
* @api
|
||||
* @package RESTAPI
|
||||
*/
|
||||
class RestUtils
|
||||
{
|
||||
/**
|
||||
* Registering tracking information. Any further object modification be associated with the given comment, when the modification gets
|
||||
* recorded into the DB
|
||||
*
|
||||
* @param StdClass $oData Structured input data. Must contain 'comment'.
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
* @api
|
||||
*
|
||||
*/
|
||||
public static function InitTrackingComment($oData)
|
||||
{
|
||||
$sComment = self::GetMandatoryParam($oData, 'comment');
|
||||
CMDBObject::SetTrackInfo($sComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a mandatory parameter from from a Rest/Json structure.
|
||||
*
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @param StdClass $oData Structured input data. Must contain the entry defined by sParamName.
|
||||
*
|
||||
* @return mixed parameter value if present
|
||||
* @throws Exception If the parameter is missing
|
||||
* @api
|
||||
*/
|
||||
public static function GetMandatoryParam($oData, $sParamName)
|
||||
{
|
||||
if (isset($oData->$sParamName)) {
|
||||
return $oData->$sParamName;
|
||||
} else {
|
||||
throw new Exception("Missing parameter '$sParamName'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read an optional parameter from a Rest/Json structure.
|
||||
*
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @param mixed $default Default value if the parameter is not found in the input data
|
||||
*
|
||||
* @param StdClass $oData Structured input data.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
* @api
|
||||
*/
|
||||
public static function GetOptionalParam($oData, $sParamName, $default)
|
||||
{
|
||||
if (isset($oData->$sParamName)) {
|
||||
return $oData->$sParamName;
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a class from a Rest/Json structure.
|
||||
*
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
* @param StdClass $oData Structured input data. Must contain the entry defined by sParamName.
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception If the parameter is missing or the class is unknown
|
||||
* @api
|
||||
*/
|
||||
public static function GetClass($oData, $sParamName)
|
||||
{
|
||||
$sClass = self::GetMandatoryParam($oData, $sParamName);
|
||||
if (!MetaModel::IsValidClass($sClass)) {
|
||||
throw new Exception("$sParamName: '$sClass' is not a valid class'");
|
||||
}
|
||||
|
||||
return $sClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read a list of attribute codes from a Rest/Json structure.
|
||||
*
|
||||
* @param StdClass $oData Structured input data.
|
||||
* @param string $sParamName Name of the parameter to fetch from the input data
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return array of class => list of attributes (see RestResultWithObjects::AddObject that uses it)
|
||||
* @throws Exception
|
||||
* @api
|
||||
*/
|
||||
public static function GetFieldList($sClass, $oData, $sParamName)
|
||||
{
|
||||
$sFields = self::GetOptionalParam($oData, $sParamName, '*');
|
||||
$aShowFields = array();
|
||||
if ($sFields == '*') {
|
||||
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
|
||||
$aShowFields[$sClass][] = $sAttCode;
|
||||
}
|
||||
} elseif ($sFields == '*+') {
|
||||
foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sRefClass) {
|
||||
foreach (MetaModel::ListAttributeDefs($sRefClass) as $sAttCode => $oAttDef) {
|
||||
$aShowFields[$sRefClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach (explode(',', $sFields) as $sAttCode) {
|
||||
$sAttCode = trim($sAttCode);
|
||||
if (($sAttCode != 'id') && (!MetaModel::IsValidAttCode($sClass, $sAttCode))) {
|
||||
throw new Exception("$sParamName: invalid attribute code '$sAttCode'");
|
||||
}
|
||||
$aShowFields[$sClass][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
|
||||
return $aShowFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and interpret object search criteria from a Rest/Json structure
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
* @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the
|
||||
* attriute)
|
||||
*
|
||||
* @return object The object found
|
||||
* @throws Exception If the input structure is not valid or it could not find exactly one object
|
||||
* @api
|
||||
*/
|
||||
protected static function FindObjectFromCriteria($sClass, $oCriteria)
|
||||
{
|
||||
$aCriteriaReport = array();
|
||||
if (isset($oCriteria->finalclass)) {
|
||||
if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
|
||||
throw new Exception("finalclass: Unknown class '" . $oCriteria->finalclass . "'");
|
||||
}
|
||||
if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
|
||||
throw new Exception("finalclass: '" . $oCriteria->finalclass . "' is not a child class of '$sClass'");
|
||||
}
|
||||
$sClass = $oCriteria->finalclass;
|
||||
}
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
foreach ($oCriteria as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||
if (is_object($value) || is_array($value)) {
|
||||
$value = json_encode($value);
|
||||
}
|
||||
$aCriteriaReport[] = "$sAttCode: $value ($realValue)";
|
||||
}
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->Count();
|
||||
if ($iCount == 0) {
|
||||
throw new Exception("No item found with criteria: " . implode(', ', $aCriteriaReport));
|
||||
} elseif ($iCount > 1) {
|
||||
throw new Exception("Several items found ($iCount) with criteria: " . implode(', ', $aCriteriaReport));
|
||||
}
|
||||
$res = $oSet->Fetch();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find an object from a polymorph search specification (Rest/Json)
|
||||
*
|
||||
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
||||
* @param bool $bAllowNullValue Allow the cases such as key = 0 or key = {null} and return null then
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return DBObject The object found
|
||||
* @throws Exception If the input structure is not valid or it could not find exactly one object
|
||||
*
|
||||
* @api
|
||||
* @see DBObject::CheckChangedExtKeysValues() generic method to check that we can access the linked object isn't used in that use case because values can be literal, OQL, friendlyname
|
||||
*/
|
||||
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
|
||||
{
|
||||
if (is_object($key)) {
|
||||
$res = static::FindObjectFromCriteria($sClass, $key);
|
||||
} elseif (is_numeric($key)) {
|
||||
if ($bAllowNullValue && ($key == 0)) {
|
||||
$res = null;
|
||||
} else {
|
||||
$res = MetaModel::GetObject($sClass, $key, false);
|
||||
if (is_null($res)) {
|
||||
throw new Exception("Invalid object $sClass::$key");
|
||||
}
|
||||
}
|
||||
} elseif (is_string($key)) {
|
||||
// OQL
|
||||
$oSearch = DBObjectSearch::FromOQL($key);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
$iCount = $oSet->Count();
|
||||
if ($iCount == 0) {
|
||||
throw new Exception("No item found for query: $key");
|
||||
} elseif ($iCount > 1) {
|
||||
throw new Exception("Several items found ($iCount) for query: $key");
|
||||
}
|
||||
$res = $oSet->Fetch();
|
||||
} else {
|
||||
throw new Exception("Wrong format for key");
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search objects from a polymorph search specification (Rest/Json)
|
||||
*
|
||||
* @param string $sClass Name of the class
|
||||
* @param mixed $key Either search criteria (substructure), or an object or an OQL string.
|
||||
* @param int $iLimit The limit of results to return
|
||||
* @param int $iOffset The offset of results to return
|
||||
*
|
||||
* @return DBObjectSet The search result set
|
||||
* @throws Exception If the input structure is not valid
|
||||
* @api
|
||||
*/
|
||||
public static function GetObjectSetFromKey($sClass, $key, $iLimit = 0, $iOffset = 0)
|
||||
{
|
||||
if (is_object($key)) {
|
||||
if (isset($key->finalclass)) {
|
||||
$sClass = $key->finalclass;
|
||||
if (!MetaModel::IsValidClass($sClass)) {
|
||||
throw new Exception("finalclass: Unknown class '$sClass'");
|
||||
}
|
||||
}
|
||||
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
foreach ($key as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
$oSearch->AddCondition($sAttCode, $realValue, '=');
|
||||
}
|
||||
} elseif (is_numeric($key)) {
|
||||
$oSearch = new DBObjectSearch($sClass);
|
||||
$oSearch->AddCondition('id', $key);
|
||||
} elseif (is_string($key)) {
|
||||
// OQL
|
||||
try {
|
||||
$oSearch = DBObjectSearch::FromOQL($key);
|
||||
} catch (Exception $e) {
|
||||
throw new CoreOqlException('Query failed to execute', [
|
||||
'query' => $key,
|
||||
'exception_class' => get_class($e),
|
||||
'exception_message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Wrong format for key");
|
||||
}
|
||||
$oObjectSet = new DBObjectSet($oSearch, array(), array(), null, $iLimit, $iOffset);
|
||||
|
||||
return $oObjectSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret the Rest/Json value and get a valid attribute value
|
||||
*
|
||||
* @param string $sAttCode Attribute code
|
||||
* @param mixed $value Depending on the type of attribute (a scalar, or search criteria, or list of related objects...)
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return mixed The value that can be used with DBObject::Set()
|
||||
* @throws Exception If the specification of the value is not valid.
|
||||
* @api
|
||||
*/
|
||||
public static function MakeValue($sClass, $sAttCode, $value)
|
||||
{
|
||||
try {
|
||||
if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
|
||||
throw new Exception("Unknown attribute");
|
||||
}
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeExternalKey) {
|
||||
$oExtKeyObject = static::FindObjectFromKey($oAttDef->GetTargetClass(), $value, true /* allow null */);
|
||||
$value = ($oExtKeyObject != null) ? $oExtKeyObject->GetKey() : 0;
|
||||
} elseif ($oAttDef instanceof AttributeLinkedSet) {
|
||||
if (!is_array($value)) {
|
||||
throw new Exception("A link set must be defined by an array of objects");
|
||||
}
|
||||
$sLnkClass = $oAttDef->GetLinkedClass();
|
||||
$aLinks = array();
|
||||
foreach ($value as $oValues) {
|
||||
$oLnk = static::MakeObjectFromFields($sLnkClass, $oValues);
|
||||
// Fix for N°1939
|
||||
if (($oAttDef instanceof AttributeLinkedSetIndirect) && ($oLnk->Get($oAttDef->GetExtKeyToRemote()) == 0)) {
|
||||
continue;
|
||||
}
|
||||
$aLinks[] = $oLnk;
|
||||
}
|
||||
$value = DBObjectSet::FromArray($sLnkClass, $aLinks);
|
||||
} elseif ($oAttDef instanceof AttributeTagSet) {
|
||||
if (!is_array($value)) {
|
||||
throw new Exception("A tag set must be defined by an array of tag codes");
|
||||
}
|
||||
$value = $oAttDef->FromJSONToValue($value);
|
||||
} else {
|
||||
$value = $oAttDef->FromJSONToValue($value);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a Rest/Json structure that defines attribute values, and build an object
|
||||
*
|
||||
* @param array $aFields A hash of attribute code => value specification.
|
||||
* @param string $sClass Name of the class
|
||||
*
|
||||
* @return DBObject The newly created object
|
||||
* @throws Exception If the specification of the values is not valid
|
||||
* @api
|
||||
*/
|
||||
public static function MakeObjectFromFields($sClass, $aFields)
|
||||
{
|
||||
$oObject = MetaModel::NewObject($sClass);
|
||||
foreach ($aFields as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
try {
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
return $oObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a Rest/Json structure that defines attribute values, and update the given object
|
||||
*
|
||||
* @param array $aFields A hash of attribute code => value specification.
|
||||
* @param DBObject $oObject The object being modified
|
||||
*
|
||||
* @return DBObject The object modified
|
||||
* @throws Exception If the specification of the values is not valid
|
||||
* @api
|
||||
*/
|
||||
public static function UpdateObjectFromFields($oObject, $aFields)
|
||||
{
|
||||
$sClass = get_class($oObject);
|
||||
foreach ($aFields as $sAttCode => $value) {
|
||||
$realValue = static::MakeValue($sClass, $sAttCode, $value);
|
||||
try {
|
||||
$oObject->Set($sAttCode, $realValue);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("$sAttCode: " . $e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
return $oObject;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A REST service provider implementing this interface will have its input JSON data sanitized for logging purposes
|
||||
*
|
||||
* @see \iRestServiceProvider
|
||||
* @since 2.7.13, 3.2.1-1
|
||||
*/
|
||||
interface iRestInputSanitizer
|
||||
{
|
||||
public function SanitizeJsonInput(string $sJsonInput): string;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to add new operations to the REST/JSON web service
|
||||
*
|
||||
* @api
|
||||
* @package RESTExtensibilityAPI
|
||||
* @since 2.0.1
|
||||
*/
|
||||
interface iRestServiceProvider
|
||||
{
|
||||
/**
|
||||
* Enumerate services delivered by this class
|
||||
*
|
||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||
*
|
||||
* @return array An array of hash 'verb' => verb, 'description' => description
|
||||
* @api
|
||||
*/
|
||||
public function ListOperations($sVersion);
|
||||
|
||||
/**
|
||||
* Enumerate services delivered by this class
|
||||
*
|
||||
* @param string $sVersion The version (e.g. 1.0) supported by the services
|
||||
* @param string $sVerb
|
||||
* @param array $aParams
|
||||
*
|
||||
* @return RestResult The standardized result structure (at least a message)
|
||||
* @api
|
||||
*/
|
||||
public function ExecOperation($sVersion, $sVerb, $aParams);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -22,7 +22,7 @@
|
||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||
* inside the set
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -22,7 +22,7 @@
|
||||
* to check and is linked to a set of rules that determine the valid or invalid objects
|
||||
* inside the set
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -86,7 +86,7 @@ class lnkAuditCategoryToAuditDomain extends cmdbAbstractObject
|
||||
{
|
||||
$aParams = array
|
||||
(
|
||||
"category" => "application,grant_by_profile",
|
||||
"category" => "application, grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -23,7 +23,7 @@
|
||||
* or the "bad" ones. The core audit engines computes the complement to the definition
|
||||
* set when needed to obtain either the valid objects, or the ones with an error
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
8
application/capturewebpage.class.inc.php
Normal file
8
application/capturewebpage.class.inc.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader');
|
||||
8
application/clipage.class.inc.php
Normal file
8
application/clipage.class.inc.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader');
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2024 Combodo SAS
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
|
||||
8
application/csvpage.class.inc.php
Normal file
8
application/csvpage.class.inc.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader');
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -9,8 +9,6 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
require_once(APPROOT.'application/dashboardlayout.class.inc.php');
|
||||
require_once(APPROOT.'application/dashlet.class.inc.php');
|
||||
@@ -296,21 +294,21 @@ abstract class Dashboard
|
||||
public function FromParams($aParams)
|
||||
{
|
||||
$this->sLayoutClass = $aParams['layout_class'];
|
||||
if (!is_subclass_of($this->sLayoutClass,DashboardLayout::class)) {
|
||||
throw new InvalidParameterException('Invalid parameter layout_class "'.$aParams['layout_class'].'"');
|
||||
}
|
||||
$this->sTitle = $aParams['title'];
|
||||
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
||||
|
||||
foreach($aParams['cells'] as $aCell) {
|
||||
foreach($aParams['cells'] as $aCell)
|
||||
{
|
||||
$aCellDashlets = array();
|
||||
foreach($aCell as $aDashletParams) {
|
||||
foreach($aCell as $aDashletParams)
|
||||
{
|
||||
$sDashletClass = $aDashletParams['dashlet_class'];
|
||||
$sId = $aDashletParams['dashlet_id'];
|
||||
/** @var \Dashlet $oNewDashlet */
|
||||
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
|
||||
if (isset($aDashletParams['dashlet_type'])) {
|
||||
if (isset($aDashletParams['dashlet_type']))
|
||||
{
|
||||
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
|
||||
}
|
||||
$oForm = $oNewDashlet->GetForm();
|
||||
@@ -424,7 +422,7 @@ abstract class Dashboard
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage *
|
||||
* @param \WebPage $oPage *
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
@@ -480,7 +478,7 @@ abstract class Dashboard
|
||||
CombodoTooltip.InitTooltipFromMarkup($("#attr_auto_reload_sec"));
|
||||
$("#attr_auto_reload_sec").prop('disabled', !$('#attr_auto_reload').is(':checked'));
|
||||
|
||||
$('#attr_auto_reload').on('change', function(ev) {
|
||||
$('#attr_auto_reload').change( function(ev) {
|
||||
$("#attr_auto_reload_sec").prop('disabled', !$(this).is(':checked'));
|
||||
} );
|
||||
|
||||
@@ -515,7 +513,7 @@ EOF
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param bool $bEditMode
|
||||
* @param array $aExtraParams
|
||||
* @param bool $bCanEdit
|
||||
@@ -524,7 +522,9 @@ EOF
|
||||
*/
|
||||
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
|
||||
{
|
||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
if (!array_key_exists('dashboard_div_id', $aExtraParams)) {
|
||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||
}
|
||||
|
||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||
$oLayout = new $this->sLayoutClass();
|
||||
@@ -561,15 +561,15 @@ JS
|
||||
}
|
||||
|
||||
if (!$bEditMode) {
|
||||
$oPage->LinkScriptFromAppRoot('js/dashlet.js');
|
||||
$oPage->LinkScriptFromAppRoot('js/dashboard.js');
|
||||
$oPage->add_linked_script('../js/dashlet.js');
|
||||
$oPage->add_linked_script('../js/dashboard.js');
|
||||
}
|
||||
|
||||
return $oDashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
* @throws \Exception
|
||||
@@ -592,7 +592,7 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
*/
|
||||
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
|
||||
@@ -1050,7 +1050,7 @@ EOF
|
||||
$sSelectorHtml .= '</div>';
|
||||
|
||||
$sFile = addslashes($this->GetDefinitionFile());
|
||||
$sReloadURL = json_encode($this->GetReloadURL());
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
|
||||
$bFromDashboardPage = isset($aAjaxParams['from_dashboard_page']) ? isset($aAjaxParams['from_dashboard_page']) : false;
|
||||
if ($bFromDashboardPage) {
|
||||
@@ -1109,15 +1109,15 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function RenderEditionTools(WebPage $oPage, DashboardLayoutUIBlock $oDashboard, $aExtraParams)
|
||||
{
|
||||
$oPage->LinkScriptFromAppRoot('node_modules/blueimp-file-upload/js/jquery.iframe-transport.js');
|
||||
$oPage->LinkScriptFromAppRoot('node_modules/blueimp-file-upload/js/jquery.fileupload.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.iframe-transport.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.fileupload.js');
|
||||
$sId = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||
|
||||
$sMenuTogglerId = "ibo-dashboard-menu-toggler-{$sId}";
|
||||
@@ -1139,6 +1139,7 @@ JS
|
||||
->AddCSSClass('ibo-action-button');
|
||||
|
||||
$oToolbar->AddSubBlock($oActionButton);
|
||||
|
||||
$aActions = array();
|
||||
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
||||
$sJSExtraParams = json_encode($aExtraParams);
|
||||
@@ -1163,7 +1164,7 @@ JS
|
||||
$oToolbar->AddSubBlock($oActionButton)
|
||||
->AddSubBlock($oActionsMenu);
|
||||
|
||||
$sReloadURL = json_encode($this->GetReloadURL());
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
function EditDashboard(sId, sDashboardFile, aExtraParams)
|
||||
@@ -1227,7 +1228,7 @@ EOF
|
||||
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
*
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
@@ -1263,14 +1264,14 @@ EOF
|
||||
$sOkButtonLabel = Dict::S('UI:Button:Save');
|
||||
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
|
||||
|
||||
$sId = json_encode($this->sId);
|
||||
$sLayoutClass = json_encode($this->sLayoutClass);
|
||||
$sId = utils::HtmlEntities($this->sId);
|
||||
$sLayoutClass = utils::HtmlEntities($this->sLayoutClass);
|
||||
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
|
||||
$sAutoReloadSec = (string) $this->iAutoReloadSec;
|
||||
$sTitle = json_encode($this->sTitle);
|
||||
$sFile = json_encode($this->GetDefinitionFile());
|
||||
$sTitle = utils::HtmlEntities($this->sTitle);
|
||||
$sFile = utils::HtmlEntities($this->GetDefinitionFile());
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
|
||||
$sReloadURL = json_encode($this->GetReloadURL());
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
|
||||
$sExitConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
|
||||
$sCancelConfirmationMessage = addslashes(Dict::S('UI:CancelConfirmationMessage'));
|
||||
@@ -1324,15 +1325,15 @@ $('#dashboard_editor').dialog({
|
||||
});
|
||||
|
||||
$('#dashboard_editor .ui-layout-center').runtimedashboard({
|
||||
dashboard_id: $sId,
|
||||
layout_class: $sLayoutClass,
|
||||
title: $sTitle,
|
||||
dashboard_id: '$sId',
|
||||
layout_class: '$sLayoutClass',
|
||||
title: '$sTitle',
|
||||
auto_reload: $sAutoReload,
|
||||
auto_reload_sec: $sAutoReloadSec,
|
||||
submit_to: '$sUrl',
|
||||
submit_parameters: {operation: 'save_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
||||
submit_parameters: {operation: 'save_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
||||
render_to: '$sUrl',
|
||||
render_parameters: {operation: 'render_dashboard', file: $sFile, extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
||||
render_parameters: {operation: 'render_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
|
||||
new_dashlet_parameters: {operation: 'new_dashlet'}
|
||||
});
|
||||
|
||||
@@ -1487,7 +1488,7 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param $sOQL
|
||||
*
|
||||
* @throws \DictExceptionMissingString
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2024 Combodo SAS
|
||||
// Copyright (C) 2010-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,12 +19,11 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardColumn;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardRow;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
/**
|
||||
* Dashboard presentation
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class DashboardLayout
|
||||
@@ -107,7 +106,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param $aCells
|
||||
* @param bool $bEditMode
|
||||
* @param array $aExtraParams
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2012-2024 Combodo SAS
|
||||
// Copyright (C) 2012-2023 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -23,14 +23,13 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
|
||||
require_once(APPROOT.'application/forms.class.inc.php');
|
||||
|
||||
/**
|
||||
* Base class for all 'dashlets' (i.e. widgets to be inserted into a dashboard)
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
abstract class Dashlet
|
||||
@@ -223,7 +222,7 @@ abstract class Dashlet
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param bool $bEditMode
|
||||
* @param bool $bEnclosingDiv
|
||||
* @param array $aExtraParams
|
||||
@@ -299,7 +298,7 @@ EOF
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param bool $bEditMode
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
@@ -310,7 +309,7 @@ EOF
|
||||
/**
|
||||
* Rendering without the real data
|
||||
*
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param bool $bEditMode
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
@@ -1967,10 +1966,7 @@ class DashletHeaderStatic extends Dashlet
|
||||
$sIcon = $this->aProperties['icon'];
|
||||
|
||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||
$sIconPath = '';
|
||||
if (Utils::IsNotNullOrEmptyString($sIcon)) {
|
||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||
}
|
||||
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
|
||||
|
||||
return DashletFactory::MakeForDashletHeaderStatic($this->oModelReflection->DictString($sTitle), $sIconPath);
|
||||
}
|
||||
@@ -1984,7 +1980,6 @@ class DashletHeaderStatic extends Dashlet
|
||||
$oForm->AddField($oField);
|
||||
|
||||
$oField = $this->oModelReflection->GetIconSelectionField('icon', Dict::S('UI:DashletHeaderStatic:Prop-Icon'), $this->aProperties['icon']);
|
||||
$oField->AddAllowedValue(['value' => '', 'label' => Dict::S('UI:DashletIcon:None'), 'icon' => '']);
|
||||
$oForm->AddField($oField);
|
||||
}
|
||||
|
||||
@@ -2097,10 +2092,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$sGroupBy = $this->aProperties['group_by'];
|
||||
|
||||
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
|
||||
$sIconPath = '';
|
||||
if (Utils::IsNotNullOrEmptyString($sIcon)) {
|
||||
$sIconPath = $oIconSelect->MakeFileUrl($sIcon);
|
||||
}
|
||||
$sIconPath = $oIconSelect->MakeFileUrl($sIcon);
|
||||
|
||||
$aValues = $this->GetValues();
|
||||
if (count($aValues) > 0) {
|
||||
@@ -2145,7 +2137,7 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
$iCount = $oSet->Count();
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($oFilter->serialize());
|
||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($oFilter->serialize());
|
||||
$oSubTitle->AddHtml('<a class="summary" href="'.$sHyperlink.'">'.Dict::Format(str_replace('_', ':', $sSubtitle), $iCount).'</a>');
|
||||
|
||||
return $oPanel;
|
||||
@@ -2230,7 +2222,6 @@ class DashletHeaderDynamic extends Dashlet
|
||||
$oForm->AddField($oField);
|
||||
|
||||
$oField = $this->oModelReflection->GetIconSelectionField('icon', Dict::S('UI:DashletHeaderDynamic:Prop-Icon'), $this->aProperties['icon']);
|
||||
$oField->AddAllowedValue(['value' => '', 'label' => Dict::S('UI:DashletIcon:None'), 'icon' => '']);
|
||||
$oForm->AddField($oField);
|
||||
|
||||
$oField = new DesignerTextField('subtitle', Dict::S('UI:DashletHeaderDynamic:Prop-Subtitle'), $this->aProperties['subtitle']);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
|
||||
<classes>
|
||||
<class id="AbstractResource" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
@@ -40,36 +40,6 @@
|
||||
<presentation/>
|
||||
<methods/>
|
||||
</class>
|
||||
<class id="WelcomePopupAcknowledge" _delta="define">
|
||||
<parent>DBObject</parent>
|
||||
<properties>
|
||||
<comment>/** Acknowledge welcome popup messages */</comment>
|
||||
<abstract>false</abstract>
|
||||
<category/>
|
||||
<key_type>autoincrement</key_type>
|
||||
<db_table>priv_welcome_popup_acknowledge</db_table>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="message_uuid" xsi:type="AttributeString">
|
||||
<sql>message_uuid</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
<field id="user_id" xsi:type="AttributeExternalKey">
|
||||
<sql>user_id</sql>
|
||||
<target_class>User</target_class>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
<on_target_delete>DEL_SILENT</on_target_delete>
|
||||
</field>
|
||||
<field id="acknowledge_date" xsi:type="AttributeDateTime">
|
||||
<sql>acknowledge_date</sql>
|
||||
<default_value/>
|
||||
<is_null_allowed>false</is_null_allowed>
|
||||
</field>
|
||||
</fields>
|
||||
<presentation/>
|
||||
<methods/>
|
||||
</class>
|
||||
</classes>
|
||||
<portals>
|
||||
<portal id="backoffice" _delta="define">
|
||||
@@ -111,6 +81,7 @@
|
||||
<menu id="UserManagement" xsi:type="TemplateMenuNode" _delta="define">
|
||||
<rank>10</rank>
|
||||
<parent>AdminTools</parent>
|
||||
<template_file/>
|
||||
</menu>
|
||||
<menu id="UserAccountsMenu" xsi:type="OQLMenuNode" _delta="define">
|
||||
<rank>11</rank>
|
||||
@@ -140,6 +111,7 @@
|
||||
<menu id="Queries" xsi:type="TemplateMenuNode" _delta="define">
|
||||
<rank>30</rank>
|
||||
<parent>AdminTools</parent>
|
||||
<template_file/>
|
||||
</menu>
|
||||
<menu id="RunQueriesMenu" xsi:type="WebPageMenuNode" _delta="define">
|
||||
<rank>31</rank>
|
||||
@@ -183,10 +155,6 @@
|
||||
<decoration_classes>fas fa-cog</decoration_classes>
|
||||
</style>
|
||||
</menu>
|
||||
<menu id="Integrations" xsi:type="TemplateMenuNode" _delta="define">
|
||||
<rank>50</rank>
|
||||
<parent>ConfigurationTools</parent>
|
||||
</menu>
|
||||
<menu id="DataSources" xsi:type="OQLMenuNode" _delta="define">
|
||||
<rank>20</rank>
|
||||
<parent>ConfigurationTools</parent>
|
||||
@@ -219,9 +187,7 @@
|
||||
</menus>
|
||||
<events>
|
||||
<event id="EVENT_DB_BEFORE_WRITE" _delta="define">
|
||||
<name>Before create or update</name>
|
||||
<description><![CDATA[An object is about to be written into the database.
|
||||
The object can be modified.]]></description>
|
||||
<description>An object is about to be written into the database. The object can be modified.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -235,10 +201,6 @@ The object can be modified.]]></description>
|
||||
<description>Creation flag</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus_applied">
|
||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
@@ -246,11 +208,7 @@ The object can be modified.]]></description>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_CHECK_TO_WRITE" _delta="define">
|
||||
<name>Check to write</name>
|
||||
<description><![CDATA[Check an object before it is written into the database (no change possible).
|
||||
Call $this->AddCheckIssue($sErrorMessage) to report a blocking issue.
|
||||
Call $this->AddCheckWarning($sWarningMessage) to display a warning.
|
||||
]]></description>
|
||||
<description>Check an object before it is written into the database (no change possible). Call DBObject::AddCheckIssue() to signal an issue</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -264,10 +222,6 @@ Call $this->AddCheckWarning($sWarningMessage) to display a warning.
|
||||
<description>Creation flag</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus_applied">
|
||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
@@ -275,9 +229,7 @@ Call $this->AddCheckWarning($sWarningMessage) to display a warning.
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_AFTER_WRITE" _delta="define">
|
||||
<name>After create or update</name>
|
||||
<description><![CDATA[An object has been written into the database.
|
||||
The modifications can be propagated to other objects.]]></description>
|
||||
<description>An object has been written into the database. The modifications can be propagated to other objects.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -292,13 +244,9 @@ The modifications can be propagated to other objects.]]></description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="changes">
|
||||
<description><![CDATA[For updates, the list of changes done during this operation]]></description>
|
||||
<description>For updates, the list of changes done during this operation</description>
|
||||
<type>array</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus_applied">
|
||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
@@ -306,9 +254,7 @@ The modifications can be propagated to other objects.]]></description>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_CHECK_TO_DELETE" _delta="define">
|
||||
<name>Check to delete</name>
|
||||
<description><![CDATA[Check an object before it is deleted from the database.
|
||||
Call $this->AddDeleteIssue($sIssueMessage) to signal an issue.]]></description>
|
||||
<description>Check an object before it is deleted from the database. Call DBObject::AddDeleteIssue() to signal an issue</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -324,27 +270,8 @@ Call $this->AddDeleteIssue($sIssueMessage) to signal an issue.]]></description>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_ABOUT_TO_DELETE" _delta="define">
|
||||
<name>Before delete</name>
|
||||
<description><![CDATA[An object is about to be deleted from the database]]></description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<replaces>cmdbAbstractObject::OnDelete</replaces>
|
||||
<event_data>
|
||||
<event_datum id="object">
|
||||
<description>The object about to be deleted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_AFTER_DELETE" _delta="define">
|
||||
<name>After delete</name>
|
||||
<description><![CDATA[An object has been deleted into the database]]></description>
|
||||
<description>An object has been deleted into the database</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -360,10 +287,8 @@ Call $this->AddDeleteIssue($sIssueMessage) to signal an issue.]]></description>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_ENUM_TRANSITIONS" _delta="define">
|
||||
<name>Enum transitions</name>
|
||||
<description><![CDATA[Manage the allowed transitions in current object state.
|
||||
The only action allowed is to deny transitions with $this->DenyTransition($sTransitionCode)]]></description>
|
||||
<event id="EVENT_DB_BEFORE_APPLY_STIMULUS" _delta="define">
|
||||
<description>A stimulus is about to be applied to an object</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -372,9 +297,89 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
<description>The object where the stimulus is targeted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="allowed_stimuli">
|
||||
<description>The list of available stimuli in the current state</description>
|
||||
<type>array</type>
|
||||
<event_datum id="stimulus">
|
||||
<description>Current stimulus applied</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="previous_state">
|
||||
<description>Object previous state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="new_state">
|
||||
<description>Object new state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="save_object">
|
||||
<description>The object must be saved in the database</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_AFTER_APPLY_STIMULUS" _delta="define">
|
||||
<description>A stimulus has been applied to an object</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<event_data>
|
||||
<event_datum id="object">
|
||||
<description>The object where the stimulus is targeted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus">
|
||||
<description>Current stimulus applied</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="previous_state">
|
||||
<description>Object previous state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="new_state">
|
||||
<description>Object new state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="save_object">
|
||||
<description>The object is asked to be saved in the database</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_APPLY_STIMULUS_FAILED" _delta="define">
|
||||
<description>A stimulus has failed</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<event_data>
|
||||
<event_datum id="action">
|
||||
<description>The action that failed to apply the stimulus</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="object">
|
||||
<description>The object where the stimulus is targeted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus">
|
||||
<description>Current stimulus applied</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="previous_state">
|
||||
<description>Object previous state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="new_state">
|
||||
<description>Object new state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="save_object">
|
||||
<description>The object must be saved in the database</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
@@ -383,8 +388,7 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_LINKS_CHANGED" _delta="define">
|
||||
<name>Links on object have changed</name>
|
||||
<description><![CDATA[At least one link class was changed]]></description>
|
||||
<description>At least one link class was changed</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -400,9 +404,7 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_OBJECT_RELOAD" _delta="define">
|
||||
<name>Object reload</name>
|
||||
<internal>true</internal>
|
||||
<description><![CDATA[An object has been re-loaded from the database]]></description>
|
||||
<description>An object has been re-loaded from the database</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -418,8 +420,7 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_COMPUTE_VALUES" _delta="define">
|
||||
<name>Recompute object values</name>
|
||||
<description><![CDATA[An object needs to be recomputed after changes]]></description>
|
||||
<description>An object needs to be recomputed after changes</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -429,14 +430,6 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
<description>The object inserted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="is_new">
|
||||
<description>Creation flag</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus_applied">
|
||||
<description>Life cycle stimulus applied (null if not within a transition)</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
@@ -444,8 +437,7 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_ARCHIVE" _delta="define">
|
||||
<name>Object archived</name>
|
||||
<description><![CDATA[An object has been archived]]></description>
|
||||
<description>An object has been archived</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -461,8 +453,7 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_UNARCHIVE" _delta="define">
|
||||
<name>Object unarchived</name>
|
||||
<description><![CDATA[An object has been unarchived]]></description>
|
||||
<description>An object has been unarchived</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -478,9 +469,7 @@ The only action allowed is to deny transitions with $this->DenyTransition($sTran
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_SET_ATTRIBUTES_FLAGS" _delta="define">
|
||||
<name>Set attributes flags</name>
|
||||
<description><![CDATA[Set object attributes flags.
|
||||
Call $this->AddAttributeFlags($sAttCode, $iFlags) for all the attributes to be set for this target state.]]></description>
|
||||
<description>Set object attributes flags. Call cmdbAbstractObject::AddAttributeFlags() for all the attributes to be set for this target state.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -491,7 +480,7 @@ Call $this->AddAttributeFlags($sAttCode, $iFlags) for all the attributes to be s
|
||||
</event_datum>
|
||||
<event_datum id="target_state">
|
||||
<description>The target state in which to evaluate the flags</description>
|
||||
<type>string</type>
|
||||
<type>array</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
@@ -500,9 +489,7 @@ Call $this->AddAttributeFlags($sAttCode, $iFlags) for all the attributes to be s
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_SET_INITIAL_ATTRIBUTES_FLAGS" _delta="define">
|
||||
<name>Set initial attributes flags</name>
|
||||
<description><![CDATA[Set object initial attributes flags.
|
||||
Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial attributes to be set initially.]]></description>
|
||||
<description>Set object initial attributes flags. Call cmdbAbstractObject::AddInitialAttributeFlags() for all the initial attributes to be set initially.</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -518,8 +505,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DOWNLOAD_DOCUMENT" _delta="define">
|
||||
<name>Document downloaded</name>
|
||||
<description><![CDATA[A document has been downloaded from the GUI]]></description>
|
||||
<description>A document has been downloaded from the GUI</description>
|
||||
<sources>
|
||||
<source id="Document">Document</source>
|
||||
</sources>
|
||||
@@ -528,18 +514,10 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
<description>The object containing the document</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="att_code">
|
||||
<description>The optional object attribute code hosting the document</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="document">
|
||||
<description>The document downloaded</description>
|
||||
<type>ormDocument</type>
|
||||
</event_datum>
|
||||
<event_datum id="content_disposition">
|
||||
<description>The content disposition of the document ("inline" or "attachment")</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
@@ -547,9 +525,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_LOGIN" _delta="define">
|
||||
<name>Login</name>
|
||||
<internal>true</internal>
|
||||
<description><![CDATA[Inform the listeners about the connection states]]></description>
|
||||
<description>Inform the listeners about the connection states</description>
|
||||
<event_data>
|
||||
<event_datum id="code">
|
||||
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>
|
||||
|
||||
877
application/datatable.class.inc.php
Normal file
877
application/datatable.class.inc.php
Normal file
@@ -0,0 +1,877 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2023 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
|
||||
*
|
||||
* @deprecated 3.0.0 use Combodo\iTop\Application\UI\Base\Component\DataTable\Datatable
|
||||
*/
|
||||
|
||||
class DataTable
|
||||
{
|
||||
protected $iListId; // Unique ID inside the web page
|
||||
/** @var string */
|
||||
private $sDatatableContainerId;
|
||||
protected $sTableId; // identifier for saving the settings (combined with the class aliases)
|
||||
protected $oSet; // The set of objects to display
|
||||
protected $aClassAliases; // The aliases (alias => class) inside the set
|
||||
protected $iNbObjects; // Total number of objects in the set
|
||||
protected $bUseCustomSettings; // Whether or not the current display uses custom settings
|
||||
protected $oDefaultSettings; // the default settings for displaying such a list
|
||||
protected $bShowObsoleteData;
|
||||
|
||||
/**
|
||||
* @param string $iListId Unique ID for this div/table in the page
|
||||
* @param DBObjectSet $oSet The set of data to display
|
||||
* @param array$aClassAliases The list of classes/aliases to be displayed in this set $sAlias => $sClassName
|
||||
* @param string $sTableId A string (or null) identifying this table in order to persist its settings
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
public function __construct($iListId, $oSet, $aClassAliases, $sTableId = null)
|
||||
{
|
||||
DeprecatedCallsLog::NotifyDeprecatedPhpMethod('use Combodo\iTop\Application\UI\Base\Component\DataTable\Datatable');
|
||||
$this->iListId = utils::GetSafeId($iListId); // Make a "safe" ID for jQuery
|
||||
$this->sDatatableContainerId = 'datatable_'.utils::GetSafeId($iListId);
|
||||
$this->oSet = $oSet;
|
||||
$this->aClassAliases = $aClassAliases;
|
||||
$this->sTableId = $sTableId;
|
||||
$this->iNbObjects = $oSet->Count();
|
||||
$this->bUseCustomSettings = false;
|
||||
$this->oDefaultSettings = null;
|
||||
$this->bShowObsoleteData = $oSet->GetShowObsoleteData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param \DataTableSettings $oSettings
|
||||
* @param $bActionsMenu
|
||||
* @param $sSelectMode
|
||||
* @param $bViewLink
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public function Display(WebPage $oPage, DataTableSettings $oSettings, $bActionsMenu, $sSelectMode, $bViewLink, $aExtraParams)
|
||||
{
|
||||
$this->oDefaultSettings = $oSettings;
|
||||
|
||||
// Identified tables can have their own specific settings
|
||||
$oCustomSettings = DataTableSettings::GetTableSettings($this->aClassAliases, $this->sTableId);
|
||||
|
||||
if ($oCustomSettings != null)
|
||||
{
|
||||
// Custom settings overload the default ones
|
||||
$this->bUseCustomSettings = true;
|
||||
if ($this->oDefaultSettings->iDefaultPageSize == 0)
|
||||
{
|
||||
$oCustomSettings->iDefaultPageSize = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oCustomSettings = $oSettings;
|
||||
}
|
||||
|
||||
if ($oCustomSettings->iDefaultPageSize > 0)
|
||||
{
|
||||
$this->oSet->SetLimit($oCustomSettings->iDefaultPageSize);
|
||||
}
|
||||
$this->oSet->SetOrderBy($oCustomSettings->GetSortOrder());
|
||||
|
||||
// Load only the requested columns
|
||||
$aColumnsToLoad = array();
|
||||
foreach($oCustomSettings->aColumns as $sAlias => $aColumnsInfo)
|
||||
{
|
||||
foreach($aColumnsInfo as $sAttCode => $aData)
|
||||
{
|
||||
if ($sAttCode != '_key_')
|
||||
{
|
||||
if ($aData['checked'])
|
||||
{
|
||||
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
// See if this column is a must to load
|
||||
$sClass = $this->aClassAliases[$sAlias];
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
if ($oAttDef->AlwaysLoadInTables()) {
|
||||
$aColumnsToLoad[$sAlias][] = $sAttCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->oSet->OptimizeColumnLoad($aColumnsToLoad);
|
||||
|
||||
|
||||
$bToolkitMenu = true;
|
||||
if (isset($aExtraParams['toolkit_menu']))
|
||||
{
|
||||
$bToolkitMenu = (bool) $aExtraParams['toolkit_menu'];
|
||||
}
|
||||
if (UserRights::IsPortalUser())
|
||||
{
|
||||
// Portal users have a limited access to data, for now they can only see what's configured for them
|
||||
$bToolkitMenu = false;
|
||||
}
|
||||
|
||||
return $this->GetAsHTML($oPage, $oCustomSettings->iDefaultPageSize, $oCustomSettings->iDefaultPageSize, 0, $oCustomSettings->aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $iPageSize
|
||||
* @param $iDefaultPageSize
|
||||
* @param $iPageIndex
|
||||
* @param $aColumns
|
||||
* @param $bActionsMenu
|
||||
* @param $bToolkitMenu
|
||||
* @param $sSelectMode
|
||||
* @param $bViewLink
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function GetAsHTML(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex, $aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams)
|
||||
{
|
||||
$sObjectsCount = $this->GetObjectCount($oPage, $sSelectMode);
|
||||
$sPager = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||
$sActionsMenu = '';
|
||||
$sToolkitMenu = '';
|
||||
if ($bActionsMenu) {
|
||||
$sActionsMenu = $this->GetActionsMenu($oPage, $aExtraParams);
|
||||
}
|
||||
// if ($bToolkitMenu)
|
||||
// {
|
||||
// $sToolkitMenu = $this->GetToolkitMenu($oPage, $aExtraParams);
|
||||
// }
|
||||
|
||||
$sDataTable = $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
$sConfigDlg = $this->GetTableConfigDlg($oPage, $aColumns, $bViewLink, $iDefaultPageSize);
|
||||
|
||||
$sHtml = "<table id=\"{$this->sDatatableContainerId}\" class=\"datatable\">";
|
||||
$sHtml .= "<tr><td>";
|
||||
$sHtml .= "<table style=\"width:100%;\">";
|
||||
$sHtml .= "<tr><td class=\"pagination_container\">$sObjectsCount</td><td class=\"menucontainer\">$sToolkitMenu $sActionsMenu</td></tr>";
|
||||
$sHtml .= "<tr>$sPager</tr>";
|
||||
$sHtml .= "</table>";
|
||||
$sHtml .= "</td></tr>";
|
||||
$sHtml .= "<tr><td class=\"datacontents\">$sDataTable</td></tr>";
|
||||
$sHtml .= "</table>\n";
|
||||
$oPage->add_at_the_end($sConfigDlg);
|
||||
|
||||
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
||||
|
||||
$aOptions = array(
|
||||
'sPersistentId' => '',
|
||||
'sFilter' => $this->oSet->GetFilter()->serialize(),
|
||||
'oColumns' => $aColumns,
|
||||
'sSelectMode' => $sSelectMode,
|
||||
'sViewLink' => ($bViewLink ? 'true' : 'false'),
|
||||
'iNbObjects' => $this->iNbObjects,
|
||||
'iDefaultPageSize' => $iDefaultPageSize,
|
||||
'iPageSize' => $iPageSize,
|
||||
'iPageIndex' => $iPageIndex,
|
||||
'oClassAliases' => $this->aClassAliases,
|
||||
'sTableId' => $this->sTableId,
|
||||
'oExtraParams' => $aExtraParams,
|
||||
'sRenderUrl' => utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php',
|
||||
'oRenderParameters' => array('str' => ''), // Forces JSON to encode this as a object...
|
||||
'oDefaultSettings' => array('str' => ''), // Forces JSON to encode this as a object...
|
||||
'oLabels' => array('moveup' => Dict::S('UI:Button:MoveUp'), 'movedown' => Dict::S('UI:Button:MoveDown')),
|
||||
);
|
||||
if($this->oDefaultSettings != null)
|
||||
{
|
||||
$aOptions['oDefaultSettings'] = $this->GetAsHash($this->oDefaultSettings);
|
||||
}
|
||||
$sJSOptions = json_encode($aOptions);
|
||||
$oPage->add_ready_script("$('#{$this->sDatatableContainerId}').datatable($sJSOptions);");
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* When refreshing the body of a paginated table, get the rows of the table (inside the TBODY)
|
||||
* return string The HTML rows to insert inside the <tbody> node
|
||||
*/
|
||||
public function GetAsHTMLTableRows(WebPage $oPage, $iPageSize, $aColumns, $sSelectMode, $bViewLink, $aExtraParams)
|
||||
{
|
||||
if ($iPageSize < 1)
|
||||
{
|
||||
$iPageSize = -1; // convention: no pagination
|
||||
}
|
||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
|
||||
$sHtml = '';
|
||||
foreach($aValues as $aRow)
|
||||
{
|
||||
$sHtml .= $oPage->GetTableRow($aRow, $aAttribs);
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $sSelectMode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function GetObjectCount(WebPage $oPage, $sSelectMode)
|
||||
{
|
||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
||||
{
|
||||
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderSelection', '<span id="total">'.$this->iNbObjects.'</span>', '<span class="selectedCount">0</span>').'</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml = '<div class="pagination_objcount">'.Dict::Format('UI:Pagination:HeaderNoSelection', '<span id="total">'.$this->iNbObjects.'</span>').'</div>';
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $iPageSize
|
||||
* @param $iDefaultPageSize
|
||||
* @param $iPageIndex
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function GetPager(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex)
|
||||
{
|
||||
$sHtml = '';
|
||||
if ($iPageSize < 1) // Display all
|
||||
{
|
||||
$sPagerStyle = 'style="display:none"'; // no limit: display the full table, so hide the "pager" UI
|
||||
// WARNING: mPDF does not take the "display" style into account
|
||||
// when applied to a <td> or a <table> tag, so make sure you apply this to a div
|
||||
}
|
||||
else
|
||||
{
|
||||
$sPagerStyle = '';
|
||||
}
|
||||
|
||||
$sCombo = '<select class="pagesize">';
|
||||
if($iPageSize < 1)
|
||||
{
|
||||
$sCombo .= "<option selected=\"selected\" value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||
}
|
||||
else
|
||||
{
|
||||
for($iPage = 1; $iPage < 5; $iPage++)
|
||||
{
|
||||
$iNbItems = $iPage * $iDefaultPageSize;
|
||||
$sSelected = ($iNbItems == $iPageSize) ? 'selected="selected"' : '';
|
||||
$sCombo .= "<option $sSelected value=\"$iNbItems\">$iNbItems</option>";
|
||||
}
|
||||
$sCombo .= "<option value=\"-1\">".Dict::S('UI:Pagination:All')."</option>";
|
||||
}
|
||||
|
||||
$sCombo .= '</select>';
|
||||
|
||||
$sPages = Dict::S('UI:Pagination:PagesLabel');
|
||||
$sPageSizeCombo = Dict::Format('UI:Pagination:PageSize', $sCombo);
|
||||
|
||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||
if ($iNbPages == 1)
|
||||
{
|
||||
// No need to display the pager
|
||||
$sPagerStyle = 'style="display:none"';
|
||||
}
|
||||
$aPagesToDisplay = array();
|
||||
for($idx = 0; $idx <= min(4, $iNbPages-1); $idx++)
|
||||
{
|
||||
if ($idx == 0)
|
||||
{
|
||||
$aPagesToDisplay[$idx] = '<span page="0" class="curr_page">1</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPagesToDisplay[$idx] = "<span id=\"gotopage_$idx\" class=\"gotopage\" page=\"$idx\">".(1+$idx)."</span>";
|
||||
}
|
||||
}
|
||||
$iLastPageIdx = $iNbPages - 1;
|
||||
if (!isset($aPagesToDisplay[$iLastPageIdx]))
|
||||
{
|
||||
unset($aPagesToDisplay[$idx - 1]); // remove the last page added to make room for the very last page
|
||||
$aPagesToDisplay[$iLastPageIdx] = "<span id=\"gotopage_$iLastPageIdx\" class=\"gotopage\" page=\"$iLastPageIdx\">... $iNbPages</span>";
|
||||
}
|
||||
$sPagesLinks = implode('', $aPagesToDisplay);
|
||||
$sPagesList = '['.implode(',', array_keys($aPagesToDisplay)).']';
|
||||
|
||||
$sSelectionMode = ($iNbPages == 1) ? '' : 'positive';
|
||||
$sHtml =
|
||||
<<<EOF
|
||||
<td colspan="2">
|
||||
<div $sPagerStyle>
|
||||
<table id="pager{$this->iListId}" class="pager"><tr>
|
||||
<td>$sPages</td>
|
||||
<td><img src="../images/first.png" class="first"/></td>
|
||||
<td><img src="../images/prev.png" class="prev"/></td>
|
||||
<td><span id="index">$sPagesLinks</span></td>
|
||||
<td><img src="../images/next.png" class="next"/></td>
|
||||
<td><img src="../images/last.png" class="last"/></td>
|
||||
<td>$sPageSizeCombo</td>
|
||||
<td><span id="loading"> </span><input type="hidden" name="selectionMode" value="$sSelectionMode"></input>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
EOF;
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
protected function GetActionsMenu(WebPage $oPage, $aExtraParams)
|
||||
{
|
||||
$oMenuBlock = new MenuBlock($this->oSet->GetFilter(), 'list');
|
||||
$oBlock = $oMenuBlock->GetRenderContent($oPage, $aExtraParams, $this->iListId);
|
||||
|
||||
return ConsoleBlockRenderer::RenderBlockTemplateInPage($oPage, $oBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams)
|
||||
{
|
||||
if (!$oPage->IsPrintableVersion())
|
||||
{
|
||||
$sMenuTitle = Dict::S('UI:ConfigureThisList');
|
||||
$sHtml = '<div class="itop_popup toolkit_menu" id="tk_'.$this->iListId.'"><ul><li aria-label="'.Dict::S('UI:Menu:Toolkit').'"><i class="fas fa-tools"></i><i class="fas fa-caret-down"></i><ul>';
|
||||
|
||||
$oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "$('#datatable_dlg_".$this->iListId."').dialog('open');");
|
||||
$aActions = array(
|
||||
$oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem(),
|
||||
);
|
||||
$this->oSet->Rewind();
|
||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId);
|
||||
$this->oSet->Rewind();
|
||||
$sHtml .= $oPage->RenderPopupMenuItems($aActions);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHtml = '';
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $aColumns
|
||||
* @param $bViewLink
|
||||
* @param $iDefaultPageSize
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function GetTableConfigDlg(WebPage $oPage, $aColumns, $bViewLink, $iDefaultPageSize)
|
||||
{
|
||||
$sHtml = "<div id=\"datatable_dlg_{$this->iListId}\" style=\"display: none;\">";
|
||||
$sHtml .= "<form onsubmit=\"return false\">";
|
||||
$sChecked = ($this->bUseCustomSettings) ? '' : 'checked';
|
||||
$sHtml .= "<p><input id=\"dtbl_dlg_settings_{$this->iListId}\" type=\"radio\" name=\"settings\" $sChecked value=\"defaults\"><label for=\"dtbl_dlg_settings_{$this->iListId}\"> ".Dict::S('UI:UseDefaultSettings').'</label></p>';
|
||||
$sHtml .= "<fieldset>";
|
||||
$sChecked = ($this->bUseCustomSettings) ? 'checked': '';
|
||||
$sHtml .= "<legend class=\"transparent\"><input id=\"dtbl_dlg_specific_{$this->iListId}\" type=\"radio\" class=\"specific_settings\" name=\"settings\" $sChecked value=\"specific\"><label for=\"dtbl_dlg_specific_{$this->iListId}\"> ".Dict::S('UI:UseSpecificSettings')."</label></legend>";
|
||||
$sHtml .= Dict::S('UI:ColumnsAndSortOrder').'<br/><ul class="sortable_field_list" id="sfl_'.$this->iListId.'"></ul>';
|
||||
|
||||
$sHtml .= '<p>'.Dict::Format('UI:Display_X_ItemsPerPage', '<input type="text" size="4" name="page_size" value="'.$iDefaultPageSize.'">').'</p>';
|
||||
$sHtml .= "</fieldset>";
|
||||
$sHtml .= "<fieldset>";
|
||||
$sSaveChecked = ($this->sTableId != null) ? 'checked' : '';
|
||||
$sCustomDisabled = ($this->sTableId == null) ? 'disabled="disabled" stay-disabled="true" ' : '';
|
||||
$sCustomChecked = ($this->sTableId != null) ? 'checked' : '';
|
||||
$sGenericChecked = ($this->sTableId == null) ? 'checked' : '';
|
||||
$sHtml .= "<legend class=\"transparent\"><input id=\"dtbl_dlg_save_{$this->iListId}\" type=\"checkbox\" $sSaveChecked name=\"save_settings\"><label for=\"dtbl_dlg_save_{$this->iListId}\"> ".Dict::S('UI:UseSavetheSettings')."</label></legend>";
|
||||
$sHtml .= "<p><input id=\"dtbl_dlg_this_list_{$this->iListId}\" type=\"radio\" name=\"scope\" $sCustomChecked $sCustomDisabled value=\"this_list\"><label for=\"dtbl_dlg_this_list_{$this->iListId}\"> ".Dict::S('UI:OnlyForThisList').'</label> ';
|
||||
$sHtml .= "<input id=\"dtbl_dlg_all_{$this->iListId}\" type=\"radio\" name=\"scope\" $sGenericChecked value=\"defaults\"><label for=\"dtbl_dlg_all_{$this->iListId}\"> ".Dict::S('UI:ForAllLists').'</label></p>';
|
||||
$sHtml .= "</fieldset>";
|
||||
$sHtml .= '<table style="width:100%"><tr><td style="text-align:center;">';
|
||||
$sHtml .= '<button type="button" onclick="$(\'#'.$this->sDatatableContainerId.'\').datatable(\'onDlgCancel\'); $(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'close\')">'.Dict::S('UI:Button:Cancel').'</button>';
|
||||
$sHtml .= '</td><td style="text-align:center;">';
|
||||
$sHtml .= '<button type="submit" onclick="$(\'#'.$this->sDatatableContainerId.'\').datatable(\'onDlgOk\');$(\'#datatable_dlg_'.$this->iListId.'\').dialog(\'close\');">'.Dict::S('UI:Button:Ok').'</button>';
|
||||
$sHtml .= '</td></tr></table>';
|
||||
$sHtml .= "</form>";
|
||||
$sHtml .= "</div>";
|
||||
|
||||
$sDlgTitle = addslashes(Dict::S('UI:ListConfigurationTitle'));
|
||||
$oPage->add_ready_script("$('#datatable_dlg_{$this->iListId}').dialog({autoOpen: false, title: '$sDlgTitle', width: 500, close: function() { $('#{$this->sDatatableContainerId}').datatable('onDlgCancel'); } });");
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $oSetting
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetAsHash($oSetting)
|
||||
{
|
||||
$aSettings = array('iDefaultPageSize' => $oSetting->iDefaultPageSize, 'oColumns' => $oSetting->aColumns);
|
||||
return $aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aColumns
|
||||
* @param string $sSelectMode
|
||||
* @param bool $bViewLink
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink)
|
||||
{
|
||||
$aAttribs = array();
|
||||
if ($sSelectMode == 'multiple')
|
||||
{
|
||||
$aAttribs['form::select'] = array(
|
||||
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>",
|
||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||
'metadata' => array(),
|
||||
);
|
||||
}
|
||||
else if ($sSelectMode == 'single')
|
||||
{
|
||||
$aAttribs['form::select'] = array('label' => '', 'description' => '', 'metadata' => array());
|
||||
}
|
||||
|
||||
foreach($this->aClassAliases as $sAlias => $sClassName)
|
||||
{
|
||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||
{
|
||||
if ($aData['checked'])
|
||||
{
|
||||
if ($sAttCode == '_key_')
|
||||
{
|
||||
$sAttLabel = MetaModel::GetName($sClassName);
|
||||
|
||||
$aAttribs['key_'.$sAlias] = array(
|
||||
'label' => $sAttLabel,
|
||||
'description' => '',
|
||||
'metadata' => array(
|
||||
'object_class' => $sClassName,
|
||||
'attribute_label' => $sAttLabel,
|
||||
),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
||||
$sAttDefClass = get_class($oAttDef);
|
||||
$sAttLabel = MetaModel::GetLabel($sClassName, $sAttCode);
|
||||
|
||||
$aAttribs[$sAttCode.'_'.$sAlias] = array(
|
||||
'label' => $sAttLabel,
|
||||
'description' => $oAttDef->GetOrderByHint(),
|
||||
'metadata' => array(
|
||||
'object_class' => $sClassName,
|
||||
'attribute_code' => $sAttCode,
|
||||
'attribute_type' => $sAttDefClass,
|
||||
'attribute_label' => $sAttLabel,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aAttribs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $aColumns
|
||||
* @param $sSelectMode
|
||||
* @param $iPageSize
|
||||
* @param $bViewLink
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||
{
|
||||
$bLocalize = true;
|
||||
if (isset($aExtraParams['localize_values']))
|
||||
{
|
||||
$bLocalize = (bool) $aExtraParams['localize_values'];
|
||||
}
|
||||
|
||||
$aValues = array();
|
||||
$aAttDefsCache = array();
|
||||
$this->oSet->Seek(0);
|
||||
$iMaxObjects = $iPageSize;
|
||||
while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0))
|
||||
{
|
||||
$bFirstObject = true;
|
||||
$aRow = array();
|
||||
foreach($this->aClassAliases as $sAlias => $sClassName)
|
||||
{
|
||||
if (is_object($aObjects[$sAlias]))
|
||||
{
|
||||
$sHilightClass = $aObjects[$sAlias]->GetHilightClass();
|
||||
if ($sHilightClass != '')
|
||||
{
|
||||
$aRow['@class'] = $sHilightClass;
|
||||
}
|
||||
if ((($sSelectMode == 'single') || ($sSelectMode == 'multiple')) && $bFirstObject)
|
||||
{
|
||||
if (array_key_exists('selection_enabled', $aExtraParams) && isset($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]))
|
||||
{
|
||||
$sDisabled = ($aExtraParams['selection_enabled'][$aObjects[$sAlias]->GetKey()]) ? '' : ' disabled="disabled"';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisabled = '';
|
||||
}
|
||||
if ($sSelectMode == 'single')
|
||||
{
|
||||
$aRow['form::select'] = "<input type=\"radio\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow['form::select'] = "<input type=\"checkbox\" $sDisabled class=\"selectList{$this->iListId}\" name=\"selectObject[]\" value=\"".$aObjects[$sAlias]->GetKey()."\"></input>";
|
||||
}
|
||||
}
|
||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||
{
|
||||
if ($aData['checked'])
|
||||
{
|
||||
if ($sAttCode == '_key_')
|
||||
{
|
||||
$aRow['key_'.$sAlias] = array(
|
||||
'value_raw' => $aObjects[$sAlias]->GetKey(),
|
||||
'value_html' => $aObjects[$sAlias]->GetHyperLink(),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prepare att. def. classes cache to avoid retrieving AttDef for each row
|
||||
if(!isset($aAttDefsCache[$sClassName][$sAttCode]))
|
||||
{
|
||||
$aAttDefClassesCache[$sClassName][$sAttCode] = get_class(MetaModel::GetAttributeDef($sClassName, $sAttCode));
|
||||
}
|
||||
|
||||
// Only retrieve raw (stored) value for simple fields
|
||||
$bExcludeRawValue = false;
|
||||
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
|
||||
{
|
||||
if (is_a($aAttDefClassesCache[$sClassName][$sAttCode], $sAttDefClassToExclude, true))
|
||||
{
|
||||
$bExcludeRawValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($bExcludeRawValue)
|
||||
{
|
||||
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow[$sAttCode.'_'.$sAlias] = array(
|
||||
'value_raw' => $aObjects[$sAlias]->Get($sAttCode),
|
||||
'value_html' => $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||
{
|
||||
if ($aData['checked'])
|
||||
{
|
||||
if ($sAttCode == '_key_')
|
||||
{
|
||||
$aRow['key_'.$sAlias] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow[$sAttCode.'_'.$sAlias] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$bFirstObject = false;
|
||||
}
|
||||
$aValues[] = $aRow;
|
||||
$iMaxObjects--;
|
||||
}
|
||||
return $aValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $aColumns
|
||||
* @param $sSelectMode
|
||||
* @param $iPageSize
|
||||
* @param $bViewLink
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||
{
|
||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||
if ($iPageSize < 1)
|
||||
{
|
||||
$iPageSize = -1; // convention: no pagination
|
||||
}
|
||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||
|
||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
|
||||
$sHtml = '<table class="listContainer object-list">';
|
||||
|
||||
foreach($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue)
|
||||
{
|
||||
$aExtraParams['query_params'][$sName] = $sValue;
|
||||
}
|
||||
$aExtraParams['show_obsolete_data'] = $this->bShowObsoleteData;
|
||||
|
||||
$sHtml .= "<tr><td>";
|
||||
$sHtml .= $oPage->GetTable($aAttribs, $aValues);
|
||||
$sHtml .= '</td></tr>';
|
||||
$sHtml .= '</table>';
|
||||
$iCount = $this->iNbObjects;
|
||||
|
||||
$aArgs = $this->oSet->GetArgs();
|
||||
$sExtraParams = addslashes(str_replace('"', "'", json_encode(array_merge($aExtraParams, $aArgs)))); // JSON encode, change the style of the quotes and escape them
|
||||
$sSelectModeJS = '';
|
||||
$sHeaders = '';
|
||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
||||
{
|
||||
$sSelectModeJS = $sSelectMode;
|
||||
$sHeaders = 'headers: { 0: {sorter: false}},';
|
||||
}
|
||||
$sDisplayKey = ($bViewLink) ? 'true' : 'false';
|
||||
// Protect against duplicate elements in the Zlist
|
||||
$aUniqueOrderedList = array();
|
||||
foreach($this->aClassAliases as $sAlias => $sClassName)
|
||||
{
|
||||
foreach($aColumns[$sAlias] as $sAttCode => $aData)
|
||||
{
|
||||
if ($aData['checked'])
|
||||
{
|
||||
$aUniqueOrderedList[$sAttCode] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$aUniqueOrderedList = array_keys($aUniqueOrderedList);
|
||||
$sJSColumns = json_encode($aColumns);
|
||||
$sJSClassAliases = json_encode($this->aClassAliases);
|
||||
$sCssCount = isset($aExtraParams['cssCount']) ? ", cssCount: '{$aExtraParams['cssCount']}'" : '';
|
||||
$this->oSet->ApplyParameters();
|
||||
// Display the actual sort order of the table
|
||||
$aRealSortOrder = $this->oSet->GetRealSortOrder();
|
||||
$aDefaultSort = array();
|
||||
$iColOffset = 0;
|
||||
if (($sSelectMode == 'single') || ($sSelectMode == 'multiple'))
|
||||
{
|
||||
$iColOffset += 1;
|
||||
}
|
||||
if ($bViewLink)
|
||||
{
|
||||
// $iColOffset += 1;
|
||||
}
|
||||
foreach($aRealSortOrder as $sColCode => $bAscending)
|
||||
{
|
||||
$iPos = array_search($sColCode, $aUniqueOrderedList);
|
||||
if ($iPos !== false)
|
||||
{
|
||||
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
||||
}
|
||||
else if (($iPos = array_search(preg_replace('/_friendlyname$/', '', $sColCode), $aUniqueOrderedList)) !== false)
|
||||
{
|
||||
// if sorted on the friendly name of an external key, then consider it sorted on the column that shows the links
|
||||
$aDefaultSort[] = "[".($iColOffset+$iPos).",".($bAscending ? '0' : '1')."]";
|
||||
}
|
||||
else if($sColCode == 'friendlyname' && $bViewLink)
|
||||
{
|
||||
$aDefaultSort[] = "[".($iColOffset).",".($bAscending ? '0' : '1')."]";
|
||||
}
|
||||
}
|
||||
$sFakeSortList = '';
|
||||
if (count($aDefaultSort) > 0)
|
||||
{
|
||||
$sFakeSortList = '['.implode(',', $aDefaultSort).']';
|
||||
}
|
||||
$sOQL = addslashes($this->oSet->GetFilter()->serialize());
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
var oTable = $('#{$this->sDatatableContainerId} table.listResults');
|
||||
oTable.tableHover();
|
||||
oTable
|
||||
.tablesorter({ $sHeaders widgets: ['myZebra', 'truncatedList']})
|
||||
.tablesorterPager({
|
||||
container: $('#pager{$this->iListId}'),
|
||||
totalRows:$iCount,
|
||||
size: $iPageSize,
|
||||
filter: '$sOQL',
|
||||
extra_params: '$sExtraParams',
|
||||
select_mode: '$sSelectModeJS',
|
||||
displayKey: $sDisplayKey,
|
||||
table_id: '{$this->sDatatableContainerId}',
|
||||
columns: $sJSColumns,
|
||||
class_aliases: $sJSClassAliases $sCssCount
|
||||
});
|
||||
JS
|
||||
);
|
||||
if ($sFakeSortList != '')
|
||||
{
|
||||
$oPage->add_ready_script("oTable.trigger(\"fakesorton\", [$sFakeSortList]);");
|
||||
}
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $iDefaultPageSize
|
||||
* @param $iStart
|
||||
*/
|
||||
public function UpdatePager(WebPage $oPage, $iDefaultPageSize, $iStart)
|
||||
{
|
||||
$iPageSize = $iDefaultPageSize;
|
||||
$iPageIndex = 0;
|
||||
$sHtml = $this->GetPager($oPage, $iPageSize, $iDefaultPageSize, $iPageIndex);
|
||||
$oPage->add_ready_script("$('#pager{$this->iListId}').html('".json_encode($sHtml)."');");
|
||||
if ($iDefaultPageSize < 1)
|
||||
{
|
||||
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().hide()");
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->add_ready_script("$('#pager{$this->iListId}').parent().show()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified version of the data table with less "decoration" (and no paging)
|
||||
* which is optimized for printing
|
||||
*/
|
||||
class PrintableDataTable extends DataTable
|
||||
{
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $iPageSize
|
||||
* @param $iDefaultPageSize
|
||||
* @param $iPageIndex
|
||||
* @param $aColumns
|
||||
* @param $bActionsMenu
|
||||
* @param $bToolkitMenu
|
||||
* @param $sSelectMode
|
||||
* @param $bViewLink
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
public function GetAsHTML(WebPage $oPage, $iPageSize, $iDefaultPageSize, $iPageIndex, $aColumns, $bActionsMenu, $bToolkitMenu, $sSelectMode, $bViewLink, $aExtraParams)
|
||||
{
|
||||
return $this->GetHTMLTable($oPage, $aColumns, $sSelectMode, -1, $bViewLink, $aExtraParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param $aColumns
|
||||
* @param $sSelectMode
|
||||
* @param $iPageSize
|
||||
* @param $bViewLink
|
||||
* @param $aExtraParams
|
||||
*
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
*/
|
||||
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
|
||||
{
|
||||
$iNbPages = ($iPageSize < 1) ? 1 : ceil($this->iNbObjects / $iPageSize);
|
||||
if ($iPageSize < 1)
|
||||
{
|
||||
$iPageSize = -1; // convention: no pagination
|
||||
}
|
||||
$aAttribs = $this->GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink);
|
||||
|
||||
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
|
||||
|
||||
$sHtml = $oPage->GetTable($aAttribs, $aValues);
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -24,8 +24,6 @@ use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxBars\BlockChartAjaxBa
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxPie\BlockChartAjaxPie;
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockCsv\BlockCsv;
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Service\Router\Router;
|
||||
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
@@ -263,8 +261,6 @@ class DisplayBlock
|
||||
/** param for export.php */
|
||||
'refresh_action',
|
||||
/**to add refresh button in datatable*/
|
||||
'object_count',
|
||||
/** int number of objects in list */
|
||||
], DataTableUIBlockFactory::GetAllowedParams()),
|
||||
static::ENUM_STYLE_LIST_SEARCH => array_merge([
|
||||
'update_history',
|
||||
@@ -572,7 +568,7 @@ class DisplayBlock
|
||||
} else {
|
||||
// render it as an Ajax (asynchronous) call
|
||||
$oHtml->AddCSSClass("loading");
|
||||
$oHtml->AddHtml("<p><img src=\"".utils::GetAbsoluteUrlAppRoot()."images/indicator_arrows.gif\"> ".Dict::S('UI:Loading').'</p>');
|
||||
$oHtml->AddHtml("<p><img src=\"../images/indicator_arrows.gif\"> ".Dict::S('UI:Loading').'</p>');
|
||||
$oPage->add_script('
|
||||
$.post("ajax.render.php?style='.$this->m_sStyle.'",
|
||||
{ operation: "ajax", filter: "'.$sFilter.'", extra_params: "'.$sExtraParams.'" },
|
||||
@@ -599,7 +595,7 @@ class DisplayBlock
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
@@ -708,7 +704,7 @@ class DisplayBlock
|
||||
if ($bDoSearch)
|
||||
{
|
||||
// Keep the table_id identifying this table if we're performing a search
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, 'raw_data');
|
||||
if ($sTableId != null)
|
||||
{
|
||||
$aExtraParams['table_id'] = $sTableId;
|
||||
@@ -1126,7 +1122,7 @@ JS
|
||||
$oSingleGroupByValueFilter->SetShowObsoleteData($this->m_bShowObsoleteData);
|
||||
}
|
||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot()
|
||||
.'pages/UI.php?operation=search'.$oAppContext->GetForLink(true)
|
||||
.'pages/UI.php?operation=search&'.$oAppContext->GetForLink()
|
||||
.'&filter='.rawurlencode($oSingleGroupByValueFilter->serialize());
|
||||
$aCounts[$sStateValue] = ['link' => $sHyperlink, 'label' => $aCounts[$sStateValue]];
|
||||
}
|
||||
@@ -1234,7 +1230,7 @@ JS
|
||||
$iCount = $this->m_oSet->Count();
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
$sClassIconUrl = MetaModel::GetClassIcon($sClass, false);
|
||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize());
|
||||
$sHyperlink = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize());
|
||||
|
||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||
$aRefreshParams = [
|
||||
@@ -1243,7 +1239,7 @@ JS
|
||||
];
|
||||
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
|
||||
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.$oAppContext->GetForLink(true);
|
||||
$sCreateActionUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=new&class='.$sClass.'&'.$oAppContext->GetForLink();
|
||||
$sCreateActionLabel = Dict::Format('UI:Button:Create');
|
||||
$oBlock = DashletFactory::MakeForDashletBadge($sClassIconUrl, $sHyperlink, $iCount, $sClassLabel, $sCreateActionUrl,
|
||||
$sCreateActionLabel, $aRefreshParams);
|
||||
@@ -1291,7 +1287,7 @@ JS
|
||||
|
||||
$aData = array();
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sParams = $oAppContext->GetForLink(true);
|
||||
$sParams = $oAppContext->GetForLink();
|
||||
foreach ($aGroupBy as $iRow => $iCount) {
|
||||
// Build the search for this subset
|
||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||
@@ -1306,7 +1302,7 @@ JS
|
||||
|
||||
$aData[] = array(
|
||||
'group' => $aLabels[$iRow],
|
||||
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1$sParams&filter=$sFilter\">$iCount</a>"
|
||||
'value' => "<a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&dosearch=1&$sParams&filter=$sFilter\">$iCount</a>"
|
||||
); // TO DO: add the context information
|
||||
}
|
||||
$aAttribs = array(
|
||||
@@ -1358,7 +1354,7 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\iUIBlock
|
||||
@@ -1382,7 +1378,7 @@ JS
|
||||
|
||||
/**
|
||||
* @param array $aExtraParams
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \ConfigException
|
||||
@@ -1460,7 +1456,7 @@ JS
|
||||
|
||||
/**
|
||||
* @param array $aExtraParams
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Layout\UIContentBlock
|
||||
* @throws \ApplicationException
|
||||
@@ -1568,7 +1564,7 @@ JS
|
||||
/**
|
||||
* @deprecated 3.1.0 N°5957
|
||||
*
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Base\Component\Html\Html|\Combodo\iTop\Application\UI\Base\Layout\UIContentBlock|string
|
||||
@@ -1638,7 +1634,7 @@ JS
|
||||
$sGroupByExpr = isset($aExtraParams['group_by_expr']) ? '¶ms[group_by_expr]='.$aExtraParams['group_by_expr'] : '';
|
||||
$sFilter = $this->m_oFilter->serialize(false, $aQueryParams);
|
||||
$oContext = new ApplicationContext();
|
||||
$sContextParam = $oContext->GetForLink(true);
|
||||
$sContextParam = $oContext->GetForLink();
|
||||
$sAggregationFunction = isset($aExtraParams['aggregation_function']) ? $aExtraParams['aggregation_function'] : '';
|
||||
$sAggregationAttr = isset($aExtraParams['aggregation_attribute']) ? $aExtraParams['aggregation_attribute'] : '';
|
||||
$sLimit = isset($aExtraParams['limit']) ? $aExtraParams['limit'] : '';
|
||||
@@ -1646,7 +1642,7 @@ JS
|
||||
$sOrderDirection = isset($aExtraParams['order_direction']) ? $aExtraParams['order_direction'] : '';
|
||||
|
||||
if (isset($aExtraParams['group_by_label'])) {
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).$sContextParam;
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
|
||||
} else {
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$sGroupBy{$sGroupByExpr}¶ms[chart_type]=$sChartType¶ms[currentId]=$sChartId{$iChartCounter}¶ms[order_direction]=$sOrderDirection¶ms[order_by]=$sOrderBy¶ms[limit]=$sLimit¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sChartId{$iChartCounter}&filter=".rawurlencode($sFilter).'&'.$sContextParam;
|
||||
}
|
||||
@@ -1668,7 +1664,7 @@ JS
|
||||
|
||||
/**
|
||||
* @param array $aExtraParams
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
*
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
@@ -1683,14 +1679,11 @@ JS
|
||||
$oBlock = null;
|
||||
$sJSURLs = '';
|
||||
|
||||
$oContext = new ApplicationContext();
|
||||
$sContextParam = $oContext->GetForLink(true);
|
||||
|
||||
if (isset($aExtraParams['group_by'])) {
|
||||
$this->MakeGroupByQuery($aExtraParams, $oGroupByExp, $sGroupByLabel, $aGroupBy, $sAggregationFunction, $sFctVar, $sAggregationAttr, $sSql);
|
||||
$aRes = CMDBSource::QueryToArray($sSql);
|
||||
|
||||
|
||||
$oContext = new ApplicationContext();
|
||||
$sContextParam = $oContext->GetForLink();
|
||||
|
||||
$iTotalCount = 0;
|
||||
$aURLs = array();
|
||||
@@ -1710,14 +1703,14 @@ JS
|
||||
$oSubsetSearch = $this->m_oFilter->DeepClone();
|
||||
$oCondition = new BinaryExpression($oGroupByExp, '=', new ScalarExpression($sValue));
|
||||
$oSubsetSearch->AddConditionExpression($oCondition);
|
||||
$aURLs[] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".rawurlencode($oSubsetSearch->serialize()).$sContextParam;
|
||||
$aURLs[] = utils::GetAbsoluteUrlAppRoot()."pages/UI.php?operation=search&format=html&filter=".rawurlencode($oSubsetSearch->serialize()).'&'.$sContextParam;
|
||||
}
|
||||
$sJSURLs = json_encode($aURLs);
|
||||
}
|
||||
if (isset($aExtraParams['group_by_label'])) {
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).$sContextParam;
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[group_by_label]={$aExtraParams['group_by_label']}¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).'&'.$sContextParam;
|
||||
} else {
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).$sContextParam;
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=chart¶ms[group_by]=$aExtraParams[group_by]¶ms[chart_type]=$sChartType¶ms[currentId]=$aExtraParams[currentId]¶ms[order_direction]=$aExtraParams[order_direction]¶ms[order_by]=$aExtraParams[order_by]¶ms[limit]=$aExtraParams[limit]¶ms[aggregation_function]=$sAggregationFunction¶ms[aggregation_attribute]=$sAggregationAttr&id=$sId&filter=".rawurlencode($this->m_oFilter->ToOQL()).'&'.$sContextParam;
|
||||
}
|
||||
|
||||
switch ($sChartType) {
|
||||
@@ -1790,7 +1783,7 @@ JS
|
||||
|
||||
$oBlock->sCsvFile = strtolower($this->m_oFilter->GetClass()).'.csv';
|
||||
$oBlock->sDownloadLink = utils::GetAbsoluteUrlAppRoot().'webservices/export.php?expression='.urlencode($this->m_oFilter->ToOQL(true)).'&format=csv&filename='.urlencode($oBlock->sCsvFile);
|
||||
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search'.$oAppContext->GetForLink(true).'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
||||
$oBlock->sLinkToToggle = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&'.$oAppContext->GetForLink().'&filter='.rawurlencode($this->m_oFilter->serialize()).'&format=csv';
|
||||
// Pass the parameters via POST, since expression may be very long
|
||||
$aParamsToPost = array(
|
||||
'expression' => $this->m_oFilter->ToOQL(true),
|
||||
@@ -1837,7 +1830,7 @@ class MenuBlock extends DisplayBlock
|
||||
* an object in with the same tab active by default as the tab that was active when selecting
|
||||
* the "Modify..." action.
|
||||
*
|
||||
* @param WebPage $oPage
|
||||
* @param \WebPage $oPage
|
||||
* @param array $aExtraParams
|
||||
* @param string|null $sId
|
||||
*
|
||||
@@ -1865,11 +1858,7 @@ class MenuBlock extends DisplayBlock
|
||||
$aSelectedClasses = $this->GetFilter()->GetSelectedClasses();
|
||||
$bIsForLinkset = isset($aExtraParams['target_attr']);
|
||||
$oSet = new CMDBObjectSet($this->GetFilter());
|
||||
if(isset($aExtraParams['object_count'])){
|
||||
$iSetCount = $aExtraParams['object_count'];
|
||||
} else {
|
||||
$iSetCount = $oSet->Count();
|
||||
}
|
||||
$iSetCount = $oSet->Count();
|
||||
/** @var string $sRefreshAction JS snippet to run when clicking on the refresh button of the menu */
|
||||
$sRefreshAction = $aExtraParams['refresh_action'] ?? '';
|
||||
$bIsCreationInModal = isset($aExtraParams['creation_in_modal']) && $aExtraParams['creation_in_modal'] === true;
|
||||
@@ -1894,7 +1883,10 @@ class MenuBlock extends DisplayBlock
|
||||
&& (!isset($aExtraParams['menu']) || $aExtraParams['menu'] === "1" || $aExtraParams['menu'] === true)
|
||||
) {
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink(true);
|
||||
$sContext = $oAppContext->GetForLink();
|
||||
if (utils::IsNotNullOrEmptyString($sContext)) {
|
||||
$sContext = '&'.$sContext;
|
||||
}
|
||||
|
||||
|
||||
$sFilter = $this->GetFilter()->serialize();
|
||||
@@ -2030,8 +2022,8 @@ class MenuBlock extends DisplayBlock
|
||||
$sSelectedClassName = MetaModel::GetName($sSelectedClass);
|
||||
|
||||
// Check rights on class
|
||||
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE);
|
||||
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
|
||||
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE, $sSelectedClass);
|
||||
|
||||
// Refine filter on selected class so bullk actions occur on the right class
|
||||
$oSelectedClassFilter = $this->GetFilter()->DeepClone();
|
||||
@@ -2224,11 +2216,6 @@ class MenuBlock extends DisplayBlock
|
||||
$aFavoriteRegularActions[$key] = $aRegularActions[$key];
|
||||
unset($aRegularActions[$key]);
|
||||
}
|
||||
// Toolkit actions
|
||||
if (isset($aToolkitActions[$key])) {
|
||||
$aFavoriteRegularActions[$key] = $aToolkitActions[$key];
|
||||
unset($aToolkitActions[$key]);
|
||||
}
|
||||
|
||||
// Transitions
|
||||
if (isset($aTransitionActions[$key])) {
|
||||
@@ -2318,27 +2305,7 @@ class MenuBlock extends DisplayBlock
|
||||
break;
|
||||
|
||||
case 'UI:Menu:EMail':
|
||||
$sIconClass = 'far fa-envelope fa-lg';
|
||||
$sLabel = '';
|
||||
break;
|
||||
case 'UI:Menu:OpenOQL':
|
||||
$sIconClass = 'fas fa-play fa-sm';
|
||||
$sLabel = '';
|
||||
break;
|
||||
case 'UI:Menu:ExportXLSX':
|
||||
$sIconClass = 'far fa-file-excel fa-lg';
|
||||
$sLabel = '';
|
||||
break;
|
||||
case 'UI:Menu:CSVExport':
|
||||
$sIconClass = 'fas fa-file-csv fa-lg';
|
||||
$sLabel = '';
|
||||
break;
|
||||
case 'UI:Menu:PrintableVersion':
|
||||
$sIconClass = 'fas fa-print';
|
||||
$sLabel = '';
|
||||
break;
|
||||
case 'UI:Menu:ExportPDF':
|
||||
$sIconClass = 'fas fa-file-pdf fa-lg';
|
||||
$sIconClass = 'fas fa-share-alt';
|
||||
$sLabel = '';
|
||||
break;
|
||||
|
||||
@@ -2350,12 +2317,7 @@ class MenuBlock extends DisplayBlock
|
||||
}
|
||||
|
||||
$sTarget = isset($aAction['target']) ? $aAction['target'] : '';
|
||||
if (!empty($aAction['onclick'])) {
|
||||
$oActionButton = ButtonUIBlockFactory::MakeIconAction($sIconClass, $aAction['label'], $aAction['label'], $sLabel,false); //utils::Sanitize($sActionId.md5($aAction['onclick']), '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER))
|
||||
$oActionButton->SetOnClickJsCode($aAction['onclick']);
|
||||
} else {
|
||||
$oActionButton = ButtonUIBlockFactory::MakeLinkNeutral($sUrl, $sLabel, $sIconClass, $sTarget, utils::Sanitize($sActionId, '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER));
|
||||
}
|
||||
$oActionButton = ButtonUIBlockFactory::MakeLinkNeutral($sUrl, $sLabel, $sIconClass, $sTarget, utils::Sanitize($sActionId, '', utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER));
|
||||
// ResourceId should not be sanitized
|
||||
$oActionButton->AddDataAttribute('resource-id', $sActionId);
|
||||
$oActionButton->AddCSSClasses(['ibo-action-button', 'ibo-regular-action-button']);
|
||||
@@ -2614,8 +2576,11 @@ class MenuBlock extends DisplayBlock
|
||||
$sUrl = "{$sRootUrl}pages/{$sUIPage}?{$sUrlParams}";
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink(true);
|
||||
$sContext = $oAppContext->GetForLink();
|
||||
if (utils::IsNotNullOrEmptyString($sContext)) {
|
||||
$sUrl .= '&'.$sContext;
|
||||
}
|
||||
|
||||
return $sUrl . $sContext;
|
||||
return $sUrl;
|
||||
}
|
||||
}
|
||||
|
||||
8
application/errorpage.class.inc.php
Normal file
8
application/errorpage.class.inc.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
*/
|
||||
|
||||
DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader');
|
||||
@@ -1,8 +1,4 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Application\WebPage\CLIPage;
|
||||
use Combodo\iTop\Application\WebPage\Page;
|
||||
|
||||
require_once('xlsxwriter.class.php');
|
||||
|
||||
class ExcelExporter
|
||||
@@ -303,7 +299,7 @@ class ExcelExporter
|
||||
{
|
||||
if ($this->sOutputFilePath == null)
|
||||
{
|
||||
return utils::GetDataPath().'bulk_export/'.$this->sToken.'.xlsx';
|
||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -313,14 +309,14 @@ class ExcelExporter
|
||||
|
||||
public static function GetExcelFileFromToken($sToken)
|
||||
{
|
||||
return @file_get_contents(utils::GetDataPath().'bulk_export/'.$sToken.'.xlsx');
|
||||
return @file_get_contents(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
||||
}
|
||||
|
||||
public static function CleanupFromToken($sToken)
|
||||
{
|
||||
@unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.status');
|
||||
@unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.data');
|
||||
@unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.xlsx');
|
||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.status');
|
||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.data');
|
||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
||||
}
|
||||
|
||||
public function Cleanup()
|
||||
@@ -334,7 +330,7 @@ class ExcelExporter
|
||||
*/
|
||||
public static function CleanupOldFiles()
|
||||
{
|
||||
$aFiles = glob(utils::GetDataPath().'bulk_export/*.*');
|
||||
$aFiles = glob(APPROOT.'data/bulk_export/*.*');
|
||||
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
||||
|
||||
if($iDelay > 0)
|
||||
@@ -416,14 +412,14 @@ class ExcelExporter
|
||||
|
||||
protected function CheckDataDir()
|
||||
{
|
||||
if(!is_dir(utils::GetDataPath()."bulk_export"))
|
||||
if(!is_dir(APPROOT."data/bulk_export"))
|
||||
{
|
||||
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
||||
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
||||
clearstatcache();
|
||||
}
|
||||
if (!is_writable(utils::GetDataPath()."bulk_export"))
|
||||
if (!is_writable(APPROOT."data/bulk_export"))
|
||||
{
|
||||
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
||||
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,12 +429,12 @@ class ExcelExporter
|
||||
{
|
||||
$sToken = $this->sToken;
|
||||
}
|
||||
return utils::GetDataPath()."bulk_export/$sToken.status";
|
||||
return APPROOT."data/bulk_export/$sToken.status";
|
||||
}
|
||||
|
||||
protected function GetDataFile()
|
||||
{
|
||||
return utils::GetDataPath().'bulk_export/'.$this->sToken.'.data';
|
||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.data';
|
||||
}
|
||||
|
||||
protected function GetNewToken()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -60,24 +60,6 @@ class CoreCannotSaveObjectException extends CoreException
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
public function getTextMessage()
|
||||
{
|
||||
$sTitle = Dict::S('UI:Error:SaveFailed');
|
||||
$sContent = $sTitle;
|
||||
|
||||
if (count($this->aIssues) == 1) {
|
||||
$sIssue = reset($this->aIssues);
|
||||
$sContent .= $sIssue;
|
||||
} else {
|
||||
foreach ($this->aIssues as $sError) {
|
||||
$sContent .= " " . $sError . ", ";
|
||||
}
|
||||
}
|
||||
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
|
||||
public function getIssues()
|
||||
{
|
||||
return $this->aIssues;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -67,7 +67,7 @@ class CoreException extends Exception
|
||||
|
||||
public function getHtmlDesc($sHighlightHtmlBegin = '<b>', $sHighlightHtmlEnd = '</b>')
|
||||
{
|
||||
return utils::EscapeHtml($this->getMessage());
|
||||
return $this->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user