From 834d74c814fdcd0b12a08671b3b8c294fafc4b7b Mon Sep 17 00:00:00 2001 From: MyuTsu Date: Tue, 16 Sep 2025 15:36:54 +0200 Subject: [PATCH 01/15] eol genericobject --- .github/workflows/continuous-integration.yml | 2 +- ajax/remove.txt | 3 - composer.json | 13 +- composer.lock | 467 ++++++------- front/commondropdown.form.php | 43 -- front/commondropdown.php | 43 -- front/commontreedropdown.form.php | 43 -- front/commontreedropdown.php | 32 - front/eol_info.php | 28 + front/familylist.php | 70 -- front/field.form.php | 63 -- front/getimpacticon.php | 65 -- front/migration_status.php | 62 ++ front/object.form.php | 113 --- front/object.php | 46 -- front/profile.form.php | 54 -- front/type.form.php | 76 -- front/type.php | 54 -- front/typefamily.form.php | 34 - front/typefamily.php | 34 - hook.php | 69 -- inc/eolinfo.class.php | 109 +++ inc/field.class.php | 187 ----- inc/object.class.php | 700 +------------------ inc/profile.class.php | 134 +--- inc/type.class.php | 595 +--------------- inc/typefamily.class.php | 38 +- setup.php | 54 +- templates/eol_info.html.twig | 117 ++++ templates/migration_status.html.twig | 299 ++++++++ 30 files changed, 853 insertions(+), 2794 deletions(-) delete mode 100644 ajax/remove.txt delete mode 100644 front/commondropdown.form.php delete mode 100644 front/commondropdown.php delete mode 100644 front/commontreedropdown.form.php delete mode 100644 front/commontreedropdown.php create mode 100644 front/eol_info.php delete mode 100644 front/familylist.php delete mode 100644 front/field.form.php delete mode 100644 front/getimpacticon.php create mode 100644 front/migration_status.php delete mode 100644 front/object.form.php delete mode 100644 front/object.php delete mode 100644 front/profile.form.php delete mode 100644 front/type.form.php delete mode 100644 front/type.php delete mode 100644 front/typefamily.form.php delete mode 100644 front/typefamily.php create mode 100644 inc/eolinfo.class.php create mode 100644 templates/eol_info.html.twig create mode 100644 templates/migration_status.html.twig diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d1f521d0..b442e5b4 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -20,7 +20,7 @@ jobs: name: "Generate CI matrix" uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1" with: - glpi-version: "10.0.x" + glpi-version: "11.0.x" ci: name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}" needs: "generate-ci-matrix" diff --git a/ajax/remove.txt b/ajax/remove.txt deleted file mode 100644 index 97732142..00000000 --- a/ajax/remove.txt +++ /dev/null @@ -1,3 +0,0 @@ -Vous pouvez effacer ce fichier sans dommages. - -You can safely remove this file. diff --git a/composer.json b/composer.json index 05b653c3..abca2fb8 100644 --- a/composer.json +++ b/composer.json @@ -1,19 +1,24 @@ { "require": { - "php": ">=7.4" + "php": ">=8.2" }, "require-dev": { "glpi-project/phpstan-glpi": "^1.1", "glpi-project/tools": "^0.8.0", "php-parallel-lint/php-parallel-lint": "^1.4", "phpstan/phpstan": "^2.1", - "squizlabs/php_codesniffer": "^3.13" + "phpstan/phpstan-deprecation-rules": "^2.0", + "squizlabs/php_codesniffer": "^3.13", + "phpstan/extension-installer": "^1.4" }, "config": { "optimize-autoloader": true, "platform": { - "php": "7.4.0" + "php": "8.2" }, - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "phpstan/extension-installer": true + } } } diff --git a/composer.lock b/composer.lock index 6425d1e6..ba86048f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f3c8fd45c1590d3efd34bde0a7c463e", + "content-hash": "2927360dc294aa405d9de557d182b3d8", "packages": [], "packages-dev": [ { @@ -58,16 +58,16 @@ }, { "name": "glpi-project/tools", - "version": "0.8.0", + "version": "0.7.8", "source": { "type": "git", "url": "https://github.com/glpi-project/tools.git", - "reference": "7c2dcec105ed3427183bdfd382d785363aade436" + "reference": "bd78ad2ab0d30510729530c077f84d52b8f02866" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/glpi-project/tools/zipball/7c2dcec105ed3427183bdfd382d785363aade436", - "reference": "7c2dcec105ed3427183bdfd382d785363aade436", + "url": "https://api.github.com/repos/glpi-project/tools/zipball/bd78ad2ab0d30510729530c077f84d52b8f02866", + "reference": "bd78ad2ab0d30510729530c077f84d52b8f02866", "shasum": "" }, "require": { @@ -110,7 +110,7 @@ "issues": "https://github.com/glpi-project/tools/issues", "source": "https://github.com/glpi-project/tools" }, - "time": "2025-08-26T10:18:38+00:00" + "time": "2025-08-20T09:58:56+00:00" }, { "name": "php-parallel-lint/php-parallel-lint", @@ -173,18 +173,66 @@ }, "time": "2024-03-27T12:14:49+00:00" }, + { + "name": "phpstan/extension-installer", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" + }, + "time": "2024-09-04T20:21:43+00:00" + }, { "name": "phpstan/phpstan", - "version": "2.1.22", + "version": "2.1.23", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4" + "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/41600c8379eb5aee63e9413fe9e97273e25d57e4", - "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5", "shasum": "" }, "require": { @@ -229,26 +277,78 @@ "type": "github" } ], - "time": "2025-08-04T19:17:37+00:00" + "time": "2025-09-10T11:42:22+00:00" + }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "468e02c9176891cc901143da118f09dc9505fc2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/468e02c9176891cc901143da118f09dc9505fc2f", + "reference": "468e02c9176891cc901143da118f09dc9505fc2f", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.15" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.3" + }, + "time": "2025-05-14T10:56:57+00:00" }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -275,22 +375,22 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.13.2", + "version": "3.13.4", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" + "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", - "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ad545ea9c1b7d270ce0fc9cbfb884161cd706119", + "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119", "shasum": "" }, "require": { @@ -361,56 +461,51 @@ "type": "thanks_dev" } ], - "time": "2025-06-17T22:17:01+00:00" + "time": "2025-09-05T05:47:09+00:00" }, { "name": "symfony/console", - "version": "v5.4.47", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed" + "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", - "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "url": "https://api.github.com/repos/symfony/console/zipball/273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", + "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -444,7 +539,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.47" + "source": "https://github.com/symfony/console/tree/v6.4.25" }, "funding": [ { @@ -455,29 +550,33 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-11-06T11:30:55+00:00" + "time": "2025-08-22T10:21:53+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.4", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", - "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { @@ -486,7 +585,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { @@ -511,7 +610,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -527,7 +626,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/polyfill-ctype", @@ -864,86 +963,6 @@ ], "time": "2024-12-23T08:48:59+00:00" }, - { - "name": "symfony/polyfill-php73", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", - "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, { "name": "symfony/polyfill-php80", "version": "v1.33.0", @@ -1028,111 +1047,28 @@ ], "time": "2025-01-02T08:10:11+00:00" }, - { - "name": "symfony/polyfill-php81", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, { "name": "symfony/service-contracts", - "version": "v2.5.4", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f37b419f7aea2e9abf10abd261832cace12e3300" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300", - "reference": "f37b419f7aea2e9abf10abd261832cace12e3300", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "thanks": { @@ -1140,13 +1076,16 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.6-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1173,7 +1112,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.4" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" }, "funding": [ { @@ -1189,38 +1128,39 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2025-04-25T09:37:31+00:00" }, { "name": "symfony/string", - "version": "v5.4.47", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "136ca7d72f72b599f2631aca474a4f8e26719799" + "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/136ca7d72f72b599f2631aca474a4f8e26719799", - "reference": "136ca7d72f72b599f2631aca474a4f8e26719799", + "url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", + "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1259,7 +1199,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.47" + "source": "https://github.com/symfony/string/tree/v7.3.3" }, "funding": [ { @@ -1270,36 +1210,39 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-11-10T20:33:58+00:00" + "time": "2025-08-25T06:35:40+00:00" }, { "name": "twig/twig", - "version": "v3.11.3", + "version": "v3.21.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "3b06600ff3abefaf8ff55d5c336cd1c4253f8c7e" + "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3b06600ff3abefaf8ff55d5c336cd1c4253f8c7e", - "reference": "3b06600ff3abefaf8ff55d5c336cd1c4253f8c7e", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/285123877d4dd97dd7c11842ac5fb7e86e60d81d", + "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php80": "^1.22", - "symfony/polyfill-php81": "^1.29" + "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { + "phpstan/phpstan": "^2.0", "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, @@ -1343,7 +1286,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.11.3" + "source": "https://github.com/twigphp/Twig/tree/v3.21.1" }, "funding": [ { @@ -1355,7 +1298,7 @@ "type": "tidelift" } ], - "time": "2024-11-07T12:34:41+00:00" + "time": "2025-05-03T07:21:55+00:00" } ], "aliases": [], @@ -1364,11 +1307,11 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.4" + "php": ">=8.2" }, "platform-dev": {}, "platform-overrides": { - "php": "7.4.0" + "php": "8.2" }, "plugin-api-version": "2.6.0" } diff --git a/front/commondropdown.form.php b/front/commondropdown.form.php deleted file mode 100644 index 11c7cc1a..00000000 --- a/front/commondropdown.form.php +++ /dev/null @@ -1,43 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -if (isset($_REQUEST['itemtype'])) { - $itemtype = $_REQUEST['itemtype']; - if (class_exists($itemtype)) { - $dropdown = new $itemtype(); - include(GLPI_ROOT . "/front/dropdown.common.form.php"); - } else { - Html::displayErrorAndDie(__('The requested dropdown does not exists', 'genericobject')); - } -} else { - Html::displayErrorAndDie(__('Not Found!')); -} diff --git a/front/commondropdown.php b/front/commondropdown.php deleted file mode 100644 index 3597003e..00000000 --- a/front/commondropdown.php +++ /dev/null @@ -1,43 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -if (isset($_REQUEST['itemtype'])) { - $itemtype = $_REQUEST['itemtype']; - if (class_exists($itemtype)) { - $dropdown = new $itemtype(); - include(GLPI_ROOT . "/front/dropdown.common.php"); - } else { - Html::displayErrorAndDie(__('The requested dropdown does not exists', 'genericobject')); - } -} else { - Html::displayErrorAndDie(__('Not Found!')); -} diff --git a/front/commontreedropdown.form.php b/front/commontreedropdown.form.php deleted file mode 100644 index 11c7cc1a..00000000 --- a/front/commontreedropdown.form.php +++ /dev/null @@ -1,43 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -if (isset($_REQUEST['itemtype'])) { - $itemtype = $_REQUEST['itemtype']; - if (class_exists($itemtype)) { - $dropdown = new $itemtype(); - include(GLPI_ROOT . "/front/dropdown.common.form.php"); - } else { - Html::displayErrorAndDie(__('The requested dropdown does not exists', 'genericobject')); - } -} else { - Html::displayErrorAndDie(__('Not Found!')); -} diff --git a/front/commontreedropdown.php b/front/commontreedropdown.php deleted file mode 100644 index da2d6ff5..00000000 --- a/front/commontreedropdown.php +++ /dev/null @@ -1,32 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); -include("./commondropdown.php"); diff --git a/front/eol_info.php b/front/eol_info.php new file mode 100644 index 00000000..0a7cf12e --- /dev/null +++ b/front/eol_info.php @@ -0,0 +1,28 @@ +showForm(); + +Html::footer(); diff --git a/front/familylist.php b/front/familylist.php deleted file mode 100644 index 3880052a..00000000 --- a/front/familylist.php +++ /dev/null @@ -1,70 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include('../../../inc/includes.php'); - -$family = new PluginGenericobjectTypeFamily(); - -if (!isset($_GET['id']) || !$family->getFromDB($_GET['id'])) { - Html::header( - __("Objects management", "genericobject"), - $_SERVER['PHP_SELF'], - "assets", - "genericobject" - ); - - echo ""; - echo ""; - echo "
" . __("Empty family", "genericobject") . "
"; -} else { - $family->getFromDB($_GET['id']); - Html::header( - __("Objects management", "genericobject"), - $_SERVER['PHP_SELF'], - "assets", - $family->getName() - ); - - echo ""; - $types = PluginGenericobjectTypeFamily::getItemtypesByFamily($_GET['id']); - echo ""; - foreach ($types as $type) { - $itemtype = $type['itemtype']; - if (Session::haveRight(PluginGenericobjectProfile::getProfileNameForItemtype($itemtype), READ)) { - echo ""; - } - } - echo "
" . Dropdown::getDropdownName("glpi_plugin_genericobject_typefamilies", $_GET['id']) . "
"; - echo ""; - echo $itemtype::getTypeName(); - echo "
"; -} - -Html::footer(); diff --git a/front/field.form.php b/front/field.form.php deleted file mode 100644 index 0c2f26d2..00000000 --- a/front/field.form.php +++ /dev/null @@ -1,63 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); -if (isset($_POST["delete"])) { - if (isset($_POST["fields"]) && count($_POST["fields"]) > 0) { - $type = new PluginGenericobjectType(); - $type->getFromDB($_POST["id"]); - $itemtype = $type->fields['itemtype']; - PluginGenericobjectType::registerOneType($itemtype); - - foreach ($_POST["fields"] as $field => $value) { - if ( - $type->can($_POST["id"], PURGE) - && $value == 1 - && PluginGenericobjectField::checkNecessaryFieldsDelete($itemtype, $field) - ) { - PluginGenericobjectField::deleteField(getTableForItemType($itemtype), $field); - Session::addMessageAfterRedirect(__("Field(s) deleted successfully", "genericobject"), true, INFO); - } - } - } -} else if (isset($_POST["add_field"])) { - $type = new PluginGenericobjectType(); - if ($_POST["new_field"] && $type->can($_POST["id"], UPDATE)) { - $itemtype = $type->fields['itemtype']; - PluginGenericobjectType::registerOneType($itemtype); - PluginGenericobjectField::addNewField(getTableForItemType($itemtype), $_POST["new_field"]); - Session::addMessageAfterRedirect(__("Field added successfully", "genericobject")); - } -} else if (isset($_POST['action'])) { - //Move field - PluginGenericobjectField::changeFieldOrder($_POST); -} - -Html::back(); diff --git a/front/getimpacticon.php b/front/getimpacticon.php deleted file mode 100644 index 6efe10e1..00000000 --- a/front/getimpacticon.php +++ /dev/null @@ -1,65 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -// Read itemtype -$itemtype = $_GET['itemtype'] ?? null; - -// Missing required parameter -if (empty($itemtype)) { - http_response_code(400); - die; -} - -// Find by itemtype -$type = new PluginGenericobjectType(); -if (!$type->getFromDBByCrit(['itemtype' => $itemtype])) { - http_response_code(400); - die; -} - -// Get filepath -$filepath = $type->getImpactIconFilePath(); -if ($filepath === null) { - http_response_code(404); - die; -} - -// Validate image -if (!Document::isImage($filepath)) { - http_response_code(400); - die; -} - -// Send image -header("Content-Type: " . mime_content_type($filepath)); -readfile($filepath); -die; diff --git a/front/migration_status.php b/front/migration_status.php new file mode 100644 index 00000000..4f37bb22 --- /dev/null +++ b/front/migration_status.php @@ -0,0 +1,62 @@ +tableExists(PluginGenericobjectType::getTable())) { + $query = [ + 'SELECT' => ['itemtype', 'name'], + 'FROM' => PluginGenericobjectType::getTable(), + ]; + $request = $DB->request($query); + foreach($request as $data) { + $genericobject_types[$data['name']] = $data; + } + +} + +$customassets = []; +if ($DB->tableExists(AssetDefinition::getTable())) { + $query = [ + 'SELECT' => ['id', 'system_name', 'label', 'icon'], + 'FROM' => AssetDefinition::getTable(), + ]; + $request = $DB->request($query); + foreach($request as $data) { + $customassets[$data['system_name']] = $data; + $customassets[$data['system_name']]['items'] = 0; + if ($DB->tableExists('glpi_forms_forms')) { + $customassets[$data['system_name']]['items'] = countElementsInTable('glpi_assets_assets', ['assets_assetdefinitions_id' => $data['id']]); + } + } +} + +// Display GLPI header +Html::header(__('GenericObject Migration Status', 'genericobject'), '', "tools", "migration"); + +// Render the template content +TemplateRenderer::getInstance()->display('@genericobject/migration_status.html.twig', [ + 'genericobject_types' => $genericobject_types, + 'customassets' => $customassets, +]); + +// Display GLPI footer +Html::footer(); diff --git a/front/object.form.php b/front/object.form.php deleted file mode 100644 index f3cad980..00000000 --- a/front/object.form.php +++ /dev/null @@ -1,113 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -$itemtype = null; - -if (isset($_REQUEST['itemtype'])) { - $types = array_keys(PluginGenericobjectType::getTypes()); - - $requested_type = $_REQUEST['itemtype']; - $error = []; - - if (!in_array($requested_type, $types)) { - $error[] = __('The requested type has not been defined yet!'); - if (!PluginGenericobjectType::canCreate()) { - $error[] = __('Please ask your administrator to create this type of object'); - }; - } else if (!class_exists($requested_type)) { - $error[] = __('The generated files for the requested type of object are missing!'); - $error[] = __('You might need to regenerate the files under ' . GENERICOBJECT_DOC_DIR . '.'); - } - - if (count($error) > 0) { - Html::header(__('Type not found!')); - Html::displayErrorAndDie(implode('
', $error)); - } else { - $itemtype = $requested_type; - } -} - -if (!is_null($itemtype)) { - if (!isset($_REQUEST['id'])) { - $id = -1; - } else { - $id = $_REQUEST['id']; - } - - if (!isset($_GET["withtemplate"])) { - $_GET["withtemplate"] = ""; - } - - $item = new $itemtype(); - - if (isset($_POST["add"])) { - $item->check($id, CREATE); - $newID = $item->add($_POST); - - if ($_SESSION['glpibackcreated']) { - Html::redirect($itemtype::getFormURL() . "&id=" . $newID); - } else { - Html::back(); - } - } else if (isset($_POST["update"])) { - $item->check($id, UPDATE); - $item->update($_POST); - Html::back(); - } else if (isset($_POST["restore"])) { - $item->check($id, DELETE); - $item->restore($_POST); - Html::back(); - } else if (isset($_POST["purge"])) { - $item->check($id, PURGE); - $item->delete($_POST, 1); - $item->redirectToList(); - } else if (isset($_POST["delete"])) { - $item->check($id, DELETE); - $item->delete($_POST); - $item->redirectToList(); - } - $menu = PluginGenericobjectType::getFamilyNameByItemtype($_GET['itemtype']); - Html::header( - $itemtype::getTypeName(), - $_SERVER['PHP_SELF'], - "assets", - ($menu !== false ? $menu : $itemtype), - strtolower($itemtype) - ); - - $item->display($_GET, ['withtemplate' => $_GET["withtemplate"]]); - - Html::footer(); -} else { - Html::header(__('Access Denied!')); - Html::DisplayErrorAndDie(__("You can't access to this page directly!")); -} diff --git a/front/object.php b/front/object.php deleted file mode 100644 index de023a91..00000000 --- a/front/object.php +++ /dev/null @@ -1,46 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -if (isset($_GET['itemtype'])) { - Session::checkRight(PluginGenericobjectProfile::getProfileNameForItemtype($_GET['itemtype']), READ); - $menu = PluginGenericobjectType::getFamilyNameByItemtype($_GET['itemtype']); - Html::header( - __("Type of objects", "genericobject"), - $_SERVER['PHP_SELF'], - "assets", - ($menu !== false ? $menu : strtolower($_GET['itemtype'])), - strtolower($_GET['itemtype']) - ); - Search::Show($_GET['itemtype']); -} - -Html::footer(); diff --git a/front/profile.form.php b/front/profile.form.php deleted file mode 100644 index 9d6fdc25..00000000 --- a/front/profile.form.php +++ /dev/null @@ -1,54 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); -Session::checkRight("profile", UPDATE); - -_log($_POST); -$prof = new Profile(); - -/* save profile */ -if (isset($_POST['update_all_rights']) && isset($_POST['itemtype'])) { - $profiles = []; - foreach ($_POST as $key => $val) { - if (preg_match("/^profile_/", $key)) { - $id = preg_replace("/^profile_/", "", $key); - $profiles[$id] = [ - "id" => $id, - "_" . PluginGenericobjectProfile::getProfileNameForItemtype($_POST['itemtype']) => $val - ]; - } - } - _log($profiles); - foreach ($profiles as $profile_id => $input) { - $prof->update($input); - } -} -Html::redirect($_SERVER['HTTP_REFERER']); diff --git a/front/type.form.php b/front/type.form.php deleted file mode 100644 index 8df873df..00000000 --- a/front/type.form.php +++ /dev/null @@ -1,76 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -if (!isset($_GET["id"])) { - $_GET["id"] = ''; -} -$type = new PluginGenericobjectType(); -$extraparams = []; -if (isset($_POST["select"]) && $_POST["select"] == "all") { - $extraparams["selected"] = "checked"; -} - -if (isset($_POST["add"])) { - //Add a new itemtype - $new_id = $type->add($_POST); - Html::redirect(Toolbox::getItemTypeFormURL('PluginGenericobjectType') . "?id=$new_id"); -} else if (isset($_POST["update"])) { - //Update an existing itemtype - if (isset($_POST['itemtypes']) && is_array($_POST['itemtypes'])) { - $_POST['linked_itemtypes'] = json_encode($_POST['itemtypes']); - } - $type->update($_POST); - Html::back(); -} else if (isset($_POST["purge"])) { - //Delete an itemtype - $type->delete($_POST); - $type->redirectToList(); -} else if (isset($_POST['regenerate'])) { - //Regenerate files for an itemtype - $type->getFromDB($_POST["id"]); - PluginGenericobjectType::checkClassAndFilesForOneItemType( - $type->fields['itemtype'], - $type->fields['name'], - true - ); - Html::back(); -} - -Html::header( - __("Objects management", "genericobject"), - $_SERVER['PHP_SELF'], - "config", - "PluginGenericobjectType" -); -$type->display($_GET); - -Html::footer(); diff --git a/front/type.php b/front/type.php deleted file mode 100644 index 74c4b6a0..00000000 --- a/front/type.php +++ /dev/null @@ -1,54 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -if ( - isset($_GET['itemtype']) - && !isset($_GET['search']) - && !isset($_GET['sort']) -) { - $type = new PluginGenericobjectType(); - $type->getFromDBByType($_GET['itemtype']); - Html::redirect(Toolbox::getItemTypeFormURL('PluginGenericobjectType') . '?id=' . $type->getID()); -} else if (Session::haveRightsOr('plugin_genericobject_types', [READ, CREATE, UPDATE, PURGE])) { - Html::header( - __("Type of objects", "genericobject"), - $_SERVER['PHP_SELF'], - "config", - "PluginGenericobjectType" - ); - Search::Show('PluginGenericobjectType'); - Html::footer(); -} else { - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - Html::redirect($CFG_GLPI['root_doc'] . "/front/central.php"); -} diff --git a/front/typefamily.form.php b/front/typefamily.form.php deleted file mode 100644 index 3a94c818..00000000 --- a/front/typefamily.form.php +++ /dev/null @@ -1,34 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -$dropdown = new PluginGenericobjectTypeFamily(); -include(GLPI_ROOT . "/front/dropdown.common.form.php"); diff --git a/front/typefamily.php b/front/typefamily.php deleted file mode 100644 index 51bd93bc..00000000 --- a/front/typefamily.php +++ /dev/null @@ -1,34 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -include("../../../inc/includes.php"); - -$dropdown = new PluginGenericobjectTypeFamily(); -include(GLPI_ROOT . "/front/dropdown.common.php"); diff --git a/hook.php b/hook.php index 4ead38bf..23f6022c 100644 --- a/hook.php +++ b/hook.php @@ -28,25 +28,9 @@ * ------------------------------------------------------------------------- */ -function plugin_genericobject_AssignToTicket($types) -{ - foreach (PluginGenericobjectType::getTypes() as $tmp => $value) { - $itemtype = $value['itemtype']; - if ($value['use_tickets']) { - if (class_exists($itemtype)) { - $types[$itemtype] = $itemtype::getTypeName(); - } else { - $types[$itemtype] = $itemtype; - } - } - } - return $types; -} - // Define Dropdown tables to be manage in GLPI : function plugin_genericobject_getDropdown() { - $dropdowns = ['PluginGenericobjectTypeFamily' => PluginGenericobjectTypeFamily::getTypeName(2)]; $plugin = new Plugin(); @@ -93,8 +77,6 @@ function plugin_genericobject_install() foreach ( [ 'PluginGenericobjectField', - 'PluginGenericobjectCommonDropdown', - 'PluginGenericobjectCommonTreeDropdown', 'PluginGenericobjectProfile', 'PluginGenericobjectType', 'PluginGenericobjectTypeFamily' @@ -184,54 +166,3 @@ function plugin_genericobject_uninstall() return true; } -function plugin_datainjection_populate_genericobject() -{ - /** @var array $INJECTABLE_TYPES */ - global $INJECTABLE_TYPES; - $type = new PluginGenericobjectType(); - foreach ($type->find(['use_plugin_datainjection' => 1, 'is_active' => 1]) as $data) { - if (class_exists($data ['itemtype'] . "Injection")) { - $INJECTABLE_TYPES[$data ['itemtype'] . "Injection"] = 'genericobject'; - } - } -} - -function plugin_genericobject_MassiveActions($type) -{ - $types = PluginGenericobjectType::getTypes(); - if (isset($types[$type])) { - $objecttype = PluginGenericobjectType::getInstance($type); - if ($objecttype->isTransferable()) { - return ['PluginGenericobjectObject' . - MassiveAction::CLASS_ACTION_SEPARATOR . 'plugin_genericobject_transfer' => __("Transfer") - ]; - } else { - return []; - } - } else { - return []; - } -} - -function plugin_genericobject_MassiveActionsFieldsDisplay($options = []) -{ - if (!Plugin::isPluginActive('fields')) { - return false; - } - - if (!class_exists('PluginFieldsContainer') || !method_exists('PluginFieldsContainer', 'getEntries')) { - return false; - } - - if (!class_exists('PluginFieldsField') || !method_exists('PluginFieldsField', 'showSingle')) { - return false; - } - - $itemtypes = PluginFieldsContainer::getEntries('all'); - - if (in_array($options['itemtype'], $itemtypes)) { - return PluginFieldsField::showSingle($options['itemtype'], $options['options'], true); - } - - return false; -} diff --git a/inc/eolinfo.class.php b/inc/eolinfo.class.php new file mode 100644 index 00000000..c7f4d2be --- /dev/null +++ b/inc/eolinfo.class.php @@ -0,0 +1,109 @@ +display('@genericobject/eol_info.html.twig', [ + 'plugin_version' => PLUGIN_GENERICOBJECT_VERSION, + 'plugin_web_dir' => $CFG_GLPI['root_doc'] . '/plugins/genericobject', + ]); + } + + /** + * Display EOL warning on central dashboard using Twig template + * + * @return void + */ + static function displayCentralEOLWarning() + { + /** @var array $CFG_GLPI */ + global $CFG_GLPI; + + if (!static::canView()) { + return; + } + + $_SESSION['formcreator_eol_central_shown'] = true; + + TemplateRenderer::getInstance()->display('@genericobject/central_eol_warning.html.twig', [ + 'plugin_version' => PLUGIN_GENERICOBJECT_VERSION, + 'root_doc' => $CFG_GLPI['root_doc'], + ]); + } +} diff --git a/inc/field.class.php b/inc/field.class.php index 53cfd578..ba1d8cbc 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -30,122 +30,6 @@ class PluginGenericobjectField extends CommonDBTM { - /** - * - * Displat all fields present in DB for an itemtype - * @param $id the itemtype's id - */ - public static function showObjectFieldsForm($id) - { - /** - * @var array $GO_BLACKLIST_FIELDS - * @var array $GO_READONLY_FIELDS - * @var array $GO_FIELDS - */ - global $GO_BLACKLIST_FIELDS, $GO_READONLY_FIELDS, $GO_FIELDS; - - $url = Toolbox::getItemTypeFormURL(__CLASS__); - $object_type = new PluginGenericobjectType(); - $object_type->getFromDB($id); - $itemtype = $object_type->fields['itemtype']; - $fields_in_db = PluginGenericobjectSingletonObjectField::getInstance($itemtype); - $used_fields = []; - - //Reset fields definition only to keep the itemtype ones - $GO_FIELDS = []; - plugin_genericobject_includeCommonFields(true); - - PluginGenericobjectType::includeLocales($object_type->fields['name']); - PluginGenericobjectType::includeConstants($object_type->fields['name'], true); - - self::addReadOnlyFields($object_type); - - foreach ($GO_BLACKLIST_FIELDS as $autofield) { - if (!in_array($autofield, $used_fields)) { - $used_fields[$autofield] = $autofield; - } - } - - echo "
"; - echo "
"; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - $total = count($fields_in_db); - $global_index = $index = 1; - $haveCheckbox = false; - - foreach ($fields_in_db as $field => $value) { - $readonly = in_array($field, $GO_READONLY_FIELDS); - $blacklist = in_array($field, $GO_BLACKLIST_FIELDS); - - self::displayFieldDefinition($url, $itemtype, $field, $index, ($global_index == $total)); - - //All backlisted fields cannot be moved, and are listed first - if (!$readonly) { - $index++; - } - - if (!$blacklist && !$readonly) { - $haveCheckbox = true; - } - - //$table = getTableNameForForeignKeyField($field); - $used_fields[$field] = $field; - $global_index++; - } - echo "
"; - echo __("Fields associated with the object", "genericobject") . " : "; - echo $itemtype::getTypeName(); - echo "
" . __("Label", "genericobject") . "" . __("Name in DB", "genericobject") . "
"; - if ($haveCheckbox) { - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "
"; - echo ""; - echo "" . __('Check all') . "/"; - echo "" . __('Uncheck all') . ""; - echo Html::submit(__("Delete permanently"), [ - 'name' => 'delete', - ]); - echo "
"; - } - - $dropdownFields = self::dropdownFields("new_field", $itemtype, $used_fields); - - if ($dropdownFields) { - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "
" . __("Add new field", "genericobject") . ""; - echo $dropdownFields; - echo ""; - echo ""; - echo "
"; - } - - Html::closeForm(); - echo "
"; - } - /** * Method to set fields as read only, when the depend on some features * that are enabled @@ -324,57 +208,6 @@ public static function getFieldOptions($field, $itemtype = "") return $options; } - public static function displayFieldDefinition($target, $itemtype, $field, $index, $last = false) - { - /** - * @var array $CFG_GLPI - * @var array $GO_BLACKLIST_FIELDS - * @var array $GO_READONLY_FIELDS - */ - global $CFG_GLPI, $GO_BLACKLIST_FIELDS, $GO_READONLY_FIELDS; - - $readonly = in_array($field, $GO_READONLY_FIELDS); - $blacklist = in_array($field, $GO_BLACKLIST_FIELDS); - $options = self::getFieldOptions($field, $itemtype); - - echo ""; - echo ""; - if (!$blacklist && !$readonly) { - echo ""; - } else { - echo ""; - } - echo ""; - echo "" . __($options['name'], 'genericobject') . ""; - echo "" . $field . ""; - - echo ""; - if ((!$blacklist || $readonly) && $index > 1) { - Html::showSimpleForm( - $target, - $CFG_GLPI["root_doc"] . "/pics/deplier_up.png", - 'up', - ['field' => $field, 'action' => 'up', 'itemtype' => $itemtype], - $CFG_GLPI["root_doc"] . "/pics/deplier_up.png" - ); - } - echo ""; - - echo ""; - if ((!$blacklist || $readonly) && !$last) { - Html::showSimpleForm( - $target, - $CFG_GLPI["root_doc"] . "/pics/deplier_down.png", - 'down', - ['field' => $field, 'action' => 'down', 'itemtype' => $itemtype], - $CFG_GLPI["root_doc"] . "/pics/deplier_down.png" - ); - } - echo ""; - - echo ""; - } - /** * Add a new field in DB * @param string $table the table @@ -487,26 +320,6 @@ public static function deleteField($table, $field) } } - public static function deleteDisplayPreferences($table, $field) - { - - $pref = new DisplayPreference(); - $itemtype = getItemTypeForTable($table); - $searchopt = Search::getCleanedOptions($itemtype); - foreach ($searchopt as $num => $option) { - if ( - (isset($option['field']) && ($option['field'] == $field)) - || (isset($option['field']) && $option['linkfield'] == $field) - ) { - $pref->deleteByCriteria([ - 'itemtype' => $itemtype, - 'num' => $num - ]); - break; - } - } - } - /** * Change field order in DB * @params an array which contains the itemtype, the field to move and the action (up/down) diff --git a/inc/object.class.php b/inc/object.class.php index 8b3269a2..eacb9e68 100644 --- a/inc/object.class.php +++ b/inc/object.class.php @@ -93,58 +93,6 @@ public function getCloneRelations(): array ]; } - - /** - * Display information on treeview plugin - * - * @params itemtype, id, pic, url, name - * - * @return array - **/ - public static function showGenericObjectTreeview($params) - { - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - - if (array_key_exists($params['itemtype'], PluginGenericobjectType::getTypes())) { - $item = new $params['itemtype'](); - if ($item->getFromDB($params['id'])) { - $params['name'] = $item->fields["name"]; - $params['url'] = Plugin::getWebDir('genericobject') . "/front/object.form.php" . "?itemtype=" . $params['itemtype'] . "&id=" . $params['id']; - } - } - return $params; - } - - /** - * Display node search url on treeview plugin - * - * @params itemtype, id, pic, url, name - * - * @return array - **/ - public static function getParentNodeSearchUrl($params) - { - if (array_key_exists($params['itemtype'], PluginGenericobjectType::getTypes())) { - $item = new $params['itemtype'](); - $search = $item->rawSearchOptions(); - //get searchoption id for location_id - $index = ''; - foreach ($search as $key => $val) { - if (isset($val['table']) && $val['table'] === 'glpi_locations') { - $index = $key; - } - } - - $token = Session::getNewCSRFToken(); - - $params['searchurl'] = $params['itemtype']::getSearchURL() . "&is_deleted=0&criteria[0][field]=" . $index . "&criteria[0]" . "[searchtype]=equals&criteria[0][value]=" . $params['locations_id'] . "&search=Rechercher&start=0&_glpi_csrf_token=$token"; - return $params; - } - - return $params; - } - public static function install() { } @@ -322,30 +270,6 @@ public static function registerType() } } - public static function getMenuIcon($itemtype) - { - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - $itemtype_table = getTableForItemType($itemtype); - $itemtype_shortname = preg_replace("/^glpi_plugin_genericobject_/", "", $itemtype_table); - $itemtype_icons = glob( - GENERICOBJECT_PICS_PATH . '/' . getSingular($itemtype_shortname) . ".*" - ); - $finfo = new finfo(FILEINFO_MIME); - $icon_found = null; - foreach ($itemtype_icons as $icon) { - if (preg_match("|^image/|", $finfo->file($icon))) { - $icon_found = preg_replace("|^" . GLPI_ROOT . "|", "", $icon); - } - } - if (!is_null($icon_found)) { - $icon_path = $CFG_GLPI['root_doc'] . $icon_found; - } else { - $icon_path = Plugin::getWebDir('genericobject') . "/pics/default-icon.png"; - } - return ""; - } - public static function checkItemtypeRight($class, $right) { if (!is_null($class) and class_exists($class)) { @@ -357,7 +281,7 @@ public static function checkItemtypeRight($class, $right) } } - public static function canCreate() + public static function canCreate(): bool { $class = get_called_class(); //Datainjection : Don't understand why I need this trick : need to be investigated ! @@ -367,84 +291,30 @@ public static function canCreate() return static::checkItemtypeRight($class, CREATE); } - public static function canView() + public static function canView(): bool { $class = get_called_class(); return static::checkItemtypeRight($class, READ); } - public static function canUpdate() + public static function canUpdate(): bool { $class = get_called_class(); return static::checkItemtypeRight($class, UPDATE); } - public static function canDelete() + public static function canDelete(): bool { $class = get_called_class(); return static::checkItemtypeRight($class, DELETE); } - public static function canPurge() + public static function canPurge(): bool { $class = get_called_class(); return static::checkItemtypeRight($class, PURGE); } - public function defineTabs($options = []) - { - $tabs = []; - - $this->addDefaultFormTab($tabs); - - if (!$this->isNewItem()) { - // Register impact tab is enabled - if ($this->canUseImpact()) { - $this->addImpactTab($tabs, $options); - } - - if ($this->canUseNetworkPorts()) { - $this->addStandardTab('NetworkPort', $tabs, $options); - } - - if ($this->canUseItemDevice()) { - $this->addStandardTab('Item_Devices', $tabs, $options); - } - - if ($this->canUseInfocoms()) { - $this->addStandardTab('Infocom', $tabs, $options); - } - - if ($this->canUseContracts()) { - $this->addStandardTab('Contract_Item', $tabs, $options); - } - - if ($this->canUseDocuments()) { - $this->addStandardTab('Document_Item', $tabs, $options); - } - - if ($this->canUseTickets()) { - $this->addStandardTab('Ticket', $tabs, $options); - $this->addStandardTab('Item_Problem', $tabs, $options); - $this->addStandardTab('Change_Item', $tabs, $options); - } - - if ($this->canUseNotepad()) { - $this->addStandardTab('Notepad', $tabs, $options); - } - - if ($this->canBeReserved()) { - $this->addStandardTab('Reservation', $tabs, $options); - } - - if ($this->canUseHistory()) { - $this->addStandardTab('Log', $tabs, $options); - } - } - return $tabs; - } - - //------------------------ CAN methods -------------------------------------// public function getObjectTypeName() @@ -584,68 +454,6 @@ public function title() { } - - public function showForm($id, $options = [], $previsualisation = false) - { - if ($previsualisation) { - $canedit = true; - $this->getEmpty(); - } else { - if ($id > 0) { - $this->check($id, READ); - } else { - // Create item - $this->check(-1, CREATE); - $this->getEmpty(); - } - - $canedit = $this->can($id, UPDATE); - } - - if (isset($options['withtemplate']) && $options['withtemplate'] == 2) { - $template = "newcomp"; - } else if (isset($options['withtemplate']) && $options['withtemplate'] == 1) { - $template = "newtemplate"; - } else { - $template = false; - } - - $this->fields['id'] = $id; - $this->initForm($id, $options); - $this->showFormHeader($options); - - if ($previsualisation) { - echo "" . __("Object preview", "genericobject") . ": "; - $itemtype = $this->objecttype->fields['itemtype']; - echo $itemtype::getTypeName(); - echo ""; - } - - //Reset fields definition only to keep the itemtype ones - $GO_FIELDS = []; - plugin_genericobject_includeCommonFields(true); - PluginGenericobjectType::includeConstants($this->getObjectTypeName(), true); - - foreach (PluginGenericobjectSingletonObjectField::getInstance($this->objecttype->fields['itemtype']) as $field => $description) { - if ($field == "is_helpdesk_visible" && $id <= 0) { - $this->displayField($canedit, $field, 1, $template, $description); - } else { - $this->displayField($canedit, $field, $this->fields[$field], $template, $description); - } - } - $this->closeColumn(); - - if (!$previsualisation) { - $this->showFormButtons($options); - } else { - echo ""; - Html::closeForm(); - } - - return true; - } - - public static function getFieldsToHide() { return ['id', 'is_recursive', 'is_template', 'template_name', 'is_deleted', @@ -653,193 +461,6 @@ public static function getFieldsToHide() ]; } - - public function displayField($canedit, $name, $value, $template, $description = []) - { - $searchoption = PluginGenericobjectField::getFieldOptions($name, get_called_class()); - - if ( - !empty($searchoption) - && !in_array($name, self::getFieldsToHide()) - ) { - if (isset($searchoption['input_type']) && 'emptyspace' === $searchoption['input_type']) { - $searchoption['name'] = " "; - $description['Type'] = 'emptyspace'; - } - - $this->startColumn(); - echo ''; - - // Keep only main column type by removing anything that is preceded by a space (e.g. " unsigned") - // or a parenthesis (e.g. "(255)"). - echo '
'; - $column_type = preg_replace('/^([a-z]+)([ (].+)*$/', '$1', $description['Type']); - switch ($column_type) { - case "int": - $fk_table = getTableNameForForeignKeyField($name); - if ($fk_table != '') { - $itemtype = getItemTypeForTable($fk_table); - $dropdown = new $itemtype(); - $parameters = ['name' => $name, 'value' => $value, 'comments' => true]; - if ($dropdown->isEntityAssign()) { - $parameters["entity"] = $this->fields['entities_id']; - } - if ($dropdown->maybeRecursive()) { - $parameters['entity_sons'] = true; - } - if (isset($searchoption['condition'])) { - $parameters['condition'] = $searchoption['condition']; - } - if ($dropdown instanceof User) { - $parameters['entity'] = $this->fields["entities_id"]; - $parameters['right'] = 'all'; - User::dropdown($parameters); - } else { - Dropdown::show($itemtype, $parameters); - } - } else { - $min = $max = $step = 0; - if (isset($searchoption['min'])) { - $min = $searchoption['min']; - } else { - $min = 0; - } - if (isset($searchoption['max'])) { - $max = $searchoption['max']; - } else { - $max = 100; - } - if (isset($searchoption['step'])) { - $step = $searchoption['step']; - } else { - $step = 1; - } - Dropdown::showNumber( - $name, - [ - 'value' => $value, - 'min' => $min, - 'max' => $max, - 'step' => $step - ] - ); - } - break; - - case "tinyint": - Dropdown::showYesNo($name, $value); - break; - - case "varchar": - if (isset($searchoption['autoname']) && $searchoption['autoname']) { - $objectName = autoName( - $this->fields[$name], - $name, - ($template === "newcomp"), - $this->getType(), - $this->fields["entities_id"] - ); - } else { - $objectName = $this->fields[$name]; - } - echo Html::input( - $name, - [ - 'value' => $objectName, - ] - ); - break; - - case "longtext": - case "text": - case "mediumtext": - echo ""; - break; - - case "emptyspace": - echo ' '; - break; - - case "date": - Html::showDateField( - $name, - [ - 'value' => $value, - 'maybeempty' => true, - 'canedit' => true - ] - ); - break; - - case "datetime": - case "timestamp": - Html::showDateTimeField( - $name, - [ - 'value' => $value, - 'timestep' => true, - 'maybeempty' => true - ] - ); - break; - - case "float": - case 'decimal': - echo ""; - break; - - default: - echo ""; - break; - } - echo '
'; - $this->endColumn(); - } - } - - - - /** - * Add a new column - **/ - public function startColumn() - { - if ($this->cpt == 0) { - echo '
'; - echo '
'; - echo '
'; - echo '
'; - echo '
'; - } - echo '
'; - - $this->cpt++; - } - - - - /** - * End a column - **/ - public function endColumn() - { - echo "
"; - } - - - - /** - * Close a column - **/ - public function closeColumn() - { - if ($this->cpt > 0) { - echo "
"; - } - } - - public function prepareInputForAdd($input) { @@ -869,245 +490,6 @@ public function cleanDBonPurge() } } - /** - * Display object preview form - * @param PluginGenericobjectType $type the object type - */ - public static function showPrevisualisationForm(PluginGenericobjectType $type) - { - $itemtype = $type->fields['itemtype']; - $item = new $itemtype(); - - $right_name = PluginGenericobjectProfile::getProfileNameForItemtype( - $itemtype - ); - - if (Session::haveRight($right_name, READ) && Session::haveRight($right_name, CREATE)) { - $item->showForm(-1, [], true); - } else { - echo "
" . __( - "You must configure rights to enable the preview", - "genericobject" - ) . "
"; - } - } - - public function rawSearchOptions() - { - $datainjection_blacklisted = ['id', 'date_mod', 'entities_id', 'date_creation']; - $index_exceptions = ['name' => 1, 'id' => 2, 'completename' => 3, 'comment' => 16, 'date_mod' => 19, - 'entities_id' => 80, 'is_recursive' => 86, 'notepad' => 90, - 'date_creation' => 121 - ]; - - // Don't use indexes blacklisted by other item types in plugin DataInjection. - $plugin = new Plugin(); - if ( - $plugin->isActivated("datainjection") - && class_exists('PluginDatainjectionCommonInjectionLib') - ) { - $blacklisted_indexes = PluginDatainjectionCommonInjectionLib::getBlacklistedOptions( - get_called_class() //A class that extends PluginGenericobjectObject - ); - } else { - $blacklisted_indexes = []; - } - - $index = 3; - - $options = \Location::rawSearchOptionsToAdd(); - - $options[] = [ - 'id' => 'common', - 'name' => __('Characteristics'), - ]; - - $table = getTableForItemType(get_called_class()); - - // Prevent usage of reserved and blacklisted indexes - $taken_indexes = array_merge($index_exceptions, $blacklisted_indexes); - - plugin_genericobject_includeCommonFields(true); - - foreach (PluginGenericobjectSingletonObjectField::getInstance(get_called_class()) as $field => $values) { - $searchoption = PluginGenericobjectField::getFieldOptions( - $field, - $this->objecttype->fields['itemtype'] - ); - - if ($field == 'is_deleted') { - continue; - } - - //Some fields have fixed index values... - $currentindex = $index; - if (isset($index_exceptions[$field])) { - $currentindex = $index_exceptions[$field]; - } else { - //If this index is reserved, jump to next available one. - while (in_array($currentindex, $taken_indexes)) { - $currentindex++; - } - } - - $option = [ - 'id' => $currentindex, - ]; - $taken_indexes[] = $option['id']; - - $item = new $this->objecttype->fields['itemtype'](); - - //Table definition - //We test if it ends with s_id, in order to be sure that this pattern - //was found in a field that doesn't represent a foreign key - //for exemple a field called : is_identification - if (preg_match("/(s_id$|s_id_)/", $field)) { - $tmp = getTableNameForForeignKeyField($field); - } else { - $tmp = ''; - } - - if (preg_match("/(s_id_)/", $field)) { - $option['linkfield'] = $field; - } - - if ($tmp != '') { - $itemtype = getItemTypeForTable($tmp); - $tmpobj = new $itemtype(); - - //Set table - $option['table'] = $tmp; - - //Set field - if ($tmpobj instanceof CommonTreeDropdown) { - $option['field'] = 'completename'; - } else { - $option['field'] = 'name'; - } - } else { - $option['table'] = $table; - $option['field'] = $field; - } - - $option['name'] = $searchoption['name']; - - //Massive action or not - if (isset($searchoption['massiveaction'])) { - $option['massiveaction'] = $searchoption['massiveaction']; - } - - //Datainjection option - if (!in_array($field, $datainjection_blacklisted)) { - $option['injectable'] = 1; - } else { - $option['injectable'] = 0; - } - - //Field type - $column_type = preg_replace('/^([a-z]+)([ (].+)*$/', '$1', $values['Type']); - switch ($column_type) { - default: - case "varchar": - if ($field == 'name') { - $option['datatype'] = 'itemlink'; - $option['itemlink_type'] = get_called_class(); - $option['massiveaction'] = false; - // Enable autocomplete only for name, other fields may contains sensitive data - $option['autocomplete'] = true; - } else { - if (isset($searchoption['datatype']) && $searchoption['datatype'] == 'weblink') { - $option['datatype'] = 'weblink'; - } else { - $option['datatype'] = 'string'; - } - } - if ($item->canUsePluginDataInjection()) { - //Datainjection specific - $option['checktype'] = 'text'; - $option['displaytype'] = 'text'; - } - break; - case "tinyint": - $option['datatype'] = 'bool'; - if ($item->canUsePluginDataInjection()) { - //Datainjection specific - $option['displaytype'] = 'bool'; - } - break; - case "text": - case "longtext": - case "mediumtext": - $option['datatype'] = 'text'; - if ($item->canUsePluginDataInjection()) { - //Datainjection specific - $option['displaytype'] = 'multiline_text'; - } - break; - case "int": - if ($tmp != '') { - $option['datatype'] = 'dropdown'; - } else { - $option['datatype'] = 'integer'; - } - - if ($item->canUsePluginDataInjection()) { - if ($tmp != '') { - $option['displaytype'] = 'dropdown'; - $option['checktype'] = 'text'; - } else { - //Datainjection specific - $option['displaytype'] = 'dropdown_integer'; - $option['checktype'] = 'integer'; - } - } - break; - case "float": - case "decimal": - $option['datatype'] = $values['Type']; - if ($item->canUsePluginDataInjection()) { - //Datainjection specific - $option['display'] = 'text'; - $option['checktype'] = $values['Type']; - } - break; - case "date": - $option['datatype'] = 'date'; - if ($item->canUsePluginDataInjection()) { - //Datainjection specific - $option['displaytype'] = 'date'; - $option['checktype'] = 'date'; - } - break; - case "datetime": - case "timestamp": - $option['datatype'] = 'datetime'; - if ($item->canUsePluginDataInjection()) { - //Datainjection specific - $option['displaytype'] = 'date'; - $option['checktype'] = 'date'; - } - if ($field == 'date_mod') { - $option['massiveaction'] = false; - } - break; - } - - $options[] = $option; - - $index = $currentindex + 1; - } - - usort( - $options, - function ($a, $b) { - return ($a['id'] < $b['id']) ? -1 : 1; - } - ); - - return $options; - } - - //Datainjection specific methods public function isPrimaryType() { @@ -1207,78 +589,6 @@ public function transfer($new_entity) return true; } - /** - * @since version 0.85 - * - * @see CommonDBTM::showMassiveActionsSubForm() - **/ - public static function showMassiveActionsSubForm(MassiveAction $ma) - { - // KK TODO: check if MassiveAction itemtypes are concerned - //if (in_array ($options['itemtype'], $GENINVENTORYNUMBER_TYPES)) { - switch ($ma->getAction()) { - case "plugin_genericobject_transfer": - Dropdown::show('Entity', ['name' => 'new_entity']); - echo " "; - break; - default: - break; - } - //} - return true; - } - - // @codingStandardsIgnoreStart - public function plugin_genericobject_MassiveActionsProcess($data) - { - // @codingStandardsIgnoreEnd - /** @var DBmysql $DB */ - global $DB; - - switch ($data['action']) { - case 'plugin_genericobject_transfer': - $item = new $data['itemtype'](); - foreach ($data["item"] as $key => $val) { - if ($val == 1) { - $item->getFromDB($key); - $item->transfer($_POST['new_entity']); - } - } - break; - } - } - - public static function processMassiveActionsForOneItemtype( - MassiveAction $ma, - CommonDBTM $item, - array $ids - ) { - $results = [ - 'ok' => 0, - 'ko' => 0, - 'noright' => 0, - 'messages' => [] - ]; - - switch ($ma->action) { - case "plugin_genericobject_transfer": - foreach ($ma->items as $itemtype => $val) { - foreach ($val as $key => $item_id) { - $item = new $itemtype(); - $item->getFromDB($item_id); - $item->transfer($_POST['new_entity']); - $results['ok']++; - } - } - break; - - default: - break; - } - $ma->results = $results; - } - public static function getMenuContent() { $types = PluginGenericobjectType::getTypes(); diff --git a/inc/profile.class.php b/inc/profile.class.php index 988beb86..5969f107 100644 --- a/inc/profile.class.php +++ b/inc/profile.class.php @@ -36,143 +36,11 @@ public function cleanProfiles($id) $this->deleteByCriteria(['id' => $id]); } - public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) - { - switch ($item->getType()) { - case 'Profile': - return self::createTabEntry(__('Objects management', 'genericobject')); - case 'PluginGenericobjectType': - return self::createTabEntry(_n('Profile', 'Profiles', 2)); - } - - return ''; - } - - public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) - { - switch ($item->getType()) { - case 'Profile': - $profile = new self(); - $profile->showForm($item->getID()); - break; - case 'PluginGenericobjectType': - _log($item); - self::showForItemtype($item); - break; - } - return true; - } - - public static function showForItemtype($type) - { - if (!Session::haveRight("profile", READ)) { - return false; - } - self::installRights(); - $canedit = Session::haveRight("profile", UPDATE); - - echo ""; - echo ""; - $itemtype = $type->fields['itemtype']; - echo ""; - - echo ""; - echo ""; - - if ($canedit) { - echo ""; - echo ""; - } - - echo "
"; - echo __("Rights assignment") . ": "; - echo $itemtype::getTypeName(); - echo "
"; - foreach (getAllDataFromTable(getTableForItemtype("Profile")) as $profile) { - $prof = new Profile(); - $prof->getFromDB($profile['id']); - $rights = [ - [ - 'label' => $profile['name'], - 'itemtype' => $itemtype, - 'field' => self::getProfileNameForItemtype($itemtype), - 'html_field' => "profile_" . $profile['id'], - ] - ]; - $prof->displayRightsChoiceMatrix( - $rights - ); - } - - echo "
"; - echo ""; - echo "
"; - Html::closeForm(); - } - public static function getProfileNameForItemtype($itemtype) { return preg_replace("/^glpi_/", "", getTableForItemType($itemtype)); } - - /* profiles modification */ - public function showForm($profiles_id, $options = []) - { - if (!Session::haveRight("profile", READ)) { - return false; - } - $canedit = Session::haveRight("profile", UPDATE); - - //Ensure rights are defined in database - self::installRights(); - - $profile = new Profile(); - $profile->getFromDB($profiles_id); - - echo ""; - echo ""; - - $general_rights = self::getGeneralRights(); - - $profile->displayRightsChoiceMatrix( - $general_rights, - [ - 'canedit' => $canedit, - 'default_class' => 'tab_bg_2', - 'title' => __('General', 'genericobject') - ] - ); - - $types_rights = self::getTypesRights(); - - $title = __('Objects', 'genericobject'); - if (count($types_rights) == 0) { - $title .= ' ' . __("(No types defined yet)", "genericobject"); - } - - $profile->displayRightsChoiceMatrix( - $types_rights, - [ - 'canedit' => $canedit, - 'default_class' => 'tab_bg_2', - 'title' => $title - ] - ); - $profile->showLegend(); - if ($canedit) { - echo "
"; - echo Html::hidden('id', ['value' => $profiles_id]); - echo Html::submit(_sx('button', 'Save'), ['name' => 'update']); - echo "
\n"; - Html::closeForm(); - } - echo ""; - - return true; - } - public static function getProfileforItemtype($profiles_id, $itemtype) { $rights = ProfileRight::getProfileRights($profiles_id); @@ -243,7 +111,7 @@ public function saveProfileToDB($params) * Create rights for the current profile * @return void */ - public static function createFirstAccess() + public static function createFirstAccess() { if (!self::profileExists($_SESSION["glpiactiveprofile"]["id"], 'PluginGenericobjectType')) { self::createAccess($_SESSION["glpiactiveprofile"]["id"], "PluginGenericobjectType", true); diff --git a/inc/type.class.php b/inc/type.class.php index ed6d3790..52f3190d 100644 --- a/inc/type.class.php +++ b/inc/type.class.php @@ -87,78 +87,20 @@ public function getFromDBByType($itemtype) /** @var DBmysql $DB */ global $DB; - $query = "SELECT * FROM `" . getTableForItemType(__CLASS__) . "` " . - "WHERE `itemtype`='$itemtype'"; - $result = $DB->query($query); - if ($DB->numrows($result) > 0) { - $this->fields = $DB->fetchArray($result); + $query = [ + 'FROM' => getTableForItemType(__CLASS__), + 'WHERE' => ['itemtype' => $itemtype], + ]; + $result = $DB->request($query); + if ($result->numrows() > 0) { + foreach($result as $field) { + $this->fields = $field; + } } else { $this->getEmpty(); } } - - //------------------------------------ Tabs management ----------------------------------- - public function defineTabs($options = []) - { - $tabs = []; - $this->addStandardTab(__CLASS__, $tabs, $options); - return $tabs; - } - - public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) - { - if (!$withtemplate) { - switch ($item->getType()) { - case __CLASS__: - // Number of fields in database - $itemtype = $item->fields['itemtype']; - $nb_fields = 0; - if (class_exists($itemtype)) { - $obj = new $itemtype(); - $obj->getEmpty(); - $nb_fields = count($obj->fields); - } - - $tabs = [ - 1 => __("Main"), - 3 => self::createTabEntry(_n("Field", "Fields", Session::getPluralNumber()), $nb_fields), - 5 => __("Preview") - ]; - if ($item->canUseDirectConnections()) { - $tabs[7] = __("Associated element"); - } - return $tabs; - } - } - return ''; - } - - public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) - { - if ($item->getType() == __CLASS__) { - switch ($tabnum) { - case 1: - $item->showBehaviorForm($item->getID()); - break; - - case 3: - PluginGenericobjectField::showObjectFieldsForm($item->getID()); - break; - - case 5: - PluginGenericobjectObject::showPrevisualisationForm($item); - break; - - case 6: - PluginGenericobjectProfile::showForItemtype($item); - break; - } - } - return true; - } - //------------------------------------- End tabs management ------------------------------ - //------------------------------------- Framework hooks ---------------------------------- public function prepareInputForAdd($input) { @@ -419,141 +361,6 @@ public function post_deleteItem() // @codingStandardsIgnoreEnd } - public function rawSearchOptions() - { - $sopt = []; - - $sopt[] = [ - 'id' => 'common', - 'name' => __("Objects management", "genericobject"), - ]; - - $sopt[] = [ - 'id' => 1, - 'table' => $this->getTable(), - 'field' => 'name', - 'name' => __('Model'), - 'datatype' => 'itemlink', - 'autocomplete' => true, - ]; - - $sopt[] = [ - 'id' => 5, - 'table' => $this->getTable(), - 'field' => 'is_active', - 'name' => __('Active'), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 6, - 'table' => $this->getTable(), - 'field' => 'use_tickets', - 'name' => __('Associable to a ticket'), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 9, - 'table' => $this->getTable(), - 'field' => 'use_history', - 'name' => _sx('button', 'Use') . ' ' . __('Historical'), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 13, - 'table' => $this->getTable(), - 'field' => 'use_infocoms', - 'name' => _sx('button', 'Use') . ' ' . __('Financial and administratives information'), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 14, - 'table' => $this->getTable(), - 'field' => 'use_documents', - 'name' => _sx('button', 'Use') . ' ' . _n('Document', 'Documents', 2), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 15, - 'table' => $this->getTable(), - 'field' => 'use_loans', - 'name' => _sx('button', 'Use') . ' ' . _n('Reservation', 'Reservations', 2), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 16, - 'table' => $this->getTable(), - 'field' => 'use_contracts', - 'name' => _sx('button', 'Use') . ' ' . _n('Contract', 'Contracts', 2), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 17, - 'table' => $this->getTable(), - 'field' => 'use_unicity', - 'name' => _sx('button', 'Use') . ' ' . __('Fields unicity'), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 18, - 'table' => $this->getTable(), - 'field' => 'use_global_search', - 'name' => __('Global search'), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 19, - 'table' => 'glpi_plugin_genericobject_typefamilies', - 'field' => 'name', - 'name' => __('Family of type of objects', 'genericobject'), - 'datatype' => 'dropdown', - ]; - - $sopt[] = [ - 'id' => 20, - 'table' => $this->getTable(), - 'field' => 'use_projects', - 'name' => _n('Project', 'Projects', 2), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 21, - 'table' => $this->getTable(), - 'field' => 'date_mod', - 'name' => __('Last update'), - 'datatype' => 'datetime', - 'massiveaction' => false, - ]; - - $sopt[] = [ - 'id' => 22, - 'table' => $this->getTable(), - 'field' => 'use_itemdevices', - 'name' => _sx('button', 'Use') . ' ' . _n('Component', 'Components', 2), - 'datatype' => 'bool', - ]; - - $sopt[] = [ - 'id' => 121, - 'table' => $this->getTable(), - 'field' => 'date_creation', - 'name' => __('Creation date'), - 'datatype' => 'datetime', - 'massiveaction' => false, - ]; - - return $sopt; - } - /** * Define name of type to display in menu * @@ -566,389 +373,6 @@ public static function getMenuName() //------------------------------------- End Framework hooks ----------------------------- - //------------------------------------- Forms ------------------------------------------- - public function showForm($ID, $options = []) - { - - if ($ID > 0) { - $this->check($ID, READ); - } else { - // Create item - $this->check(-1, CREATE); - $this->getEmpty(); - } - - $this->initForm($ID); - - $item = new self(); - $item->showBehaviorForm($ID); - - return true; - } - - public function showBehaviorForm($ID, $options = []) - { - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - - if ($ID > 0) { - $this->check($ID, READ); - } else { - // Create item - $this->check($ID, CREATE); - $use_cache = false; - $this->getEmpty(); - } - - $this->fields['id'] = $ID; - - $right_name = PluginGenericobjectProfile::getProfileNameForItemtype( - __CLASS__ - ); - - $canedit = Session::haveRight($right_name, UPDATE); - - self::includeLocales($this->fields["name"]); - self::includeConstants($this->fields["name"]); - - $this->showFormHeader($options); - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - echo ""; - - if (!$this->isNewID($ID)) { - $canedit = $this->can($ID, CREATE); - echo ""; - - $use = [ - "use_recursivity" => __("Child entities"), - "use_tickets" => __("Assistance"), - "use_deleted" => __("Item in the dustbin"), - "use_notepad" => _n('Note', 'Notes', 2), - "use_history" => __("Historical"), - "use_template" => __("Templates"), - "use_infocoms" => __("Financial and administratives information"), - "use_contracts" => _n("Contract", "Contracts", 2), - "use_documents" => _n("Document", "Documents", 2), - "use_loans" => _n("Reservation", "Reservations", 2), - // Disable unicity feature; see #16 - // Related code : search for #16 - "use_unicity" => __("Fields unicity"), - "use_global_search" => __("Global search"), - "use_projects" => _n("Project", "Projects", 2), - "use_network_ports" => __("Network connections", "genericobject"), - "use_itemdevices" => _n('Component', 'Components', 2), - "use_impact" => Impact::getTypeName(), - ]; - - $plugins = [ - "use_plugin_datainjection" => __("injection file plugin", "genericobject"), - //"use_plugin_pdf" => __("PDF plugin", "genericobject"), - "use_plugin_geninventorynumber" => __("geninventorynumber plugin", "genericobject"), - "use_plugin_order" => __("order plugin", "genericobject"), - "use_plugin_uninstall" => __("item's uninstallation plugin", "genericobject"), - "use_plugin_simcard" => __("simcard plugin", "genericobject"), - "use_plugin_treeview" => __("treeview plugin", "genericobject"), - ]; - - $plugin = new Plugin(); - $odd = 0; - foreach ($use as $right => $label) { - if (!$odd) { - echo ""; - } - echo ""; - echo ""; - if ($odd == 1) { - $odd = 0; - echo ""; - } else { - $odd++; - } - } - if ($odd != 0) { - echo ""; - } - - echo ""; - - echo ''; - echo ""; - echo ''; - - echo ''; - echo ""; - echo ""; - echo ''; - - echo ""; - $odd = 0; - foreach ($plugins as $right => $label) { - if (!$odd) { - echo ""; - } - echo ""; - echo ""; - if ($odd == 1) { - $odd = 0; - echo ""; - } else { - $odd++; - } - } - if ($odd != 0) { - echo ""; - } - } - - $this->showFormButtons($options); - } - - /** - * - * Show a form with a button to regenerate all files - * @since 2.2.0 - * @param $ID type ID - * @return void - */ - public function showFilesForm() - { - echo ""; - echo "
"; - echo "
" . __("Internal identifier", "genericobject") . ""; - if (!$ID) { - echo Html::input( - 'name', - [ - 'value' => $this->fields['name'], - ] - ); - } else { - echo ""; - echo $this->fields["name"]; - } - - echo "
" . __("Label") . ""; - if ($ID) { - $itemtype = $this->fields["itemtype"]; - echo $itemtype::getTypeName(); - } - echo "" . __("Comments") . " :
" . __("Active") . ""; - if (!$ID) { - echo __("No"); - } else { - Dropdown::showYesNo("is_active", $this->fields["is_active"]); - } - echo "
" . __("Family of type of objects", 'genericobject') . ""; - PluginGenericobjectTypeFamily::dropdown([ - 'value' => $this->fields["plugin_genericobject_typefamilies_id"] - ]); - echo "
"; - echo __("Behaviour", "genericobject"); - echo "
" . _sx('button', 'Use') . " " . $label . ""; - - switch ($right) { - case 'use_deleted': - Html::showCheckbox(['name' => $right, - 'checked' => $this->canBeDeleted() - ]); - break; - - case 'use_recursivity': - Html::showCheckbox(['name' => $right, - 'value' => $this->canBeRecursive(), - 'checked' => $this->canBeRecursive() - ]); - break; - - case 'use_notes': - Html::showCheckbox(['name' => $right, - 'checked' => $this->canUseNotepad() - ]); - break; - - case 'use_template': - Html::showCheckbox(['name' => $right, - 'checked' => $this->canUseTemplate() - ]); - break; - - case 'use_impact': - Html::showCheckbox([ - 'name' => $right, - 'checked' => Impact::isEnabled($this->fields['itemtype']) - ]); - break; - - default: - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - break; - } - echo "
"; - echo __("Icon (impact analysis)", "genericobject"); - echo "
"; - $src = $this->getImpactIconUrl() ?? $CFG_GLPI["root_doc"] . "/pics/impact/default.png"; - echo ""; - echo "
"; - echo Html::file([ - 'name' => "impact_icon", - 'onlyimages' => true, - ]); - echo "
"; - echo _n("Plugin", "Plugins", 2); - echo "
" . _sx('button', 'Use') . " " . $label . ""; - switch ($right) { - case 'use_plugin_datainjection': - if ($plugin->isActivated('datainjection')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - break; - - case 'use_plugin_pdf': - if ($plugin->isActivated('pdf')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - break; - - case 'use_plugin_order': - if ($plugin->isActivated('order')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - break; - - case 'use_plugin_uninstall': - if ($plugin->isActivated('uninstall')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - break; - - case 'use_plugin_simcard': - if ($plugin->isActivated('simcard')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - break; - case 'use_plugin_treeview': - if ($plugin->isActivated('treeview')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - - break; - case 'use_plugin_geninventorynumber': - if ($plugin->isActivated('geninventorynumber')) { - Html::showCheckbox(['name' => $right, - 'checked' => $this->fields[$right] - ]); - } else { - echo Dropdown::EMPTY_VALUE; - echo "\n"; - } - break; - } - echo "
"; - echo ""; - echo "
"; - echo ""; - echo ""; - echo "
"; - Html::closeForm(); - } - - public function showLinkedTypesForm() - { - /** @var array $GO_LINKED_TYPES */ - global $GO_LINKED_TYPES; - - $this->showFormHeader(); - echo ""; - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - $this->showFormButtons(['candel' => false, 'canadd' => false]); - Html::closeForm(); - } - //------------------------------------- End Forms -------------------------------------- - /** * Create an object, it's table, files and rights * @@ -2847,4 +2271,5 @@ public function getImpactIconUrl($full = true): ?string return Plugin::getWebDir('genericobject', $full) . "/front/getimpacticon.php?itemtype=" . $this->fields['itemtype']; } + } diff --git a/inc/typefamily.class.php b/inc/typefamily.class.php index 87e9cb97..82bfbb9d 100644 --- a/inc/typefamily.class.php +++ b/inc/typefamily.class.php @@ -62,7 +62,7 @@ public static function install(Migration $migration) KEY `date_mod` (`date_mod`), KEY `date_creation` (`date_creation`) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die($DB->error()); + $DB->doQuery($query) or die($DB->error()); } } @@ -74,41 +74,7 @@ public static function uninstall() $table = getTableForItemType(__CLASS__); if ($DB->tableExists($table)) { $query = "DROP TABLE IF EXISTS `$table`"; - $DB->query($query) or die($DB->error()); + $DB->doQuery($query) or die($DB->error()); } } - - public static function getFamilies() - { - /** @var DBmysql $DB */ - global $DB; - - $query = "SELECT f.id as id, f.name as name, t.itemtype as itemtype - FROM glpi_plugin_genericobject_typefamilies as f - LEFT JOIN glpi_plugin_genericobject_types AS t - ON (f.id = t.plugin_genericobject_typefamilies_id) - WHERE t.id IN (SELECT DISTINCT `id` - FROM glpi_plugin_genericobject_types - WHERE is_active=1)"; - $families = []; - foreach ($DB->request($query) as $fam) { - $itemtype = $fam['itemtype']; - if ($itemtype::canCreate()) { - $families[$fam['id']] = $fam['name']; - } - } - return $families; - } - - - public static function getItemtypesByFamily($families_id) - { - return getAllDataFromTable( - 'glpi_plugin_genericobject_types', - [ - 'plugin_genericobject_typefamilies_id' => $families_id, - 'is_active' => 1 - ] + ['ORDER' => 'name'] - ); - } } diff --git a/setup.php b/setup.php index 93b0f56b..7076ff08 100644 --- a/setup.php +++ b/setup.php @@ -28,12 +28,12 @@ * ------------------------------------------------------------------------- */ -define('PLUGIN_GENERICOBJECT_VERSION', '2.14.14'); +define('PLUGIN_GENERICOBJECT_VERSION', '3.0.0'); // Minimal GLPI version, inclusive -define("PLUGIN_GENERICOBJECT_MIN_GLPI", "10.0.0"); +define("PLUGIN_GENERICOBJECT_MIN_GLPI", "11.0.0"); // Maximum GLPI version, exclusive -define("PLUGIN_GENERICOBJECT_MAX_GLPI", "10.0.99"); +define("PLUGIN_GENERICOBJECT_MAX_GLPI", "11.0.99"); if (!defined("GENERICOBJECT_DIR")) { define("GENERICOBJECT_DIR", Plugin::getPhpDir("genericobject")); @@ -144,18 +144,6 @@ function plugin_init_genericobject() //register class PluginTreeviewConfig::registerType($itemtype); $PLUGIN_HOOKS['treeview'][$itemtype] = Plugin::getWebDir('genericobject') . '/pics/default-icon16.png'; - - //add hook for overload item show form url - $PLUGIN_HOOKS['treeview_params']['genericobject'] = [ - 'PluginGenericobjectObject', - 'showGenericObjectTreeview' - ]; - - //add hook for overload search form url of itemtype - $PLUGIN_HOOKS['treeview_search_url_parent_node']['genericobject'] = [ - 'PluginGenericobjectObject', - 'getParentNodeSearchUrl' - ]; } } } @@ -166,34 +154,13 @@ function plugin_init_genericobject() ]; plugin_genericobject_includeCommonFields(); - $PLUGIN_HOOKS['use_massive_action']['genericobject'] = 1; - - // add css styles - $PLUGIN_HOOKS['add_css']['genericobject'] = [ - "css/styles.css" - ]; - - // Display a menu entry ? - $PLUGIN_HOOKS['menu_toadd']['genericobject'] = [ - 'config' => 'PluginGenericobjectType', - 'assets' => 'PluginGenericobjectObject' - ]; // Config page if (Session::haveRight('config', READ)) { - $PLUGIN_HOOKS['config_page']['genericobject'] = 'front/type.php'; + $PLUGIN_HOOKS['config_page']['genericobject'] = 'front/eol_info.php'; } - $PLUGIN_HOOKS['assign_to_ticket']['genericobject'] = true; - $PLUGIN_HOOKS['use_massive_action']['genericobject'] = 1; - $PLUGIN_HOOKS['post_init']['genericobject'] = 'plugin_post_init_genericobject'; - $PLUGIN_HOOKS['plugin_datainjection_populate']['genericobject'] = "plugin_datainjection_populate_genericobject"; - - $PLUGIN_HOOKS['formcreator_get_glpi_object_types']['genericobject'] = [ - PluginGenericobjectType::getType(), - 'getTypesForFormcreator' - ]; // Add every genericobject item's to the list of itemtypes for which the // impact analysis can be enabled @@ -236,7 +203,7 @@ function plugin_post_init_genericobject() function plugin_version_genericobject() { return [ - 'name' => __("Objects management", "genericobject"), + 'name' => __("Objects management (Migration Only)", "genericobject"), 'version' => PLUGIN_GENERICOBJECT_VERSION, 'author' => "Teclib' & siprossii", 'homepage' => 'https://github.com/pluginsGLPI/genericobject', @@ -251,17 +218,6 @@ function plugin_version_genericobject() ]; } - -function plugin_genericobject_haveTypeRight($itemtype, $right) -{ - switch ($itemtype) { - case 'PluginGenericobjectType': - return Session::haveRight("config", $right); - default: - return Session::haveRight($itemtype, $right); - } -} - function plugin_genericobject_includeCommonFields($force = false) { $includes = [ diff --git a/templates/eol_info.html.twig b/templates/eol_info.html.twig new file mode 100644 index 00000000..6dd23ec2 --- /dev/null +++ b/templates/eol_info.html.twig @@ -0,0 +1,117 @@ +
+
+
+
+ {# Header with icon and title #} +
+
+
+ +
+
+

+ {{ __('GenericObject End of Life Notice', 'genericobject') }} +

+

+ {{ __('Migration guidance and information', 'genericobject') }} +

+
+
+
+ + {# Body #} +
+ {# EOL Notice Banner #} +
+
+ +
+
{{ __('Important Notice', 'genericobject') }}
+

+ {{ __("GenericObject v%s has reached End of Life (EOL). This version only provides migration assistance to help you switch to GLPI 11's asset definition", 'formcreator')|format(plugin_version) }} +

+
+
+
+ + {# Migration Information Grid #} +
+
+
+
+
+ + {{ __('What changed?', 'genericobject') }} +
+
+
+
    +
  • + + {{ __('GLPI 11 now has native custom asset creation capabilities', 'genericobject') }} +
  • +
  • + + {{ __('All Genericobject features are available in GLPI core', 'genericobject') }} +
  • +
  • + + {{ __('Better integration with GLPI workflows', 'genericobject') }} +
  • +
  • + + {{ __('Improved performance and security', 'genericobject') }} +
  • +
+
+
+
+ +
+
+
+
+ + {{ __('Next steps', 'genericobject') }} +
+
+
+
    +
  • + + {{ __('Review your existing genericobject assets', 'genericobject') }} +
  • +
  • + + {{ __('Migrate to GLPI 11 native asset definition', 'genericobject') }} +
  • +
  • + + {{ __('Test the new asset system', 'genericobject') }} +
  • +
  • + + {{ __('Uninstall GenericObject plugin when ready', 'genericobject') }} +
  • +
+
+
+
+
+ + {# Action buttons #} + + +
+
+
+
+
diff --git a/templates/migration_status.html.twig b/templates/migration_status.html.twig new file mode 100644 index 00000000..657d00ea --- /dev/null +++ b/templates/migration_status.html.twig @@ -0,0 +1,299 @@ +{# + # --------------------------------------------------------------------- + # + # GLPI - Gestionnaire Libre de Parc Informatique + # + # http://glpi-project.org + # + # @copyright 2015-2025 Teclib' and contributors. + # @licence https://www.gnu.org/licenses/gpl-3.0.html + # + # --------------------------------------------------------------------- + # + # LICENSE + # + # This file is part of GLPI. + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 3 of the License, or + # (at your option) any later version. + # + # This program 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 General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + # + # --------------------------------------------------------------------- + #} + +{% import 'components/form/fields_macros.html.twig' as fields %} + +{# Page Header #} +
+
+ +
+
+

{{ __('GenericObject Migration Status', 'genericobject') }}

+

{{ __('End of Life migration tool for GLPI 11', 'genericobject') }}

+
+
+
+
+ {# EOL Warning Banner #} +
+
+ +
+
{{ __('End of Life Notice', 'genericobject') }}
+

+ {{ __('GenericObject v3.0.0 is an End-of-Life version. All custom asset creation functionality has been moved to GLPI 11 native asset definition.', 'genericobject') }} +

+
+
+
+ + {# Migration Status Card #} +
+
+

+ + {{ __('Migration Status', 'genericobject') }} +

+
+
+ {# Set pagination variables #} + {% set start = _get.start|default(0) %} + {% set limit = _get.limit|default(user_pref('list_limit')) %} + {% set total_count = genericobject_types|length %} + + {# Calculate pagination #} + {% set paginated_types = genericobject_types|slice(start, limit) %} + + {# Display pagination controls at the top #} + {{ include('components/pager.html.twig', { + 'count': total_count, + 'start': start, + 'limit': limit, + 'href': 'migration_status.php', + 'short_display': true, + 'no_limit_display': false + }) }} + +
+ {% for key, genericobject_type in paginated_types %} +
+
+ {% if customassets[genericobject_type.name] and customassets[genericobject_type.name].icon %} + + {% else %} + + {% endif %} +

+ {{ genericobject_type.name }} +

+
+ +
+ {% if customassets[genericobject_type.name] %} +
+ + {{ __('Migrated', 'genericobject') }} +
+
+ {{ __('Items Migrated:', 'genericobject') }} + + {{ customassets[genericobject_type.name].items }} + +
+ + {% else %} +
+ + {{ __('Not Migrated', 'genericobject') }} +
+
+ {{ __('Items Migrated:', 'genericobject') }} + 0 +
+
+ +
+ {% endif %} +
+
+ {% endfor %} +
+ + {# Display pagination controls at the bottom #} + {{ include('components/pager.html.twig', { + 'count': total_count, + 'start': start, + 'limit': limit, + 'href': 'migration_status.php', + 'short_display': false, + 'no_limit_display': false + }) }} +
+
+ +
+
+

+ + {{ __('How to Migrate', 'genericobject') }} +

+
+
+
+
+ +
+

{{ __('Command Line Migration Required', 'genericobject') }}

+

+ {{ __('For optimal performance and reliability, the migration must be performed using the command line:', 'genericobject') }} +

+
+
+ php bin/console migration:genericobject_plugin_to_core + +
+
+ + {{ __('Run this command from your GLPI root directory', 'genericobject') }} + +
+
+
+ +
+
+ +
+

{{ __('Migration Process', 'genericobject') }}

+
    +
  • {{ __('Form structure and fields will be converted', 'genericobject') }}
  • +
  • {{ __('Form categories will be preserved', 'genericobject') }}
  • +
  • {{ __('Access control rules will be migrated', 'genericobject') }}
  • +
  • {{ __('Form submissions will be preserved', 'genericobject') }}
  • +
  • {{ __('Complex validations may need manual recreation', 'genericobject') }}
  • +
+
+ + + {{ __('Note: Migration status detection is based on data presence and may not be 100% accurate. Please verify manually after running the migration command.', 'genericobject') }} + +
+
+
+
+ +
+
+ + {# Next Steps Card #} +
+
+

+ + {{ __('Next Steps', 'genericobject') }} +

+
+
+
+
+ +
+

{{ __('After Migration', 'genericobject') }}

+
    +
  • + + {{ __('Review converted forms in GLPI 11', 'genericobject') }} +
  • +
  • + + {{ __('Test form access permissions', 'genericobject') }} +
  • +
+
+
+
+ +
+

{{ __('Recommendations', 'genericobject') }}

+
    +
  • + + {{ __('Train users on GLPI 11 native forms', 'genericobject') }} +
  • +
  • + + {{ __('Update internal documentation', 'genericobject') }} +
  • +
+
+
+
+
+
+
+
+ + From 902c18a8742f1c6cba786159b5953ced23e4024c Mon Sep 17 00:00:00 2001 From: MyuTsu Date: Thu, 18 Sep 2025 11:29:26 +0200 Subject: [PATCH 02/15] eol --- css/styles.css | 91 -- hook.php | 34 - inc/field.class.php | 267 ----- inc/object.class.php | 609 +----------- inc/object_item.class.php | 138 --- inc/profile.class.php | 225 ----- inc/type.class.php | 1374 +------------------------- index.php | 71 +- objects/front.form.tpl | 35 - objects/front.tpl | 38 - objects/generic.class.tpl | 45 - objects/generic.dropdown.class.tpl | 33 - objects/generic.form.tpl | 35 - objects/locale.tpl | 29 - objects/object_item.class.tpl | 44 - objects/objectinjection.class.tpl | 91 -- setup.php | 89 -- templates/migration_status.html.twig | 14 +- 18 files changed, 28 insertions(+), 3234 deletions(-) delete mode 100644 css/styles.css delete mode 100644 inc/object_item.class.php delete mode 100644 objects/front.form.tpl delete mode 100644 objects/front.tpl delete mode 100644 objects/generic.class.tpl delete mode 100644 objects/generic.dropdown.class.tpl delete mode 100644 objects/generic.form.tpl delete mode 100644 objects/locale.tpl delete mode 100644 objects/object_item.class.tpl delete mode 100644 objects/objectinjection.class.tpl diff --git a/css/styles.css b/css/styles.css deleted file mode 100644 index 13117607..00000000 --- a/css/styles.css +++ /dev/null @@ -1,91 +0,0 @@ -/*! - * ------------------------------------------------------------------------- - * GenericObject plugin for GLPI - * ------------------------------------------------------------------------- - * - * LICENSE - * - * This file is part of GenericObject. - * - * GenericObject is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GenericObject 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GenericObject. If not, see . - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -/* - * Menu entry wrapper - */ -.genericobject_menu_wrapper { - display: block; - position: relative; - margin: 0; - padding: 0; -} - -/* - * Icon positionning - */ -.genericobject_menu_icon { - height: 16px; - width: 16px; - vertical-align: middle; - display: inline-block; -} -.icon_preview { - height: 32px; - width: 32px; -} - -.icon_preview > .genericobject_menu_icon { - display: block; - margin: 0 auto; - height: initial; - width: initial; - max-height: 32px; - max-width: 32px; -} - -.genericobject_menu_text { - padding-left: 5px; - margin: 0; - display: inline-block; -} - - -/* - * Fields Form - */ - -.genericobject_fields.add_new { - width: 80%; -} - -.genericobject_fields.add_new td.label { - width: 20%; -} - -.genericobject_fields.add_new td.dropdown { - width: 100%; -} - -/* - * Type's Profile tab : specific alignment - */ - -.genericobject_type_profiles tr > td { - width : 10%; -} diff --git a/hook.php b/hook.php index 23f6022c..bc50802d 100644 --- a/hook.php +++ b/hook.php @@ -28,38 +28,6 @@ * ------------------------------------------------------------------------- */ -// Define Dropdown tables to be manage in GLPI : -function plugin_genericobject_getDropdown() -{ - $dropdowns = ['PluginGenericobjectTypeFamily' => PluginGenericobjectTypeFamily::getTypeName(2)]; - - $plugin = new Plugin(); - if ($plugin->isActivated("genericobject")) { - foreach (PluginGenericobjectType::getTypes() as $type) { - //_log($idx, var_export($type, true)); - $itemtype = $type['itemtype']; - PluginGenericobjectType::registerOneType($itemtype); - foreach (PluginGenericobjectType::getDropdownForItemtype($itemtype) as $table) { - $dropdown_itemtype = getItemTypeForTable($table); - if (class_exists($dropdown_itemtype)) { - $dropdowns[$dropdown_itemtype] = $dropdown_itemtype::getTypeName(); - } - } - } - } - return $dropdowns; -} - -function plugin_uninstall_addUninstallTypes($uninstal_types = []) -{ - foreach (PluginGenericobjectType::getTypes() as $tmp => $type) { - if ($type["use_plugin_uninstall"]) { - $uninstal_types[] = $type["itemtype"]; - } - } - return $uninstal_types; -} - //----------------------- INSTALL / UNINSTALL FUNCTION -------------------------------// /** @@ -109,8 +77,6 @@ function plugin_genericobject_install() //Init plugin & types plugin_init_genericobject(); - //Init profiles - PluginGenericobjectProfile::changeProfile(); return true; } diff --git a/inc/field.class.php b/inc/field.class.php index ba1d8cbc..b0cba064 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -30,36 +30,6 @@ class PluginGenericobjectField extends CommonDBTM { - /** - * Method to set fields as read only, when the depend on some features - * that are enabled - * @since 0.85+2.4.0 - */ - public static function addReadOnlyFields(PluginGenericobjectType $type) - { - /** @var array $GO_READONLY_FIELDS */ - global $GO_READONLY_FIELDS; - - if ($type->canBeReserved()) { - $GO_READONLY_FIELDS[] = 'users_id'; - $GO_READONLY_FIELDS[] = 'locations_id'; - } - - if ($type->canUseGlobalSearch()) { - $GO_READONLY_FIELDS[] = 'serial'; - $GO_READONLY_FIELDS[] = 'otherserial'; - $GO_READONLY_FIELDS[] = 'locations_id'; - $GO_READONLY_FIELDS[] = 'states_id'; - $GO_READONLY_FIELDS[] = 'users_id'; - $GO_READONLY_FIELDS[] = 'groups_id'; - $GO_READONLY_FIELDS[] = 'manufacturers_id'; - $GO_READONLY_FIELDS[] = 'users_id_tech'; - } - - if ($type->canUseItemDevice()) { - $GO_READONLY_FIELDS[] = 'locations_id'; - } - } /** * Get the name of the field, as defined in a constant file * The name may be the same, or not depending if it's an isolated dropdown or not @@ -108,69 +78,6 @@ public static function getFieldName($field, $itemtype, $options, $remove_prefix return $field; } - /** - * - * Display a dropdown with all available fields for an itemtype - * @since - * @param string $name the dropdown name - * @param string $itemtype the itemtype - * @param array $used an array which contains all fields already added - * - * @return int the dropdown random ID - */ - public static function dropdownFields($name, $itemtype, $used = []) - { - /** @var array $GO_FIELDS */ - global $GO_FIELDS; - - $dropdown_types = []; - foreach ($GO_FIELDS as $field => $values) { - $message = ""; - $field_options = []; - $field = self::getFieldName($field, $itemtype, $values, false); - if (!in_array($field, $used)) { - if (!isset($dropdown_types[$field])) { - //Global management : - //meaning that a dropdown can be useful in all types (for example type, model, etc.) - if (isset($values['input_type']) && $values['input_type'] == 'dropdown') { - if (isset($values['entities_id'])) { - $field_options[] = __("Entity") . " : " . Dropdown::getYesNo($values['entities_id']); - if ($values['entities_id']) { - if (isset($values['is_recursive'])) { - $field_options[] = __("Child entities") . " : " . Dropdown::getYesNo($values['is_recursive']); - } - } - } else { - $field_options[] = __("Entity") . " : " . Dropdown::getYesNo(0); - } - if (isset($values['is_tree'])) { - $field_options[] = __("tree structure") . " : " . Dropdown::getYesNo($values['is_tree']); - } else { - $field_options[] = __("tree structure") . " : " . Dropdown::getYesNo(0); - } - //if (isset($values['isolated']) and $values['isolated']) { - // $field_options[] = __("Isolated") . " : ". Dropdown::getYesNo($values['isolated']); - //} else { - // $field_options[] = __("Isolated") . " : ". Dropdown::getYesNo(0); - //} - } - if (!empty($field_options)) { - $message = "(" . trim(implode(", ", $field_options)) . ")"; - } - } - $dropdown_types[$field] = $values['name'] . " " . $message; - } - } - - // Don't show dropdown empty - if (empty($dropdown_types)) { - return ''; - } - - ksort($dropdown_types); - return Dropdown::showFromArray($name, $dropdown_types, ['display' => false]); - } - /** * * Get field's options defined in constant files. @@ -208,180 +115,6 @@ public static function getFieldOptions($field, $itemtype = "") return $options; } - /** - * Add a new field in DB - * @param string $table the table - * @param string $field the field to delete - * @return void - */ - public static function addNewField($table, $field, $after = false) - { - /** @var DBmysql $DB */ - global $DB; - - _log("add", $field, "from", $table); - $itemtype = getItemTypeForTable($table); - if (!$DB->fieldExists($table, $field, false)) { - $options = self::getFieldOptions($field, $itemtype); - $query = "ALTER TABLE `$table` ADD `$field` "; - switch ($options['input_type']) { - case 'dropdown_yesno': - case 'dropdown_global': - case 'bool': - $query .= "TINYINT NOT NULL DEFAULT '0'"; - break; - case 'emptyspace': - case 'text': - $query .= "VARCHAR ( 255 ) NOT NULL DEFAULT ''"; - break; - case 'multitext': - $query .= "TEXT NULL"; - break; - case 'dropdown': - $query .= "INT unsigned NOT NULL DEFAULT '0'"; - break; - case 'integer': - $query .= "INT NOT NULL DEFAULT '0'"; - break; - case 'date': - $query .= "DATE DEFAULT NULL"; - break; - case 'datetime': - $query .= "TIMESTAMP NULL DEFAULT NULL"; - break; - case 'float': - $query .= "FLOAT NOT NULL DEFAULT '0'"; - break; - case 'decimal': - $query .= "DECIMAL(20,4) NOT NULL DEFAULT '0.0000'"; - break; - } - if ($after) { - $query .= " AFTER `$after`"; - } - $DB->query($query); - - //Reload list of fields for this itemtype in the singleton - - $recursive = $entity_assign = $tree = false; - - $table = getTableNameForForeignKeyField($field); - - if ($table != '' && !$DB->tableExists($table)) { - //Cannot use standard methods because class doesn't exists yet ! - $name = str_replace("glpi_plugin_genericobject_", "", $table); - $name = getSingular($name); - - $options['linked_itemtype'] = $itemtype; - - PluginGenericobjectType::addNewDropdown( - $name, - 'PluginGenericobject' . ucfirst($name), - $options - ); - } - // Invalidate menu data in current session - unset($_SESSION['glpimenu']); - - PluginGenericobjectSingletonObjectField::getInstance($itemtype, true); - } - } - - /** - * Delete a field in DB - * @param string $table the table - * @param string $field the field to delete - * @return void - */ - public static function deleteField($table, $field) - { - /** @var DBmysql $DB */ - global $DB; - - //Remove field from displaypreferences - self::deleteDisplayPreferences($table, $field); - - //If field exists, drop it ! - if ($DB->fieldExists($table, $field)) { - $DB->query("ALTER TABLE `$table` DROP `$field`"); - } - - $table = getTableNameForForeignKeyField($field); - //If dropdown is managed by the plugin - if ($table != '' && preg_match('/plugin_genericobject_(.*)/', $table, $results)) { - //Delete dropdown table - $query = "DROP TABLE `$table`"; - $DB->query($query); - //Delete dropdown files & class - $name = getSingular($results[1]); - PluginGenericobjectType::deleteClassFile($name); - PluginGenericobjectType::deleteFormFile($name); - PluginGenericobjectType::deletesearchFile($name); - } - } - - /** - * Change field order in DB - * @params an array which contains the itemtype, the field to move and the action (up/down) - * @return void - */ - public static function changeFieldOrder($params = []) - { - /** @var DBmysql $DB */ - global $DB; - $itemtype = $params['itemtype']; - $field = $params['field']; - $table = getTableForItemType($itemtype); - $fields = PluginGenericobjectSingletonObjectField::getInstance($params['itemtype']); - - //If action is down, reverse array first - if ($params['action'] == 'down') { - $fields = array_reverse($fields); - } - - //Get array keys - $keys = array_keys($fields); - //Index represents current position of $field - $index = 0; - foreach ($keys as $id => $key) { - if ($key == $field) { - $index = $id; - } - } - //Get 2 positions before and move field - if ($params['action'] == 'down') { - $previous = $index - 1; - } else { - $previous = $index - 2; - } - - if (isset($keys[$previous])) { - $parent = $fields[$keys[$previous]]; - $query = "ALTER TABLE `$table` MODIFY `$field` " . $fields[$field]['Type']; - $query .= " AFTER `" . $fields[$keys[$previous]]['Field'] . "`"; - $DB->query($query) or die($DB->error()); - } - } - - public static function checkNecessaryFieldsDelete($itemtype, $field) - { - $type = new PluginGenericobjectType(); - $type->getFromDBByType($itemtype); - - if ($type->canUseNetworkPorts() && 'locations_id' == $field) { - return false; - } - /* - if ($type->fields['use_direct_connections']) { - foreach(['users_id','groups_id',' states_id','locations_id'] as $tmp_field) { - if ($tmp_field == $field) { - return false; - } - } - }*/ - return true; - } - public static function install(Migration $migration) { } diff --git a/inc/object.class.php b/inc/object.class.php index eacb9e68..ac61cf6e 100644 --- a/inc/object.class.php +++ b/inc/object.class.php @@ -36,61 +36,9 @@ class PluginGenericobjectObject extends CommonDBTM //Internal field counter private $cpt = 0; - //Get itemtype name - public static function getTypeName($nb = 0) - { - /** @var array $LANG */ - global $LANG; - $class = get_called_class(); - //Datainjection : Don't understand why I need this trick : need to be investigated ! - if (preg_match("/Injection$/i", $class)) { - $class = str_replace("Injection", "", $class); - } - $item = new $class(); - //Itemtype name can be contained in a specific locale field : try to load it - PluginGenericobjectType::includeLocales($item->objecttype->fields['name']); - if (isset($LANG['genericobject'][$class][0])) { - $type_name = $LANG['genericobject'][$class][0]; - } else { - $type_name = $item->objecttype->fields['name']; - } - return ucwords($type_name); - } - - - public function __construct() - { - $class = get_called_class(); - if (class_exists($class)) { - $this->objecttype = PluginGenericobjectType::getInstance($class); - } - $this->dohistory = $this->canUseHistory(); - - if (preg_match("/PluginGenericobject(.*)/", $class, $results)) { - if (preg_match("/^(.*)y$/i", $results[1], $end_results)) { - static::$rightname = 'plugin_genericobject_' . strtolower($end_results[1]) . 'ies'; - } else if (preg_match("/^(.*)(ss|x)$/i", $results[1])) { - static::$rightname = 'plugin_genericobject_' . strtolower($results[1]) . 'es'; - } else { - static::$rightname = 'plugin_genericobject_' . strtolower($results[1]) . 's'; - } - } - - if ($this->canUseNotepad()) { - $this->usenotepad = true; - } - } - public function getCloneRelations(): array { - return [ - Computer_Item::class, - Contract_Item::class, - Document_Item::class, - Infocom::class, - Item_Devices::class, - NetworkPort::class, - ]; + return []; } public static function install() @@ -100,559 +48,4 @@ public static function install() public static function uninstall() { } - - public static function registerType() - { - /** - * @var array $PLUGIN_HOOKS - * @var array $UNINSTALL_TYPES - * @var array $ORDER_TYPES - * @var array $CFG_GLPI - * @var array $GO_LINKED_TYPES - * @var array $GENINVENTORYNUMBER_TYPES - */ - global $PLUGIN_HOOKS, $UNINSTALL_TYPES, $ORDER_TYPES, $CFG_GLPI, $GO_LINKED_TYPES, $GENINVENTORYNUMBER_TYPES; - - $class = get_called_class(); - $item = new $class(); - $fields = PluginGenericobjectSingletonObjectField::getInstance($class); - $plugin = new Plugin(); - - PluginGenericobjectType::includeLocales($item->getObjectTypeName()); - PluginGenericobjectType::includeConstants($item->getObjectTypeName()); - - $options = [ - "document_types" => $item->canUseDocuments(), - "helpdesk_visible_types" => $item->canUseTickets(), - "linkgroup_types" => isset($fields["groups_id"]), - "linkuser_types" => isset($fields["users_id"]), - "linkgroup_tech_types" => isset($fields["groups_id_tech"]), - "linkuser_tech_types" => isset($fields["users_id_tech"]), - "ticket_types" => $item->canUseTickets(), - "infocom_types" => $item->canUseInfocoms(), - "networkport_types" => $item->canUseNetworkPorts(), - "reservation_types" => $item->canBeReserved(), - "contract_types" => $item->canUseContracts(), - "unicity_types" => $item->canUseUnicity(), - "location_types" => isset($fields['locations_id']), - "itemdevices_types" => $item->canUseItemDevice(), - "itemdevicememory_types" => $item->canUseItemDevice(), - "itemdevicepowersupply_types" => $item->canUseItemDevice(), - "itemdevicenetworkcard_types" => $item->canUseItemDevice(), - "itemdeviceharddrive_types" => $item->canUseItemDevice(), - "itemdevicebattery_types" => $item->canUseItemDevice(), - "itemdevicefirmware_types" => $item->canUseItemDevice(), - "itemdevicesimcard_types" => $item->canUseItemDevice(), - "itemdevicegeneric_types" => $item->canUseItemDevice(), - "itemdevicepci_types" => $item->canUseItemDevice(), - "itemdevicesensor_types" => $item->canUseItemDevice(), - "itemdeviceprocessor_types" => $item->canUseItemDevice(), - "itemdevicesoundcard_types" => $item->canUseItemDevice(), - "itemdevicegraphiccard_types" => $item->canUseItemDevice(), - "itemdevicemotherboard_types" => $item->canUseItemDevice(), - "itemdevicecamera_types" => $item->canUseItemDevice(), - - ]; - - $glpiVersion = new Plugin(); - $glpiVersion = $glpiVersion->getGlpiVersion(); - - if (version_compare($glpiVersion, "10.0.19", '>=')) { - $options["itemdevicedrive_types"] = $item->canUseItemDevice(); - $options["itemdevicecontrol_types"] = $item->canUseItemDevice(); - } - - Plugin::registerClass($class, $options); - - if (plugin_genericobject_haveRight($class, READ)) { - //Change url for adding a new object, depending on template management activation - if ($item->canUseTemplate()) { - //Template management is active - $add_url = "/front/setup.templates.php?itemtype=$class&add=1"; - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['links']['template'] = "/front/setup.templates.php?itemtype=$class&add=0"; - } else { - //Template management is not active - $add_url = Toolbox::getItemTypeFormURL($class, false); - } - //Menu management - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['title'] = $class::getTypeName(); - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['page'] = Toolbox::getItemTypeSearchURL($class, false); - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['links']['search'] = Toolbox::getItemTypeSearchURL($class, false); - - if (plugin_genericobject_haveRight($class, UPDATE)) { - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['links']['add'] = $add_url; - } - - //Add configuration icon, if user has right - if (Session::haveRight('config', UPDATE)) { - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['links']['config'] = Toolbox::getItemTypeSearchURL('PluginGenericobjectType', false) . "?itemtype=$class"; - } - - if ($item->canUsePluginUninstall()) { - if (!in_array($class, $UNINSTALL_TYPES)) { - array_push($UNINSTALL_TYPES, $class); - } - } - if ($item->canUsePluginSimcard()) { - if ($plugin->isActivated('simcard') && $plugin->isActivated('simcard')) { - //@phpstan-ignore-next-line - PluginSimcardSimcard_Item::registerItemtype($class); - } - } - if ($item->canUsePluginOrder()) { - if (!in_array($class, $ORDER_TYPES)) { - array_push($ORDER_TYPES, $class); - } - } - if ($item->canBeReserved()) { - //Manage name used for sector - //See object.form.php L101 - //it can be 'itemtype' name or 'family' name - if (($name = PluginGenericobjectType::getFamilyNameByItemtype($class)) === false) { - $name = $class; - } - //from define.php $CFG_GLPI['javascript']['assets'] seems to be computed only once (from start) - //need to add manually js for sector and itemtype/family - $CFG_GLPI['javascript']['assets'][strtolower($name)] = ['fullcalendar', 'reservations']; - } - - if ($item->canUseGlobalSearch()) { - if (!in_array($class, $CFG_GLPI['asset_types'])) { - array_push($CFG_GLPI['asset_types'], $class); - } - - if (!in_array($class, $CFG_GLPI['globalsearch_types'])) { - array_push($CFG_GLPI['globalsearch_types'], $class); - } - } - - if ($item->canUseDirectConnections()) { - if (!in_array($class, $GO_LINKED_TYPES)) { - array_push($GO_LINKED_TYPES, $class); - } - $items_class = $class . "_Item"; - $items_class::registerType(); - } - - if ($item->canUseProjects()) { - if (!in_array($class, $CFG_GLPI['project_asset_types'])) { - array_push($CFG_GLPI['project_asset_types'], $class); - } - } - - $plugin_gen_path = Plugin::getPhpDir('geninventorynumber'); - if ($item->canUsePluginGeninventorynumber()) { - if (!in_array($class, $GENINVENTORYNUMBER_TYPES)) { - include_once("$plugin_gen_path/inc/profile.class.php"); - //@phpstan-ignore-next-line - PluginGeninventorynumberConfigField::registerNewItemType($class); - array_push($GENINVENTORYNUMBER_TYPES, $class); - } - } else if ($plugin->isActivated('geninventorynumber')) { - include_once("$plugin_gen_path/inc/profile.class.php"); - //@phpstan-ignore-next-line - PluginGeninventorynumberConfigField::unregisterNewItemType($class); - } - } - - foreach (PluginGenericobjectType::getDropdownForItemtype($class) as $table) { - $itemtype = getItemTypeForTable($table); - if (class_exists($itemtype)) { - $item = new $itemtype(); - //If entity dropdown, check rights to view & create - if ($itemtype::canView()) { - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$itemtype]['links']['search'] = Toolbox::getItemTypeSearchURL($itemtype, false); - if ($itemtype::canCreate()) { - $PLUGIN_HOOKS['submenu_entry']['genericobject']['options'][$class]['links']['add'] = Toolbox::getItemTypeFormURL($class, false); - } - } - } - } - } - - public static function checkItemtypeRight($class, $right) - { - if (!is_null($class) and class_exists($class)) { - $right_name = PluginGenericobjectProfile::getProfileNameForItemtype( - $class - ); - - return Session::haveRight($right_name, $right); - } - } - - public static function canCreate(): bool - { - $class = get_called_class(); - //Datainjection : Don't understand why I need this trick : need to be investigated ! - if (preg_match("/Injection$/i", $class)) { - $class = str_replace("Injection", "", $class); - } - return static::checkItemtypeRight($class, CREATE); - } - - public static function canView(): bool - { - $class = get_called_class(); - return static::checkItemtypeRight($class, READ); - } - - public static function canUpdate(): bool - { - $class = get_called_class(); - return static::checkItemtypeRight($class, UPDATE); - } - - public static function canDelete(): bool - { - $class = get_called_class(); - return static::checkItemtypeRight($class, DELETE); - } - - public static function canPurge(): bool - { - $class = get_called_class(); - return static::checkItemtypeRight($class, PURGE); - } - - //------------------------ CAN methods -------------------------------------// - - public function getObjectTypeName() - { - return $this->objecttype->getName(); - } - - public function canUseInfocoms() - { - return ($this->objecttype->canUseInfocoms() && Session::haveRight("infocom", READ)); - } - - public function canUseContracts() - { - return ($this->objecttype->canUseContracts() && Session::haveRight("contract", READ)); - } - - - public function canUseTemplate() - { - return $this->objecttype->canUseTemplate(); - } - - - public function canUseNotepad() - { - return $this->objecttype->canUseNotepad(); - } - - public function canUseUnicity() - { - // Disable unicity feature (for GLPI 0.85 onward) : see issue #16 - // Related code : search for #16 - // FIXME : The bug may be in GLPI itself - return ($this->objecttype->canUseUnicity() && Session::haveRight("config", READ)); - } - - - public function canUseDocuments() - { - return ($this->objecttype->canUseDocuments() && Session::haveRight("document", READ)); - } - - - public function canUseTickets() - { - return ($this->objecttype->canUseTickets()); - } - - - public function canUseGlobalSearch() - { - return ($this->objecttype->canUseGlobalSearch()); - } - - - public function canBeReserved() - { - return ( - $this->objecttype->canBeReserved() - and Session::haveRight(ReservationItem::$rightname, ReservationItem::RESERVEANITEM) - ); - } - - - public function canUseHistory() - { - return ($this->objecttype->canUseHistory()); - } - - - public function canUsePluginDataInjection() - { - return ($this->objecttype->canUsePluginDataInjection()); - } - - - public function canUsePluginPDF() - { - return ($this->objecttype->canUsePluginPDF()); - } - - - public function canUsePluginOrder() - { - return ($this->objecttype->canUsePluginOrder()); - } - - public function canUsePluginGeninventorynumber() - { - return ($this->objecttype->canUsePluginGeninventorynumber()); - } - - public function canUseNetworkPorts() - { - return ($this->objecttype->canUseNetworkPorts()); - } - - - public function canUseDirectConnections() - { - return ($this->objecttype->canUseDirectConnections()); - } - - public function canUseProjects() - { - return ($this->objecttype->canUseProjects()); - } - - - public function canUsePluginUninstall() - { - return ($this->objecttype->canUsePluginUninstall()); - } - - public function canUsePluginSimcard() - { - return ($this->objecttype->canUsePluginSimcard()); - } - - public function getLinkedItemTypesAsArray() - { - return $this->objecttype->getLinkedItemTypesAsArray(); - } - - public function canUseItemDevice() - { - return ($this->objecttype->canUseItemDevice()); - } - - public function canUseImpact() - { - return ($this->objecttype->canUseImpact()); - } - - public function title() - { - } - - public static function getFieldsToHide() - { - return ['id', 'is_recursive', 'is_template', 'template_name', 'is_deleted', - 'entities_id', 'notepad', 'date_mod', 'date_creation', 'ticket_tco' - ]; - } - - public function prepareInputForAdd($input) - { - - //Template management - if (isset($input["id"]) && $input["id"] > 0) { - $input["_oldID"] = $input["id"]; - } - unset($input['id']); - unset($input['withtemplate']); - - return $input; - } - - - public function cleanDBonPurge() - { - $parameters = ['items_id' => $this->getID(), 'itemtype' => get_called_class()]; - $types = ['Computer_Item', 'ReservationItem', 'Document_Item', 'Infocom', 'Contract_Item']; - foreach ($types as $type) { - $item = new $type(); - $item->deleteByCriteria($parameters); - } - - foreach (['NetworkPort', 'Computer_Item', 'ReservationItem', 'ReservationItem', 'Document_Item', 'Infocom', 'Contract_Item', 'Item_Problem', 'Change_Item', 'Item_Project'] as $itemtype) { - $ip = new $itemtype(); - $ip->cleanDBonItemDelete(get_called_class(), $this->getID()); - } - } - - //Datainjection specific methods - public function isPrimaryType() - { - return true; - } - - - public function connectedTo() - { - return []; - } - - - /** - * Standard method to add an object into glpi - * - * @param array $values fields to add into glpi - * @param array $options options used during creation - * @return array - * - **/ - public function addOrUpdateObject($values = [], $options = []) - { - //@phpstan-ignore-next-line - $lib = new PluginDatainjectionCommonInjectionLib($this, $values, $options); - $lib->processAddOrUpdate(); - return $lib->getInjectionResults(); - } - - - public function getOptions($primary_type = '') - { - return Search::getOptions($primary_type); - } - - - public function transfer($new_entity) - { - if ($this->fields['id'] > 0 && $this->fields['entities_id'] != $new_entity) { - //Update entity for this object - $tmp['id'] = $this->fields['id']; - $tmp['entities_id'] = $new_entity; - $this->update($tmp); - - $toupdate = ['id' => $this->fields['id']]; - foreach (PluginGenericobjectSingletonObjectField::getInstance(get_called_class()) as $field => $data) { - $table = getTableNameForForeignKeyField($field); - - //It is a dropdown table ! - if ( - $field != 'entities_id' - && $table != '' - && isset($this->fields[$field]) && $this->fields[$field] > 0 - ) { - //Instanciate a new dropdown object - $dropdown_itemtype = getItemTypeForTable($table); - $dropdown = new $dropdown_itemtype(); - $dropdown->getFromDB($this->fields[$field]); - - //If dropdown is only accessible in the other entity - //do not go further - if (!$dropdown->isEntityAssign() || in_array($new_entity, getAncestorsOf('glpi_entities', $dropdown->getEntityID()))) { - continue; - } else { - $tmp = []; - $where = []; - if ($dropdown instanceof CommonTreeDropdown) { - $tmp['completename'] = $dropdown->fields['completename']; - $where['completename'] = Toolbox::addslashes_deep($tmp['completename']); - } else { - $tmp['name'] = $dropdown->fields['name']; - $where['name'] = Toolbox::addslashes_deep($tmp['name']); - } - $tmp['entities_id'] = $new_entity; - $where['entities_id'] = $tmp['entities_id']; - //There's a dropdown value in the target entity - if ($found = $dropdown->find($where)) { - $myfound = array_pop($found); - if ($myfound['id'] != $this->fields[$field]) { - $toupdate[$field] = $myfound['id']; - } - } else { - $clone = $dropdown->fields; - if ($dropdown instanceof CommonTreeDropdown) { - unset($clone['completename']); - } - unset($clone['id']); - $clone['entities_id'] = $new_entity; - $new_id = $dropdown->import($clone); - $toupdate[$field] = $new_id; - } - } - } - } - $this->update($toupdate); - } - return true; - } - - public static function getMenuContent() - { - $types = PluginGenericobjectType::getTypes(); - $menu = []; - foreach ($types as $type) { - $itemtype = $type['itemtype']; - if (!class_exists($itemtype)) { - continue; - } - $item = new $itemtype(); - - $itemtype_rightname = PluginGenericobjectProfile::getProfileNameForItemtype($itemtype); - if ( - class_exists($itemtype) - && Session::haveRight($itemtype_rightname, READ) - ) { - $links = []; - $links['search'] = $itemtype::getSearchUrl(false); - $links['lists'] = ''; - - if ($item->canUseTemplate()) { - $links['template'] = "/front/setup.templates.php?itemtype=$itemtype&add=0"; - if (Session::haveRight($itemtype_rightname, CREATE)) { - $links['add'] = "/front/setup.templates.php?itemtype=$itemtype&add=1"; - } - } else { - if (Session::haveRight($itemtype_rightname, CREATE)) { - $links['add'] = $itemtype::getFormUrl(false); - } - } - - if ( - $type['plugin_genericobject_typefamilies_id'] > 0 - && (!isset($_GET['itemtype']) - || !preg_match("/itemtype=" . $_GET['itemtype'] . "/", $_GET['itemtype'])) - ) { - $family_id = $type['plugin_genericobject_typefamilies_id']; - $name = Dropdown::getDropdownName("glpi_plugin_genericobject_typefamilies", $family_id, 0, false); - $str_name = strtolower($name); - $menu[$str_name]['title'] = Dropdown::getDropdownName("glpi_plugin_genericobject_typefamilies", $family_id); - $menu[$str_name]['page'] = '/' . Plugin::getWebDir('genericobject', false) . '/front/familylist.php?id=' . $family_id; - $menu[$str_name]['options'][strtolower($itemtype)] = [ - 'title' => $type['itemtype']::getMenuName(), - 'page' => $itemtype::getSearchUrl(false), - 'links' => $links, - 'lists_itemtype' => $itemtype, - ]; - } else { - $menu[strtolower($itemtype)] = [ - 'title' => $type['itemtype']::getMenuName(), - 'page' => $itemtype::getSearchUrl(false), - 'links' => $links, - 'lists_itemtype' => $itemtype, - ]; - } - } - } - - // Sort by menu entries name - uasort($menu, fn($a, $b) => $a['title'] <=> $b['title']); - - // Mark as multi entries - $menu['is_multi_entries'] = true; - - return $menu; - } } diff --git a/inc/object_item.class.php b/inc/object_item.class.php deleted file mode 100644 index ac86590e..00000000 --- a/inc/object_item.class.php +++ /dev/null @@ -1,138 +0,0 @@ -. - * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2009-2023 by GenericObject plugin team. - * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html - * @link https://github.com/pluginsGLPI/genericobject - * ------------------------------------------------------------------------- - */ - -// @codingStandardsIgnoreStart -class PluginGenericobjectObject_Item extends CommonDBChild -{ - // @codingStandardsIgnoreEnd - public $dohistory = true; - - // From CommonDBRelation - public static $itemtype_1 = "PluginGenericobjectObject"; - public static $items_id_1 = 'plugin_genericobject_objects_id'; - - public static $itemtype_2 = 'itemtype'; - public static $items_id_2 = 'items_id'; - - //Get itemtype name - public static function getTypeName($nb = 0) - { - /** @var array $LANG */ - global $LANG; - $class = get_called_class(); - //Datainjection : Don't understand why I need this trick : need to be investigated ! - if (preg_match("/Injection$/i", $class)) { - $class = str_replace("Injection", "", $class); - } - $item = new $class(); - //Itemtype name can be contained in a specific locale field : try to load it - PluginGenericobjectType::includeLocales($item->objecttype->fields['name']); - if (isset($LANG['genericobject'][$class][0])) { - return $LANG['genericobject'][$class][0]; - } else { - return $item->objecttype->fields['name']; - } - } - - public static function canView() - { - return Session::haveRight(self::$itemtype_1, READ); - } - - public static function canCreate() - { - return Session::haveRight(self::$itemtype_1, CREATE); - } - - /** - * - * Enter description here ... - * @since 2.2.0 - * @param CommonDBTM $item - */ - public static function showItemsForSource(CommonDBTM $item) - { - } - - /** - * - * Enter description here ... - * @since 2.2.0 - * @param CommonDBTM $item - */ - public static function showItemsForTarget(CommonDBTM $item) - { - } - - /** - * - * Enter description here ... - * @since 2.2.0 - */ - public static function registerType() - { - Plugin::registerClass(get_called_class(), ['addtabon' => self::getLinkedItemTypes()]); - } - - public static function getLinkedItemTypes() - { - $source_itemtype = self::getItemType1(); - $source_item = new $source_itemtype(); - return $source_item->getLinkedItemTypesAsArray(); - } - - public static function getItemType1() - { - $classname = get_called_class(); - return $classname::$itemtype_1; - } - - public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) - { - if (!$withtemplate) { - $itemtypes = self::getLinkedItemTypes(); - if (in_array(get_class($item), $itemtypes) || get_class($item) == self::getItemType1()) { - return [1 => __("Objects management", "genericobject")]; - } - } - return ''; - } - - public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) - { - $itemtypes = self::getLinkedItemTypes(); - if (get_class($item) == self::getItemType1()) { - self::showItemsForSource($item); - } else if (in_array(get_class($item), $itemtypes)) { - self::showItemsForTarget($item); - } - return true; - } -} diff --git a/inc/profile.class.php b/inc/profile.class.php index 5969f107..59a2824b 100644 --- a/inc/profile.class.php +++ b/inc/profile.class.php @@ -41,228 +41,6 @@ public static function getProfileNameForItemtype($itemtype) return preg_replace("/^glpi_/", "", getTableForItemType($itemtype)); } - public static function getProfileforItemtype($profiles_id, $itemtype) - { - $rights = ProfileRight::getProfileRights($profiles_id); - $itemtype_rightname = self::getProfileNameForItemtype($itemtype); - return isset($rights[$itemtype_rightname]) ? $rights[$itemtype_rightname] : 0; - } - - public function getProfilesFromDB($id, $config = true) - { - $prof_datas = []; - foreach ( - getAllDataFromTable( - getTableForItemType(__CLASS__), - ['profiles_id' => $id] - ) as $prof - ) { - if ($prof['right'] != "" || $config) { - $prof_datas[$prof['itemtype']] = $prof['right']; - $prof_datas[$prof['itemtype'] . '_open_ticket'] = $prof['open_ticket']; - $prof_datas['id'] = $prof['id']; - } - } - - if (empty($prof_datas) && !$config) { - return false; - } - - $prof_datas['profiles_id'] = $id; - $this->fields = $prof_datas; - - return true; - } - - public function saveProfileToDB($params) - { - /** @var DBmysql $DB */ - global $DB; - - $types = PluginGenericobjectType::getTypes(true); - if (!empty($types)) { - foreach ($types as $tmp => $profile) { - $query = "UPDATE `" . getTableForItemType(__CLASS__) . "` " . - "SET "; - - if (isset($params[$profile['itemtype']]) && $params[$profile['itemtype']] == 'NULL') { - $query .= "`right`='' "; - } else { - if (isset($params[$profile['itemtype']])) { - $query .= "`right`='" . $params[$profile['itemtype']] . "'"; - } else { - $query .= "`right`=''"; - } - } - - if (isset($params[$profile['itemtype'] . '_open_ticket'])) { - $query .= ", `open_ticket`='" . $params[$profile['itemtype'] . '_open_ticket'] . "' "; - } - - $query .= "WHERE `profiles_id`='" . $params['profiles_id'] . "' " . - "AND `itemtype`='" . $profile['itemtype'] . "'"; - $DB->query($query); - } - } - } - - - /** - * Create rights for the current profile - * @return void - */ - public static function createFirstAccess() - { - if (!self::profileExists($_SESSION["glpiactiveprofile"]["id"], 'PluginGenericobjectType')) { - self::createAccess($_SESSION["glpiactiveprofile"]["id"], "PluginGenericobjectType", true); - } - } - - /** - * Check if rights for a profile still exists - * @param int $profiles_id the profile ID - * @param string $itemtype name of the type - * @return bool - */ - public static function profileExists($profiles_id, $itemtype = false) - { - $profile = new Profile(); - $profile->getFromDB($profiles_id); - $rights = ProfileRight::getProfileRights($profiles_id); - $itemtype_rightname = self::getProfileNameForItemtype($itemtype); - if ($itemtype) { - _log( - "get rights on itemtype " . $itemtype . " for profile " . $profile->fields['name'], - ':', - isset($rights[$itemtype_rightname]) ? $rights[$itemtype_rightname] : "NONE" - ); - return (isset($rights[self::getProfileNameForItemtype($itemtype)])); - } - return true; - } - - /** - * Create rights for the profile if it doesn't exists - * @param int $profiles_id the profile ID - * @param string $itemtype - * @param bool $first - * @return void - */ - public static function createAccess($profiles_id, $itemtype, $first = false) - { - - $rights = getAllDataFromTable('glpi_profiles'); - $profile_right = new ProfileRight(); - $itemtype_rightname = self::getProfileNameForItemtype($itemtype); - - foreach ($rights as $right) { - if ($right['id'] == $profiles_id) { - $r = ALLSTANDARDRIGHT | READNOTE | UPDATENOTE; - } else { - $r = 0; - } - $profile_right->updateProfileRights($right['id'], [$itemtype_rightname => $r]); - } - } - - public static function getGeneralRights() - { - return [[ - 'itemtype' => 'PluginGenericobjectType', - 'label' => __("Type of objects", "genericobject"), - 'field' => self::getProfileNameForItemtype('PluginGenericobjectType'), - ] - ]; - } - - public static function getTypesRights() - { - $rights = []; - - include_once(GENERICOBJECT_DIR . "/inc/type.class.php"); - - $types = PluginGenericobjectType::getTypes(true); - if (count($types) > 0) { - foreach ($types as $_ => $type) { - $itemtype = $type['itemtype']; - - if (!class_exists($itemtype)) { - continue; - } - - $field = self::getProfileNameForItemtype($itemtype); - $objecttype = new PluginGenericobjectType($itemtype); - $rights[] = [ - 'itemtype' => $itemtype, - 'label' => $itemtype::getTypeName(), - 'field' => self::getProfileNameForItemtype($itemtype) - ]; - } - } - - return $rights; - } - - public static function installRights($first = false) - { - $missing_rights = []; - $installed_rights = ProfileRight::getAllPossibleRights(); - $right_names = []; - - // Add common plugin's rights - $right_names[] = self::getProfileNameForItemtype('PluginGenericobjectType'); - - // Add types' rights - $types = PluginGenericobjectType::getTypes(true); - foreach ($types as $_ => $type) { - $itemtype = $type['itemtype']; - $right_names[] = self::getProfileNameForItemtype($itemtype); - } - - // Check for already defined rights - foreach ($right_names as $right_name) { - _log($right_name, isset($installed_rights[$right_name])); - if (!isset($installed_rights[$right_name])) { - $missing_rights[] = $right_name; - } - } - - //Install missing rights in profile and update the object - if (count($missing_rights) > 0) { - ProfileRight::addProfileRights($missing_rights); - self::changeProfile(); - } - } - - /** - * Delete type from the rights - * @param string $itemtype the name of the type - * @return void - */ - public static function deleteTypeFromProfile($itemtype) - { - $rights = [self::getProfileNameForItemtype($itemtype)]; - ProfileRight::deleteProfileRights($rights); - } - - public static function changeProfile() - { - $general_rights = self::getGeneralRights(); - $type_rights = self::getTypesRights(); - $db_rights = ProfileRight::getProfileRights($_SESSION['glpiactiveprofile']['id']); - $rights = array_merge($general_rights, $type_rights); - - foreach ($rights as $right) { - $str_right = $right['field']; - if (preg_match("/plugin_genericobject_/", $str_right)) { - unset($_SESSION['glpiactiveprofile'][$str_right]); - if (!empty($db_rights) && isset($db_rights[$str_right])) { - $_SESSION['glpiactiveprofile'][$str_right] = $db_rights[$str_right]; - } - } - } - } - public static function install(Migration $migration) { /** @var DBmysql $DB */ @@ -337,9 +115,6 @@ public static function install(Migration $migration) } //$migration->dropTable('glpi_plugin_genericobject_profiles'); } - if (!countElementsInTable('glpi_profilerights', ['name' => ['LIKE', '%genericobject%']])) { - self::createFirstAccess(); - } } public static function uninstall() diff --git a/inc/type.class.php b/inc/type.class.php index 52f3190d..28395fa0 100644 --- a/inc/type.class.php +++ b/inc/type.class.php @@ -50,9 +50,9 @@ class PluginGenericobjectType extends CommonDBTM const CAN_OPEN_TICKET = 1024; - public $dohistory = true; + public $dohistory = true; - public static $rightname = 'plugin_genericobject_types'; + public static $rightname = 'plugin_genericobject_types'; public function __construct($itemtype = false) @@ -101,543 +101,7 @@ public function getFromDBByType($itemtype) } } - //------------------------------------- Framework hooks ---------------------------------- - public function prepareInputForAdd($input) - { - //Name must not be empty - if (isset($input['name']) && $input['name'] == '') { - Session::addMessageAfterRedirect(__("Type name is missing", "genericobject"), ERROR, true); - return []; - } - - // Name must be more than 1 char - if (isset($input['name']) && strlen($input['name']) < 2) { - Session::addMessageAfterRedirect(__("Type name must be longer", "genericobject"), ERROR, true); - return []; - } - - //Name must not match specific names - if (in_array($input['name'], ['field', 'object', 'type'])) { - Session::addMessageAfterRedirect(__( - "Types 'field', 'object' and 'type' are reserved. Please choose another one", - "genericobject" - ), ERROR, true); - return []; - } - - //Name must start with a letter - if (!preg_match("/^[a-zA-Z]+/i", $input['name'])) { - Session::addMessageAfterRedirect(__("Type must start with a letter", "genericobject"), ERROR, true); - return []; - } - $input['name'] = self::filterInput($input['name']); - - //Name must not be present in DB - if (countElementsInTable(getTableForItemType(__CLASS__), ['name' => $input['name']])) { - Session::addMessageAfterRedirect(__("A type already exists with the same name", "genericobject"), ERROR, true); - return []; - } else { - $input['itemtype'] = self::getClassByName($input['name']); - return $input; - } - } - - // @codingStandardsIgnoreStart - public function post_addItem() - { - // @codingStandardsIgnoreEnd - self::addNewObject( - $this->input["name"], - $this->input["itemtype"], - ['add_table' => 1, 'create_default_profile' => 1, 'overwrite_locales' => true] - ); - return true; - } - - public function prepareInputForUpdate($input) - { - // Handle impact_icon - $input = $this->handleImpactIconUpdate($input); - - // Handle use_impact - $input = $this->handleUseImpactUpdate($input); - - //If itemtype is active : register it ! - if (isset($input["is_active"]) && $input["is_active"]) { - self::registerOneType($this->fields['itemtype']); - } - return $input; - } - - public function handleImpactIconUpdate($input) - { - // Read submitted icon - $icon = $input['_impact_icon'][0] ?? null; - - // Icon wasn't submitted, nothing more to do - if (empty($icon)) { - return $input; - } - - // Convert to realpath - $icon_path = realpath(GLPI_TMP_DIR . "/$icon"); - - // Realpath didn't find the file, shouldn't really happenn but just in case - if (!$icon_path) { - return $input; - } - - // Wrong file type, ignore - if (!Document::isImage($icon_path)) { - return $input; - } - - // File is outside of GLPI_TMP_DIR - if (!str_starts_with($icon_path, realpath(GLPI_TMP_DIR))) { - trigger_error("Trying to read forbidden file: $icon_path", E_USER_WARNING); - return $input; - } - - // Reread base file name - $icon_filename = pathinfo($icon_path, PATHINFO_BASENAME); - - // Remove previous icon if exist - $existing_icon_path = self::getImpactIconFileStoragePath( - $this->fields['impact_icon'], - $this->fields['itemtype'] - ); - if ( - $existing_icon_path - && file_exists($existing_icon_path) - && str_starts_with( - realpath($existing_icon_path), - realpath(GLPI_PLUGIN_DOC_DIR . "/genericobject/impact_icons/") - ) - ) { - unlink($existing_icon_path); - } - - // Move file and update input on success - $icons_dir = GLPI_PLUGIN_DOC_DIR . '/genericobject/impact_icons/'; - if (!is_dir($icons_dir) && !mkdir($icons_dir)) { - trigger_error(sprintf('Unable to create "%s" directory.', $icons_dir), E_USER_WARNING); - return $input; - } - - $new_path = self::getImpactIconFileStoragePath( - $icon_filename, - $this->fields['itemtype'] - ); - if (rename($icon_path, $new_path)) { - $input['impact_icon'] = $icon_filename; - } - - return $input; - } - - public function handleUseImpactUpdate($input) - { - $use_impact = $input['use_impact'] ?? null; - unset($input['use_impact']); - - // Value wasn't modified, nothing to be done - if ($use_impact === null) { - return $input; - } - - // Impact analysis will now be enabled, update conf if needed - if ($use_impact && !Impact::isEnabled($this->fields['itemtype'])) { - $enabled = Config::getConfigurationValue('core', Impact::CONF_ENABLED); - $enabled = importArrayFromDB($enabled); - $enabled[] = $this->fields['itemtype']; - Config::setConfigurationValues('core', [ - Impact::CONF_ENABLED => exportArrayToDB($enabled) - ]); - return $input; - } - - // Impact analysis will now be disabled, update config if needed - if (!$use_impact && Impact::isEnabled($this->fields['itemtype'])) { - $enabled = Config::getConfigurationValue('core', Impact::CONF_ENABLED); - $enabled = importArrayFromDB($enabled); - $enabled = array_filter( - $enabled, - fn($i) => $i != $this->fields['itemtype'] - ); - Config::setConfigurationValues('core', [ - Impact::CONF_ENABLED => exportArrayToDB($enabled) - ]); - - return $input; - } - - return $input; - } - - // @codingStandardsIgnoreStart - public function post_updateItem($history = true) - { - // @codingStandardsIgnoreEnd - //Check if some fields need to be added, because of GLPI framework - $this->checkNecessaryFieldsUpdate(); - } - - // @codingStandardsIgnoreStart - public function pre_deleteItem() - { - // @codingStandardsIgnoreEnd - if ($this->getFromDB($this->fields["id"])) { - $name = $this->fields['name']; - $itemtype = $this->fields['itemtype']; - - //Delete all network ports - self::deleteNetworking($itemtype); - - //Drop all dropdowns associated with itemtype - self::deleteDropdownsForItemtype($itemtype); - - //Delete loans associated with this type - self::deleteLoans($itemtype); - - //Delete loans associated with this type - self::deleteUnicity($itemtype); - - //Delete reservations with this tyoe - self::deleteReservations($itemtype); - self::deleteReservationItems($itemtype); - - //Remove datainjection specific file - self::deleteInjectionFile($name); - - //Delete profile informations associated with this type - PluginGenericobjectProfile::deleteTypeFromProfile($itemtype); - - self::deleteTicketAssignation($itemtype); - - //Remove associations to simcards with this type - self::deleteSimcardAssignation($itemtype); - - //Remove existing datainjection models - self::removeDataInjectionModels($itemtype); - - //Delete specific locale directory - self::deleteLocales($name, $itemtype); - - self::deleteItemtypeReferencesInGLPI($itemtype); - - self::deleteItemTypeFilesAndClasses($name, $this->getTable(), $itemtype); - - //self::deleteNotepad($itemtype); - - if (preg_match("/PluginGenericobject(.*)/", $itemtype, $results)) { - $newrightname = 'plugin_genericobject_' . strtolower($results[1]) . 's'; - ProfileRight::deleteProfileRights([$newrightname]); - } - - $prof = new Profile(); - $profiles = getAllDataFromTable('glpi_profiles'); - foreach ($profiles as $profile) { - $helpdesk_item_types = json_decode($profile['helpdesk_item_type'], true); - if ($helpdesk_item_types !== null) { - $index = array_search($itemtype, $helpdesk_item_types); - if ($index) { - unset($helpdesk_item_types[$index]); - $tmp['id'] = $profile['id']; - $tmp['helpdesk_item_type'] = json_encode($helpdesk_item_types); - $prof->update($tmp); - } - } - } - - return true; - } else { - return false; - } - } - - // @codingStandardsIgnoreStart - public function post_deleteItem() - { - // @codingStandardsIgnoreEnd - } - - /** - * Define name of type to display in menu - * - * @return string type name - */ - public static function getMenuName() - { - return __('Objects management', 'genericobject'); - } - - //------------------------------------- End Framework hooks ----------------------------- - - /** - * Create an object, it's table, files and rights - * - * @since 2.1.5 - * @param string $name object short name - * @param string $itemtype object class name - * @param array $options create options : - * - add_table : add the object table (default is no) - * - create_default_profile : add default right (default is no) for current user profile - * - add_injection_file : add file to integrate itemtype into the datainjection plugin - * - add_language_file : create a default language for the itemtype - * @return void - */ - public static function addNewObject($name, $itemtype, $options = []) - { - $params['add_table'] = false; - $params['create_default_profile'] = false; - $params['add_injection_file'] = false; - $params['add_language_file'] = true; - $params['overwrite_locales'] = false; - - foreach ($options as $key => $value) { - $params[$key] = $value; - } - - if ($params['add_table']) { - self::addTable($itemtype); - } - - //Write object class on the filesystem - self::addClassFile($name, $itemtype); - - //Write the form on the filesystem - self::addFormFile($name, $itemtype); - self::addSearchFile($name, $itemtype); - - if ($params['overwrite_locales']) { - //Add language file - self::addLocales($name, $itemtype); - } - - //Add file needed by datainjectin plugin - if ($params['add_injection_file']) { - self::addDatainjectionFile($name); - } - PluginGenericobjectProfile::installRights(); - if ($params['create_default_profile']) { - //Create rights for this new object - PluginGenericobjectProfile::createAccess($_SESSION["glpiactiveprofile"]["id"], $itemtype, true); - //Reload profiles - PluginGenericobjectProfile::changeProfile(); - } - } - - /** - * - * Add a new dropdown :class & files - * @param string $name - * @param string $itemtype - * @param array $options - */ - public static function addNewDropdown($name, $itemtype, $options = []) - { - $params['entities_id'] = false; - $params['is_recursive'] = false; - $params['is_tree'] = false; - $params['linked_itemtype'] = false; - foreach ($options as $key => $value) { - $params[$key] = $value; - } - //Add files on the disk - self::addDropdownClassFile($name, $itemtype, $params); - self::addDropdownTable(getTableForItemType($itemtype), $params); - self::addDropdownFrontFile($name); - self::addDropdownFrontformFile($name); - - // Invalidate submenu data in current session - unset($_SESSION['glpimenu']); - } - - /** - * - * Add or delete, if needed some fields to make sure that the itemtype is compatible with - * GLPI framework - */ - public function checkNecessaryFieldsUpdate() - { - /** @var DBmysql $DB */ - global $DB; - - $itemtype = $this->fields["itemtype"]; - $item = new $itemtype(); - $item->getEmpty(); - $table = getTableForItemType($itemtype); - - //Global search (inventory > status) - if (isset($this->input['use_global_search']) && $this->input['use_global_search']) { - PluginGenericobjectField::addNewField($table, 'serial', 'name'); - PluginGenericobjectField::addNewField($table, 'otherserial', 'serial'); - PluginGenericobjectField::addNewField($table, 'locations_id', 'otherserial'); - PluginGenericobjectField::addNewField($table, 'states_id', 'locations_id'); - PluginGenericobjectField::addNewField($table, 'users_id', 'states_id'); - PluginGenericobjectField::addNewField($table, 'groups_id', 'users_id'); - PluginGenericobjectField::addNewField($table, 'manufacturers_id', 'groups_id'); - PluginGenericobjectField::addNewField($table, 'users_id_tech', 'manufacturers_id'); - PluginGenericobjectField::addNewField($table, 'is_deleted', 'id'); - } - - if (isset($this->input['use_recursivity']) && $this->input['use_recursivity']) { - PluginGenericobjectField::addNewField($table, 'is_recursive', 'entities_id'); - } else { - PluginGenericobjectField::deleteField($table, 'is_recursive'); - } - - //Template - if (isset($this->input['use_template']) && $this->input['use_template']) { - PluginGenericobjectField::addNewField($table, 'is_template', 'id'); - PluginGenericobjectField::addNewField($table, 'template_name', 'is_template'); - } else { - PluginGenericobjectField::deleteField($table, 'is_template'); - PluginGenericobjectField::deleteField($table, 'template_name'); - } - - //Trash - if (isset($this->input['use_deleted']) && $this->input['use_deleted']) { - PluginGenericobjectField::addNewField($table, 'is_deleted', 'id'); - } else { - if (!$this->canBeReserved()) { - PluginGenericobjectField::deleteField($table, 'is_deleted'); - } else { - _log($DB->fieldExists($table, 'is_deleted')); - if ($DB->fieldExists($table, 'is_deleted')) { - Session::addMessageAfterRedirect( - __("Dustbin can't be removed since Reservations are used on this type."), - false, - WARNING - ); - } - } - } - - //Reservation needs is_deleted field ! - if ($this->canBeReserved()) { - PluginGenericobjectField::addNewField($table, 'is_deleted', 'id'); - PluginGenericobjectField::addNewField($table, 'locations_id'); - PluginGenericobjectField::addNewField($table, 'users_id'); - } - - //Helpdesk post-only - if ($this->canUseTickets()) { - //TODO rename is_helpdesk_visible into is_helpdeskvisible - PluginGenericobjectField::addNewField($table, 'is_helpdesk_visible', 'comment'); - PluginGenericobjectField::addNewField($table, 'ticket_tco'); - } else { - PluginGenericobjectField::deleteField($table, 'is_helpdesk_visible'); - } - - //Notes - if (isset($this->input['use_notepad']) && $this->input['use_notepad']) { - PluginGenericobjectField::addNewField($table, 'notepad', 'id'); - } else { - PluginGenericobjectField::deleteField($table, 'notepad'); - } - - //Networkport - if ($this->canUseNetworkPorts()) { - PluginGenericobjectField::addNewField($table, 'locations_id'); - } - - if ($this->canUseDirectConnections()) { - self::addItemsTable($itemtype); - //self::addItemClassFile($this->fields['name'], $itemtype); - } else { - self::deleteItemsTable($itemtype); - self::deleteClassFile($this->fields['name'] . "_item"); - } - - if ( - $this->canUsePluginDataInjection() && - !file_exists(self::getCompleteInjectionFilename($this->fields['name'])) - ) { - self::addDatainjectionFile($this->fields['name']); - } - - if ( - !$this->canUsePluginDataInjection() && - file_exists(self::getCompleteInjectionFilename($this->fields['name'])) - ) { - self::deleteInjectionFile($this->fields['name']); - } - - //Device item needs locations_id field ! - if ($this->canUseItemDevice()) { - PluginGenericobjectField::addNewField($table, 'locations_id'); - } - } - - - /** - * Add object type table + entries in glpi_display - * @name object type's name - * @return void - */ - public static function addTable($itemtype) - { - /** @var DBmysql $DB */ - global $DB; - - $default_charset = DBConnection::getDefaultCharset(); - $default_collation = DBConnection::getDefaultCollation(); - $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); - - $query = "CREATE TABLE IF NOT EXISTS `" . getTableForItemType($itemtype) . "` ( - `id` INT {$default_key_sign} NOT NULL AUTO_INCREMENT, - `entities_id` INT {$default_key_sign} NOT NULL DEFAULT '0', - `name` VARCHAR( 255 ) NOT NULL DEFAULT '', - `comment` text, - `notepad` text, - `date_mod` TIMESTAMP NULL DEFAULT NULL, - `date_creation` TIMESTAMP NULL DEFAULT NULL, - PRIMARY KEY ( `id` ), - KEY `date_mod` (`date_mod`), - KEY `date_creation` (`date_creation`) - ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query); - - $query = "INSERT INTO `glpi_displaypreferences` (`id`, `itemtype`, `num`, `rank`, `users_id`) " . - "VALUES (NULL, '$itemtype', '2', '1', '0');"; - $DB->query($query); - } - - /** - * Add object_items table to connect an object to others - * @name object type's name - * @return void - */ - public static function addItemsTable($itemtype) - { - /** @var DBmysql $DB */ - global $DB; - - $default_charset = DBConnection::getDefaultCharset(); - $default_collation = DBConnection::getDefaultCollation(); - $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); - - $table = getTableForItemType($itemtype); - $fk = getForeignKeyFieldForTable($table); - $query = "CREATE TABLE IF NOT EXISTS `" . getTableForItemType($itemtype) . "_items` ( - `id` int {$default_key_sign} NOT NULL AUTO_INCREMENT, - `items_id` int {$default_key_sign} NOT NULL DEFAULT '0' COMMENT 'RELATION to various table, according to itemtype (ID)', - `date_mod` TIMESTAMP NULL DEFAULT NULL, - `date_creation` TIMESTAMP NULL DEFAULT NULL, - `$fk` int {$default_key_sign} NOT NULL DEFAULT '0', - `itemtype` varchar(100) NOT NULL, - PRIMARY KEY (`id`), - KEY `$fk` (`$fk`), - KEY `date_mod` (`date_mod`), - KEY `date_creation` (`date_creation`), - KEY `item` (`itemtype`,`items_id`) - ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query); - } - - - //-------------------------------- FILE CREATION / DELETION ----------------------------// + //-------------------------------- FILE DELETION ----------------------------// public static function deleteFile($filename) { if (file_exists($filename)) { @@ -727,40 +191,6 @@ public static function deleteInjectionFile($name) self::deleteFile(self::getCompleteInjectionFilename($name)); } - - public static function addLocales($name, $itemtype) - { - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - - $fsname = self::getSystemName($name); - - $locale_dir = GENERICOBJECT_LOCALES_PATH . "/" . $fsname; - if (!is_dir($locale_dir)) { - @ mkdir($locale_dir, 0755, true); - } - - $locale_files = [ - $fsname . '.' . $_SESSION['glpilanguage'], - ]; - if ($CFG_GLPI['language'] != $_SESSION['glpilanguage']) { - $locale_files[] = $fsname . '.' . $CFG_GLPI['language']; - } - - foreach ($locale_files as $locale_file) { - self::addFileFromTemplate( - [ - 'NAME' => $name, - 'CLASSNAME' => self::getClassByName($name), - ], - self::LOCALE_TEMPLATE, - $locale_dir, - $locale_file - ); - } - } - - public static function deleteLocales($name, $itemtype) { $locale_dir = GENERICOBJECT_LOCALES_PATH . "/" . self::getSystemName($name); @@ -772,244 +202,6 @@ public static function deleteLocales($name, $itemtype) } } - - public static function addFileFromTemplate( - $mappings, - $template, - $directory, - $filename - ) { - if (!empty($mappings)) { - $file_read = @fopen(GENERICOBJECT_DIR . $template, "rt"); - if ($file_read) { - $template_file = fread($file_read, filesize(GENERICOBJECT_DIR . $template)); - foreach ($mappings as $name => $value) { - $template_file = str_replace("%%$name%%", $value, $template_file); - } - fclose($file_read); - $file_write = @fopen($directory . "/" . $filename . ".php", "w"); - if ($file_write) { - fwrite($file_write, $template_file); - fclose($file_write); - } - } - } - } - - - public static function addDatainjectionFile($name) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name), - 'INJECTIONCLASS' => self::getClassByName($name) . "Injection" - ], - self::OBJECTINJECTION_TEMPLATE, - GENERICOBJECT_CLASS_PATH, - self::getSystemName($name) . "injection.class" - ); - } - - - public static function addDropdownFrontFile($name) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name)], - self::FRONT_DROPDOWN_TEMPLATE, - GENERICOBJECT_FRONT_PATH, - self::getSystemName($name) - ); - } - - - public static function addAjaxFile($name, $field) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name)], - self::AJAX_TEMPLATE, - GENERICOBJECT_AJAX_PATH, - self::getSystemName($name) . ".tabs" - ); - } - - - public static function addDropdownFrontformFile($name) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name)], - self::FRONTFORM_DROPDOWN_TEMPLATE, - GENERICOBJECT_FRONT_PATH, - self::getSystemName($name) . ".form" - ); - } - - - public static function addDropdownClassFile($name, $field, $options) - { - $params['is_tree'] = false; - $params['realname'] = false; - $params['linked_itemtype'] = false; - foreach ($options as $key => $value) { - $params[$key] = $value; - } - self::addFileFromTemplate([ - 'CLASSNAME' => self::getClassByName($name), - 'EXTENDS' => - 'PluginGenericobject' . ($params['is_tree'] ? 'CommonTree' : 'Common') . 'Dropdown', - 'FIELDNAME' => $params['realname'], - 'LINKED_ITEMTYPE' => $params['linked_itemtype'] - ], self::CLASS_DROPDOWN_TEMPLATE, GENERICOBJECT_CLASS_PATH, self::getSystemName($name) . ".class"); - } - - - /** - * Write on the the class file for the new object type - * @param string $name the name of the object type - * @param string $classname the name of the new object - * @return void - */ - public static function addClassFile($name, $classname) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name)], - self::CLASS_TEMPLATE, - GENERICOBJECT_CLASS_PATH, - self::getSystemName($name) . ".class" - ); - } - - /** - * Write on the the _Item class file for the new object type - * @param string $name the name of the object type - * @param string $classname the name of the new object - * @return void - */ - public static function addItemClassFile($name, $classname) - { - $class = self::getClassByName($name) . "_Item"; - self::addFileFromTemplate( - ['CLASSNAME' => $class, - 'FOREIGNKEY' => getForeignKeyFieldForItemType($classname), - 'SOURCEOBJECT' => $classname - ], - self::OBJECTITEM_TEMPLATE, - GENERICOBJECT_CLASS_PATH, - self::getSystemName($name) . "_item.class" - ); - } - - /** - * Write on the the form file for the new object type - * @param string $name the name of the object type - * @param string $classname the name of the new object - * @return void - */ - public static function addFormFile($name, $classname) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name)], - self::FORM_TEMPLATE, - GENERICOBJECT_FRONT_PATH, - self::getSystemName($name) . ".form" - ); - } - - - /** - * Write on the the form file for the new object type - * @param string $name the name of the object type - * @param string $classname the name of the new object - * @return void - */ - public static function addSearchFile($name, $classname) - { - self::addFileFromTemplate( - ['CLASSNAME' => self::getClassByName($name)], - self::SEARCH_TEMPLATE, - GENERICOBJECT_FRONT_PATH, - self::getSystemName($name) - ); - } - - - /** - * Create, if needed files for an itemtype and it's dropdown - * - * @since 2.2.0 - * - * @return void - */ - public static function checkClassAndFilesForItemType() - { - foreach (self::getTypes(true) as $type) { - //ensure old files has been removed, - $fsname = self::getSystemName($type['name']); - if (file_exists(GENERICOBJECT_DIR . "/inc/{$fsname}.class.php")) { - unlink(GENERICOBJECT_DIR . "/inc/{$fsname}.class.php"); - } - if (file_exists(GENERICOBJECT_DIR . "/front/{$fsname}.form.php")) { - unlink(GENERICOBJECT_DIR . "/front/{$fsname}.form.php"); - } - if (file_exists(GENERICOBJECT_DIR . "/front/{$fsname}.php")) { - unlink(GENERICOBJECT_DIR . "/front/{$fsname}.form.php"); - } - if (file_exists(GENERICOBJECT_DIR . "/ajax/{$fsname}.tabs.php")) { - unlink(GENERICOBJECT_DIR . "/ajax/{$fsname}.tabs.php"); - } - if (file_exists(GENERICOBJECT_DIR . "/inc/{$fsname}.injection.class.php")) { - unlink(GENERICOBJECT_DIR . "/inc/{$fsname}.injection.class.php"); - } - - self::checkClassAndFilesForOneItemType($type['itemtype'], $type['name'], true, false); - } - } - - /** - * - * Create or overwrite files for an itemtype - * @since 2.2.0 - * @param string $itemtype the itemtype to check - * @param string $name type's short name - * @param boolean $overwrite force to overwrite existing files - * @param boolean $overwrite_locales force to overwrite existing locales - * @return void - */ - public static function checkClassAndFilesForOneItemType($itemtype, $name, $overwrite = false, $overwrite_locales = true) - { - /** @var DBmysql $DB */ - global $DB; - $table = getTableForItemType($itemtype); - - //If class doesn't exist but table exists, create class - if ($DB->tableExists($table) && ($overwrite || !class_exists($itemtype))) { - self::addNewObject($name, $itemtype, ['add_table' => false, - 'create_default_profile' => false, - 'add_injection_file' => $overwrite, - 'add_language_file' => false, - 'overwrite_locales' => $overwrite_locales - ]); - } - - foreach ($DB->listFields($table) as $field => $options) { - if (preg_match("/s_id$/", $field)) { - $dropdowntable = getTableNameForForeignKeyField($field); - $dropdownclass = getItemTypeForTable($dropdowntable); - - if ($DB->tableExists($dropdowntable) && ! class_exists($dropdownclass)) { - $name = str_replace("glpi_plugin_genericobject_", "", $dropdowntable); - $name = getSingular($name); - $params = PluginGenericobjectField::getFieldOptions($field, $dropdownclass); - if ( - isset($params['dropdown_type']) - and $params['dropdown_type'] === 'isolated' - ) { - $params['linked_itemtype'] = $itemtype; - } - self::addNewDropdown($name, self::getClassByName($name), $params); - } - } - } - } - /** * * Delete all files and classes for an itemtype (including dropdowns) @@ -1073,71 +265,14 @@ public static function deleteFilesAndClassesForOneItemtype($name) public static function deleteItemtypeReferencesInGLPI($itemtype) { //Delete references to PluginGenericobjectType in the following tables - $itemtypes = ["Contract_Item", "DisplayPreference", "Document_Item", "SavedSearch", "Log"]; - foreach ($itemtypes as $type) { - $item = new $type(); - $item->deleteByCriteria(['itemtype' => $itemtype]); - } - } - - //-------------------- ADD / DELETE TABLES ----------------------------------// - - /** - * Add a new dropdown table - * @param string $table the table name - * @param array $options - * @return void - */ - public static function addDropdownTable($table, $options = []) - { - /** @var DBmysql $DB */ - global $DB; - - $default_charset = DBConnection::getDefaultCharset(); - $default_collation = DBConnection::getDefaultCollation(); - $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); - - $params['entities_id'] = false; - $params['is_recursive'] = false; - $params['is_tree'] = false; - foreach ($options as $key => $value) { - $params[$key] = $value; - } - - if (!$DB->tableExists($table)) { - $query = "CREATE TABLE IF NOT EXISTS `$table` ( - `id` int {$default_key_sign} NOT NULL auto_increment, - `name` varchar(255) default NULL, - `comment` text, - `date_mod` TIMESTAMP NULL DEFAULT NULL, - `date_creation` TIMESTAMP NOT NULL, - PRIMARY KEY (`id`), - KEY `date_mod` (`date_mod`), - KEY `date_creation` (`date_creation`), - KEY `name` (`name`) - ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query); - } - if ($params['entities_id']) { - $query = "ALTER TABLE `$table` ADD `entities_id` INT {$default_key_sign} NOT NULL DEFAULT '0'"; - $DB->query($query); - if ($params['is_recursive']) { - $query = "ALTER TABLE `$table` " . - "ADD `is_recursive` TINYINT NOT NULL DEFAULT '0' AFTER `entities_id`"; - $DB->query($query); - } - } - if ($params['is_tree']) { - $fk = getForeignKeyFieldForTable($table); - $query = "ALTER TABLE `$table` ADD `completename` text, - ADD `$fk` int {$default_key_sign} NOT NULL DEFAULT '0', - ADD `level` int NOT NULL DEFAULT '0', - ADD `ancestors_cache` longtext, - ADD `sons_cache` longtext"; - $DB->query($query); + $itemtypes = ["Contract_Item", "DisplayPreference", "Document_Item", "SavedSearch", "Log"]; + foreach ($itemtypes as $type) { + $item = new $type(); + $item->deleteByCriteria(['itemtype' => $itemtype]); } } + //-------------------- ADD / DELETE TABLES ----------------------------------// /** * Delete object type table + entries in glpi_display @@ -1151,7 +286,7 @@ public static function deleteTable($itemtype) _log($itemtype); $preferences = new DisplayPreference(); $preferences->deleteByCriteria(["itemtype" => $itemtype]); - $DB->query("DROP TABLE IF EXISTS `" . getTableForItemType($itemtype) . "`"); + $DB->doQuery("DROP TABLE IF EXISTS `" . getTableForItemType($itemtype) . "`"); } @@ -1164,29 +299,9 @@ public static function deleteItemsTable($itemtype) { /** @var DBmysql $DB */ global $DB; - $DB->query("DROP TABLE IF EXISTS `" . getTableForItemType($itemtype) . "_items`"); - } - - /** - * Get object name by ID - * @param string $itemtype - * @return string the name associated with the ID - */ - public static function getNameByID($itemtype) - { - /** @var DBmysql $DB */ - global $DB; - $query = "SELECT `name` FROM `" . getTableForItemType(__CLASS__) . "` " . - "WHERE `itemtype`='$itemtype'"; - $result = $DB->query($query); - if ($DB->numrows($result)) { - return $DB->result($result, 0, "name"); - } else { - return ""; - } + $DB->doQuery("DROP TABLE IF EXISTS `" . getTableForItemType($itemtype) . "_items`"); } - /** * Delete all tickets for an itemtype * @param string $itemtype @@ -1369,27 +484,6 @@ public static function getClassByName($name) return 'PluginGenericobject' . ucfirst(self::getSystemName($name)); } - - public static function getFamilyNameByItemtype($itemtype) - { - $types = getAllDataFromTable( - "glpi_plugin_genericobject_types", - ['itemtype' => $itemtype, 'is_active' => 1] - ); - if (empty($types)) { - return false; - } else { - $type = array_pop($types); - if ($type['plugin_genericobject_typefamilies_id'] > 0) { - $family = new PluginGenericobjectTypeFamily(); - $family->getFromDB($type['plugin_genericobject_typefamilies_id']); - return $family->getName(); - } else { - return false; - } - } - } - /** * Get all types of active&published objects */ @@ -1417,368 +511,8 @@ public static function getTypes($all = false) } } - /** - * Get all types of active&published objects - * order by family - */ - public static function getTypesByFamily($all = false) - { - /** @var DBmysql $DB */ - global $DB; - $table = getTableForItemType(__CLASS__); - if ($DB->tableExists($table)) { - $mytypes = []; - foreach (getAllDataFromTable($table, (!$all ? ['is_active' => self::ACTIVE] : [])) as $data) { - //If class is not present on the filesystem, do not list itemtype - if (file_exists(self::getCompleteClassFilename($data['name']))) { - $mytypes[$data['plugin_genericobject_typefamilies_id']][$data['itemtype']] = $data; - } - } - return $mytypes; - } else { - return []; - } - } - - public static function getTypesForFormcreator($param) - { - $families = PluginGenericobjectTypeFamily::getFamilies(); - $familyFk = PluginGenericobjectTypeFamily::getForeignKeyField(); - foreach (self::getTypes() as $type => $typeData) { - $familyName = isset($families[$typeData[$familyFk]]) - ? $families[$typeData[$familyFk]] - : _n('Other', 'Others', Session::getPluralNumber(), 'genericobject'); - $param[$familyName][$type] = $typeData['name']; - } - return $param; - } - - /** - * Register all variables for a type - * @param string $itemtype the type's attributes - * @return void - */ - public static function registerOneType($itemtype) - { - //If table doesn't exists, do not try to register ! - if (class_exists($itemtype)) { - $itemtype::registerType(); - } - } - - - /** - * Include locales for a specific type - * @name object type's name - * @return void - */ - public static function includeLocales($name) - { - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - - $fsname = self::getSystemName($name); - - $prefix = GENERICOBJECT_LOCALES_PATH . "/$fsname/$fsname"; - //Dirty hack because the plugin doesn't support gettext... - $language = str_replace('.mo', '', $CFG_GLPI["languages"][$_SESSION["glpilanguage"]][1]); - if ( - isset($_SESSION["glpilanguage"]) - && file_exists("$prefix.$language.php") - ) { - include_once("$prefix.$language.php"); - } else { - if (file_exists($prefix . ".en_GB.php")) { - include_once($prefix . ".en_GB.php"); - } else { - if (file_exists($prefix . ".fr_FR.php")) { - include_once($prefix . ".fr_FR.php"); - } else { - return false; - } - } - } - return true; - } - - - public static function includeConstants($name, $force = false) - { - - $file = self::getCompleteConstantFilename($name); - if (file_exists($file)) { - if (!$force) { - include_once($file); - } else { - include($file); - } - } - } - - - /** - * Get all dropdown fields associated with an itemtype - * @param string $itemtype the itemtype - * @return array or fields that represents the dropdown tables - */ - public static function getDropdownForItemtype($itemtype) - { - $associated_tables = []; - if (class_exists($itemtype)) { - $source_table = getTableForItemType($itemtype); - foreach (PluginGenericobjectSingletonObjectField::getInstance($itemtype) as $field => $value) { - $table = getTableNameForForeignKeyField($field); - $options = PluginGenericobjectField::getFieldOptions($field, $itemtype); - if ( - isset($options['input_type']) - and $options['input_type'] === 'dropdown' - and preg_match('/^glpi_plugin_genericobject/', $table) - ) { - $associated_tables[] = $table; - } - } - } - return $associated_tables; - } - - - public static function deleteDropdownsForItemtype($itemtype) - { - /** @var DBmysql $DB */ - global $DB; - //Foreach dropdown : drop table & remove files ! - foreach (self::getDropdownForItemtype($itemtype) as $table) { - $results = []; - if ( - preg_match("/glpi_plugin_genericobject_(.*)/i", getSingular($table), $results) - && isset($results[1]) - ) { - $name = $results[1]; - $DB->query("DROP TABLE IF EXISTS `$table`"); - self::deleteFormFile($name); - self::deleteSearchFile($name); - self::deleteClassFile($name); - } - } - - // Invalidate submenu data in current session for minor cleanup - unset($_SESSION['glpimenu']); - } - //------------------------------- GETTERS -------------------------// - - public function canUseTickets() - { - return $this->fields['use_tickets']; - } - - public function canBeLinked() - { - return $this->fields['use_links']; - } - - public function canUseTemplate() - { - /** @var DBmysql $DB */ - global $DB; - return $DB->fieldExists(getTableForItemType($this->fields['itemtype']), 'is_template'); - } - - - public function canUseUnicity() - { - return $this->fields['use_unicity']; - } - - - public function canBeDeleted() - { - /** @var DBmysql $DB */ - global $DB; - return $DB->fieldExists(getTableForItemType($this->fields['itemtype']), 'is_deleted'); - } - - - public function canBeEntityAssigned() - { - /** @var DBmysql $DB */ - global $DB; - return $DB->fieldExists(getTableForItemType($this->fields['itemtype']), 'entities_id'); - } - - - public function canBeRecursive() - { - /** @var DBmysql $DB */ - global $DB; - return $DB->fieldExists(getTableForItemType($this->fields['itemtype']), 'is_recursive'); - } - - - public function canBeReserved() - { - return $this->fields['use_loans']; - } - - - public function canUseNotepad() - { - return $this->fields['use_notepad'] != 0; - } - - - public function canUseHistory() - { - return $this->fields['use_history']; - } - - - public function canUseDocuments() - { - return $this->fields['use_documents']; - } - - - public function canUseInfocoms() - { - return $this->fields['use_infocoms']; - } - - public function canUseItemDevice() - { - return $this->fields['use_itemdevices']; - } - - public function canUseImpact() - { - return Impact::isEnabled($this->fields['itemtype']); - } - - public function canUseContracts() - { - return $this->fields['use_contracts']; - } - - - public function canUseGlobalSearch() - { - return $this->fields['use_global_search']; - } - - - public function canUseNetworkPorts() - { - return $this->fields['use_network_ports']; - } - - - public function canUseDirectConnections() - { - return $this->fields['use_direct_connections']; - } - - public function canUseProjects() - { - return $this->fields['use_projects']; - } - - public function canUsePluginDataInjection() - { - if (!Plugin::isPluginActive("datainjection")) { - return false; - } - return $this->fields['use_plugin_datainjection']; - } - - - public function canUsePluginOrder() - { - if (!Plugin::isPluginActive("order")) { - return false; - } - return $this->fields['use_plugin_order']; - } - - - public function canUsePluginPDF() - { - if (!Plugin::isPluginActive("pdf")) { - return false; - } - return $this->fields['use_plugin_pdf']; - } - - - public function canUsePluginUninstall() - { - if (!Plugin::isPluginActive("uninstall")) { - return false; - } - return $this->fields['use_plugin_uninstall']; - } - - public function canUsePluginSimcard() - { - if (!Plugin::isPluginActive("simcard")) { - return false; - } - return $this->fields['use_plugin_simcard']; - } - - public function canUsePluginTreeview() - { - if (!Plugin::isPluginActive("treeview")) { - return false; - } - return $this->fields['use_plugin_treeview']; - } - - public function canUsePluginGeninventoryNumber() - { - if (!Plugin::isPluginActive("geninventorynumber")) { - return false; - } - return $this->fields['use_plugin_geninventorynumber']; - } - - - public function isTransferable() - { - return Session::isMultiEntitiesMode(); - } - - public function getLinkedItemTypesAsArray() - { - if (!empty($this->fields['linked_itemtypes'])) { - return json_decode($this->fields['linked_itemtypes'], true); - } else { - return []; - } - } - - public static function canViewAtLeastOneType() - { - $types = self::getTypes(); - $view = false; - foreach ($types as $ID => $value) { - if (Session::haveRight($value['itemtype'], READ)) { - $view = true; - break; - } - } - return $view; - } - - /** - * Display debug information for current object - **/ - public function showDebug() - { - $this->showFilesForm(); - //NotificationEvent::debugEvent($this); - } //------------------------------- INSTALL / UNINSTALL METHODS -------------------------// - public static function install(Migration $migration) { /** @var DBmysql $DB */ @@ -1850,23 +584,11 @@ public static function install(Migration $migration) //Normalize names and itemtypes (prior to using them). self::normalizeNamesAndItemtypes($migration); - //If files are missing, recreate them! - self::checkClassAndFilesForItemType(); - // Migrate notepad data $allGenericObjectTypes = PluginGenericobjectType::getTypes(true); $notepad = new Notepad(); foreach ($allGenericObjectTypes as $genericObjectType => $genericObjectData) { - $itemtype = $genericObjectData['itemtype']; - if (! class_exists($itemtype, true)) { - // TRANS: %1$s is itemtype name - $warning = sprintf(__('Unable to load the class %1$s.', 'genericobject'), $itemtype); - // TRANS: %1$s is itemtype name - $warning .= sprintf(__('You probably have garbage data in your database for this plugin and missing files in %1$s', 'genericobject'), GENERICOBJECT_DOC_DIR); - $migration->displayWarning($warning, true); - die(); - } $genericObjectTypeInstance = new $genericObjectType(); if ($DB->fieldExists($genericObjectTypeInstance->getTable(), "notepad")) { $query = "INSERT INTO `" . $notepad->getTable() . "` @@ -2196,80 +918,4 @@ private static function updateNameAndItemtype( ); } } - - /** - * Given an impact icon filename, return the expected full or relative path - * where it should be stored - * - * @param string $filename - * @param string $itemtype Impact itemtype, needed to avoid filename colision - * @param bool $relative (default: false) - * - * @return null|string - */ - public static function getImpactIconFileStoragePath( - ?string $filename, - string $itemtype, - bool $relative = false - ): ?string { - if (empty($filename)) { - return null; - } - - // Make sure $filename does not contains any directory changes like ".." - if ($filename != pathinfo($filename)['basename']) { - trigger_error( - "Trying to access forbidden file: $filename", - E_USER_WARNING - ); - return null; - } - - $filename = "{$itemtype}_{$filename}"; - $path = GLPI_PLUGIN_DOC_DIR . "/genericobject/impact_icons/$filename"; - - if ($relative) { - $path = str_replace(GLPI_ROOT, "", $path); - } - - return $path; - } - - /** - * Get file path to impact icon file - * - * @return string|null - */ - public function getImpactIconFilePath(): ?string - { - if (empty($this->fields['impact_icon'])) { - return null; - } - - $path = self::getImpactIconFileStoragePath( - $this->fields['impact_icon'], - $this->fields['itemtype'] - ); - if (empty($path) || !file_exists($path)) { - return null; - } - - return $path; - } - - /** - * Get public URL to impact icon file - * - * @return null|string - */ - public function getImpactIconUrl($full = true): ?string - { - // Check that the file exist - if (!$this->getImpactIconFilePath()) { - return null; - } - - return Plugin::getWebDir('genericobject', $full) . "/front/getimpacticon.php?itemtype=" . $this->fields['itemtype']; - } - } diff --git a/index.php b/index.php index cf9e4c8e..dba0bcb9 100644 --- a/index.php +++ b/index.php @@ -28,66 +28,17 @@ * ------------------------------------------------------------------------- */ -define('GLPI_ROOT', '../..'); -include(GLPI_ROOT . "/inc/includes.php"); +include('../../inc/includes.php'); -if (isset($_GET['itemtypes_id']) && $_GET['itemtypes_id'] != '') { - $type = new PluginGenericobjectType(); - $type->getFromDB($_GET['itemtypes_id']); - Html::redirect(Toolbox::getItemTypeSearchURL($type->fields['itemtype'])); -} else { - $types = PluginGenericobjectType::getTypesByFamily(); - foreach ($types as $family => $typeData) { - foreach ($typeData as $ID => $value) { - if (!Session::haveRight($value['itemtype'], READ)) { - unset($types[$family][$ID]); - } - } - } +// Check if user has admin rights +Session::checkRight('config', UPDATE); - //There's only one family - if (count($types) == 1) { - //There's only one itemtype ? If yes, then automatically - //redirect to the search engine - if (key($types) == null) { - $mytypes = $types; - $tmp = array_pop($mytypes); - if (count($tmp) == 1) { - Html::redirect(Toolbox::getItemTypeSearchURL(key($tmp))); - } - } - } +// Show EOL message +$message = sprintf( + __('GenericObject v%s is End-of-Life. All form functionality is now available in GLPI 11 core. Check migration status or use native forms.', 'genericobject'), + PLUGIN_GENERICOBJECT_VERSION +); +Session::addMessageAfterRedirect($message, true, WARNING); - Html::header( - __("Objects management", "genericobject"), - $_SERVER['PHP_SELF'], - "plugins", - "genericobject" - ); - - foreach ($types as $family => $typeData) { - $PluginGenericobjectTypefamily = new PluginGenericobjectTypefamily(); - $PluginGenericobjectTypefamily->getFromDB($family); - - echo "
" . __("Link to other objects", "genericobject") . "
" . _n("Type", "Types", 2) . ""; - echo ""; - echo "
"; - if ($family == 0) { - echo ""; - } else { - echo ""; - } - if (!count($types)) { - echo ""; - } else { - foreach ($typeData as $ID => $value) { - echo ""; - } - } - echo "
" . __("Empty family", "genericobject") . "
" . $PluginGenericobjectTypefamily->getField("name") . "
" . __("No item to display") . "
"; - echo ""; - $itemtype = $value['itemtype']; - echo $itemtype::getTypeName(); - echo "
"; - } - - Html::footer(); -} +// Redirect to migration status page +Html::redirect($CFG_GLPI['root_doc'] . '/plugins/genericobject/front/migration_status.php'); diff --git a/objects/front.form.tpl b/objects/front.form.tpl deleted file mode 100644 index d1d50e6c..00000000 --- a/objects/front.form.tpl +++ /dev/null @@ -1,35 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ - -/** - * This file is automatically managed by genericobject plugin. Do not edit it ! - */ - -include ("../../../inc/includes.php"); - -$dropdown = new %%CLASSNAME%%(); -include (GLPI_ROOT . "/front/dropdown.common.form.php"); diff --git a/objects/front.tpl b/objects/front.tpl deleted file mode 100644 index 6a132b91..00000000 --- a/objects/front.tpl +++ /dev/null @@ -1,38 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ -include ("../../../inc/includes.php"); - -/** - * This file is automatically managed by genericobject plugin. Do not edit it ! - */ - -Html::header(%%CLASSNAME%%::getTypeName(), $_SERVER['PHP_SELF'], "plugins", "genericobject", - "%%CLASSNAME%%"); - -Search::show('%%CLASSNAME%%'); - -Html::footer(); diff --git a/objects/generic.class.tpl b/objects/generic.class.tpl deleted file mode 100644 index c8d14ef6..00000000 --- a/objects/generic.class.tpl +++ /dev/null @@ -1,45 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ - -/** - * This class is automatically managed by genericobject plugin. Do not edit it ! - */ -class %%CLASSNAME%% extends PluginGenericobjectObject { - - static $rightname = ''; - - static function getFormURL($full=true) { - return Toolbox::getItemTypeFormURL( parent::class , $full) . - "?itemtype=".get_called_class(); - } - static function getSearchURL($full=true) { - return Toolbox::getItemTypeSearchURL( parent::class , $full) . - "?itemtype=".get_called_class(); - - } -} - diff --git a/objects/generic.dropdown.class.tpl b/objects/generic.dropdown.class.tpl deleted file mode 100644 index de972f69..00000000 --- a/objects/generic.dropdown.class.tpl +++ /dev/null @@ -1,33 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ - -/** - * This class is automatically managed by genericobject plugin. Do not modify it ! - */ -class %%CLASSNAME%% extends %%EXTENDS%% { - public $linked_itemtype = "%%LINKED_ITEMTYPE%%"; -} diff --git a/objects/generic.form.tpl b/objects/generic.form.tpl deleted file mode 100644 index 1daf17fb..00000000 --- a/objects/generic.form.tpl +++ /dev/null @@ -1,35 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ - -/** - * This file is automatically managed by genericobject plugin. Do not edit it ! - */ - -include ("../../../inc/includes.php"); - -$item = new %%CLASSNAME%%(); -include (GENERICOBJECT_DIR."/front/object.form.php"); diff --git a/objects/locale.tpl b/objects/locale.tpl deleted file mode 100644 index 0e90ecaa..00000000 --- a/objects/locale.tpl +++ /dev/null @@ -1,29 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ -global $LANG; - -$LANG['genericobject']['%%CLASSNAME%%'][0]="%%NAME%%"; diff --git a/objects/object_item.class.tpl b/objects/object_item.class.tpl deleted file mode 100644 index 0131e4fd..00000000 --- a/objects/object_item.class.tpl +++ /dev/null @@ -1,44 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ - -if (!defined('GLPI_ROOT')){ - die("Sorry. You can't access directly to this file"); -} - -class %%CLASSNAME%% extends PluginGenericobjectObject_Item { - - public $dohistory = true; - - // From CommonDBRelation - static public $itemtype_1 = '%%SOURCEOBJECT%%'; - static public $items_id_1 = '%%FOREIGNKEY%%'; - - static public $itemtype_2 = 'itemtype'; - static public $items_id_2 = 'items_id'; - static public $checkItem_2_Rights = self::HAVE_VIEW_RIGHT_ON_ITEM; -} - diff --git a/objects/objectinjection.class.tpl b/objects/objectinjection.class.tpl deleted file mode 100644 index 5ee3fa5c..00000000 --- a/objects/objectinjection.class.tpl +++ /dev/null @@ -1,91 +0,0 @@ -. - -------------------------------------------------------------------------- - @package genericobject - @author the genericobject plugin team - @copyright Copyright (c) 2010-2017 Genericobject plugin team - @license GPLv2+ - http://www.gnu.org/licenses/gpl.txt - @link https://github.com/pluginsGLPI/genericobject - @link http://www.glpi-project.org/ - @since 2009 - ---------------------------------------------------------------------- */ - -/** - * This file is automatically managed by genericobject plugin. Do not edit it ! - */ - -if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); -} - -class %%INJECTIONCLASS%% extends %%CLASSNAME%% - implements PluginDatainjectionInjectionInterface { - - static function getTable($classname = null) { - - $parenttype = get_parent_class(); - return $parenttype::getTable(); - - } - - function isPrimaryType() { - return true; - } - - function connectedTo() { - return []; - } - - /** - * Standard method to add an object into glpi - * - * @param values fields to add into glpi - * @param options options used during creation - * @return an array of IDs of newly created objects : for example [Computer=>1, Networkport=>10] - * - **/ - function addOrUpdateObject($values = [], $options = []) { - - $lib = new PluginDatainjectionCommonInjectionLib($this, $values, $options); - $lib->processAddOrUpdate(); - return $lib->getInjectionResults(); - } - - /** - * Get search options formatted for injection mapping usage in datainjection plugin. - * - * @return array - */ - function getOptions($primary_type = '') { - $plugin = new Plugin(); - if (!$plugin->isActivated('datainjection')) { - return []; - } - - return PluginDatainjectionCommonInjectionLib::addToSearchOptions( - Search::getOptions(get_parent_class($this)), - [ - 'ignore_fields' => PluginDatainjectionCommonInjectionLib::getBlacklistedOptions( - get_parent_class($this) - ), - ], - $this - ); - } - -} diff --git a/setup.php b/setup.php index 7076ff08..a4065292 100644 --- a/setup.php +++ b/setup.php @@ -133,64 +133,11 @@ function plugin_init_genericobject() $GENERICOBJECT_PDF_TYPES = []; if (Plugin::isPluginActive("genericobject") && isset($_SESSION['glpiactiveprofile'])) { - //if treeview is installed - if (Plugin::isPluginActive("treeview") && class_exists('PluginTreeviewConfig')) { - //foreach type in genericobject - foreach (PluginGenericobjectType::getTypes() as $itemtype => $value) { - //check if location_id field exist - $fields_in_db = PluginGenericobjectSingletonObjectField::getInstance($itemtype); - $objecttype = PluginGenericobjectType::getInstance($itemtype); - if (isset($fields_in_db['locations_id']) && $objecttype->canUsePluginTreeview()) { - //register class - PluginTreeviewConfig::registerType($itemtype); - $PLUGIN_HOOKS['treeview'][$itemtype] = Plugin::getWebDir('genericobject') . '/pics/default-icon16.png'; - } - } - } - - $PLUGIN_HOOKS['change_profile']['genericobject'] = [ - 'PluginGenericobjectProfile', - 'changeProfile' - ]; - - plugin_genericobject_includeCommonFields(); // Config page if (Session::haveRight('config', READ)) { $PLUGIN_HOOKS['config_page']['genericobject'] = 'front/eol_info.php'; } - - $PLUGIN_HOOKS['post_init']['genericobject'] = 'plugin_post_init_genericobject'; - - // Add every genericobject item's to the list of itemtypes for which the - // impact analysis can be enabled - foreach ((new PluginGenericobjectType())->find([]) as $row) { - if (empty($row['impact_icon'])) { - $icon = ""; // Will fallback to default impact icon - } else { - $obj = new PluginGenericobjectType(); - $obj->getFromDB($row['id']); - $icon = $obj->getImpactIconUrl(false) ?? ""; - } - - $CFG_GLPI['impact_asset_types'][$row['itemtype']] = $icon; - } - } -} - -function plugin_post_init_genericobject() -{ - Plugin::registerClass( - 'PluginGenericobjectProfile', - ['addtabon' => ['Profile', 'PluginGenericobjectType']] - ); - - - foreach (PluginGenericobjectType::getTypes() as $id => $objecttype) { - $itemtype = $objecttype['itemtype']; - if (class_exists($itemtype)) { - $itemtype::registerType(); - } } } @@ -218,39 +165,3 @@ function plugin_version_genericobject() ]; } -function plugin_genericobject_includeCommonFields($force = false) -{ - $includes = [ - sprintf('%s/fields/field.constant.php', GENERICOBJECT_DIR), // Default common fields constants - ]; - - // User locales for common fields - if ( - isset($_SESSION['glpilanguage']) - && file_exists($locale_file = sprintf('%s/fields.%s.php', GENERICOBJECT_LOCALES_PATH, $_SESSION['glpilanguage'])) - ) { - $includes[] = $locale_file; - } elseif (file_exists($locale_file = sprintf('%s/fields.%s.php', GENERICOBJECT_LOCALES_PATH, 'en_GB'))) { - $includes[] = $locale_file; - } - - // User common fields constants - if (file_exists($fields_file = sprintf('%s/field.constant.php', GENERICOBJECT_FIELDS_PATH))) { - $includes[] = $fields_file; - } - - foreach ($includes as $include) { - if (!$force) { - include_once($include); - } else { - include($include); - } - } -} - -function plugin_genericobject_haveRight($class, $right) -{ - - $right_name = PluginGenericobjectProfile::getProfileNameForItemtype($class); - return Session::haveRight($right_name, $right); -} diff --git a/templates/migration_status.html.twig b/templates/migration_status.html.twig index 657d00ea..f8225a71 100644 --- a/templates/migration_status.html.twig +++ b/templates/migration_status.html.twig @@ -194,11 +194,9 @@

{{ __('Migration Process', 'genericobject') }}

    -
  • {{ __('Form structure and fields will be converted', 'genericobject') }}
  • -
  • {{ __('Form categories will be preserved', 'genericobject') }}
  • -
  • {{ __('Access control rules will be migrated', 'genericobject') }}
  • -
  • {{ __('Form submissions will be preserved', 'genericobject') }}
  • -
  • {{ __('Complex validations may need manual recreation', 'genericobject') }}
  • +
  • {{ __('Generic objects will be converted into custom assets', 'genericobject') }}
  • +
  • {{ __('Types will be retained.', 'genericobject') }}
  • +
  • {{ __('Asset data will not be lost', 'genericobject') }}
@@ -230,11 +228,11 @@
  • - {{ __('Review converted forms in GLPI 11', 'genericobject') }} + {{ __('Review converted assets in GLPI 11', 'genericobject') }}
  • - {{ __('Test form access permissions', 'genericobject') }} + {{ __('Test asset access permissions', 'genericobject') }}
@@ -246,7 +244,7 @@
  • - {{ __('Train users on GLPI 11 native forms', 'genericobject') }} + {{ __('Train users on GLPI 11 native custom assets', 'genericobject') }}
  • From bd7ceae4d4f4a871265507c583f53b8e9c832d95 Mon Sep 17 00:00:00 2001 From: MyuTsu Date: Thu, 18 Sep 2025 14:18:49 +0200 Subject: [PATCH 03/15] glpi11 compat --- composer.json | 2 +- composer.lock | 14 +++++++------- front/eol_info.php | 2 -- front/migration_status.php | 2 -- hook.php | 11 ++++------- inc/profile.class.php | 4 +--- inc/singletonobjectfield.class.php | 2 +- inc/type.class.php | 24 +++++++++++++++--------- inc/typefamily.class.php | 9 +++------ index.php | 2 -- setup.php | 16 +--------------- 11 files changed, 33 insertions(+), 55 deletions(-) diff --git a/composer.json b/composer.json index abca2fb8..22a05260 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "config": { "optimize-autoloader": true, "platform": { - "php": "8.2" + "php": "8.2.99" }, "sort-packages": true, "allow-plugins": { diff --git a/composer.lock b/composer.lock index ba86048f..40dd33d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2927360dc294aa405d9de557d182b3d8", + "content-hash": "12e9648115cb86923112bba1ec364a38", "packages": [], "packages-dev": [ { @@ -223,16 +223,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.23", + "version": "2.1.27", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5" + "reference": "25da374959afa391992792691093550b3098ef1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a34502adbbd5c2366b5a97679848a5ace4f6f2f5", - "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/25da374959afa391992792691093550b3098ef1e", + "reference": "25da374959afa391992792691093550b3098ef1e", "shasum": "" }, "require": { @@ -277,7 +277,7 @@ "type": "github" } ], - "time": "2025-09-10T11:42:22+00:00" + "time": "2025-09-17T09:55:13+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -1311,7 +1311,7 @@ }, "platform-dev": {}, "platform-overrides": { - "php": "8.2" + "php": "8.2.99" }, "plugin-api-version": "2.6.0" } diff --git a/front/eol_info.php b/front/eol_info.php index 0a7cf12e..f26b1d5e 100644 --- a/front/eol_info.php +++ b/front/eol_info.php @@ -7,8 +7,6 @@ * --------------------------------------------------------------------- */ -include('../../../inc/includes.php'); - // Check if user has admin rights Session::checkRight('config', READ); diff --git a/front/migration_status.php b/front/migration_status.php index 4f37bb22..5182204e 100644 --- a/front/migration_status.php +++ b/front/migration_status.php @@ -8,8 +8,6 @@ * --------------------------------------------------------------------- */ -include('../../../inc/includes.php'); - use Glpi\Application\View\TemplateRenderer; use Glpi\Asset\AssetDefinition; diff --git a/hook.php b/hook.php index bc50802d..31ced9de 100644 --- a/hook.php +++ b/hook.php @@ -63,18 +63,13 @@ function plugin_genericobject_install() } } - if (!is_dir(GENERICOBJECT_CLASS_PATH)) { - @ mkdir(GENERICOBJECT_CLASS_PATH, 0755, true) - or die("Can't create folder " . GENERICOBJECT_CLASS_PATH); - } - // Add icon directory $icons_dir = GLPI_PLUGIN_DOC_DIR . '/genericobject/impact_icons/'; if (!is_dir($icons_dir)) { mkdir($icons_dir); } - //Init plugin & types + //Init plugin plugin_init_genericobject(); return true; @@ -123,7 +118,9 @@ function plugin_genericobject_uninstall() // Delete all models of datainjection about genericobject $table_datainjection_model = 'glpi_plugin_datainjection_models'; if ($DB->tableExists($table_datainjection_model)) { - $DB->query("DELETE FROM $table_datainjection_model WHERE itemtype LIKE 'PluginGenericobject%'"); + $DB->delete($table_datainjection_model, [ + 'itemtype' => ['LIKE', 'PluginGenericobject%'] + ]); } // Invalidate menu data in current session diff --git a/inc/profile.class.php b/inc/profile.class.php index 59a2824b..23ef2111 100644 --- a/inc/profile.class.php +++ b/inc/profile.class.php @@ -121,8 +121,6 @@ public static function uninstall() { /** @var DBmysql $DB */ global $DB; - $query = "DELETE FROM `glpi_profilerights` - WHERE `name` LIKE '%plugin_genericobject%'"; - $DB->query($query) or die($DB->error()); + $DB->dropTable('glpi_profilerights'); } } diff --git a/inc/singletonobjectfield.class.php b/inc/singletonobjectfield.class.php index 76f6c650..3131c672 100644 --- a/inc/singletonobjectfield.class.php +++ b/inc/singletonobjectfield.class.php @@ -33,7 +33,7 @@ // Purpose of file: // ---------------------------------------------------------------------- if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + throw new \RuntimeException('Direct access to this file is not allowed'); } class PluginGenericobjectSingletonObjectField diff --git a/inc/type.class.php b/inc/type.class.php index 28395fa0..d723234b 100644 --- a/inc/type.class.php +++ b/inc/type.class.php @@ -28,6 +28,8 @@ * ------------------------------------------------------------------------- */ +use Glpi\DBAL\QueryExpression; + class PluginGenericobjectType extends CommonDBTM { const INACTIVE = 0; @@ -226,7 +228,7 @@ public static function deleteItemTypeFilesAndClasses($name, $table, $itemtype) if ($table != getTableForItemType("PluginGenericobjectTypeFamily")) { self::deleteFilesAndClassesForOneItemtype(getSingular($results[1])); - $DB->query("DROP TABLE IF EXISTS `$table`"); + $DB->dropTable($table, true); } } } @@ -286,7 +288,7 @@ public static function deleteTable($itemtype) _log($itemtype); $preferences = new DisplayPreference(); $preferences->deleteByCriteria(["itemtype" => $itemtype]); - $DB->doQuery("DROP TABLE IF EXISTS `" . getTableForItemType($itemtype) . "`"); + $DB->dropTable(getTableForItemType($itemtype), true); } @@ -299,7 +301,7 @@ public static function deleteItemsTable($itemtype) { /** @var DBmysql $DB */ global $DB; - $DB->doQuery("DROP TABLE IF EXISTS `" . getTableForItemType($itemtype) . "_items`"); + $DB->dropTable(getTableForItemType($itemtype) . "_items", true); } /** @@ -420,7 +422,12 @@ public static function deleteReservations($itemtype) WHERE `reservationitems_id` in ( SELECT `id` from `glpi_reservationitems` WHERE `itemtype`='$itemtype' )"; - $DB->query($query); + $reservation = new Reservation(); + $reservation_item = new ReservationItem(); + $reservation_items = $reservation_item->find(['itemtype' => $itemtype]); + foreach ($reservation_items as $data) { + $reservation->deleteByCriteria(['reservationitems_id' => $data['id']]); + } } /** @@ -557,7 +564,7 @@ public static function install(Migration $migration) `impact_icon` varchar(255) default NULL, PRIMARY KEY ( `id` ) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die($DB->error()); + $DB->doQuery($query); } $migration->addField($table, "use_network_ports", "bool"); @@ -607,7 +614,7 @@ public static function install(Migration $migration) FROM `" . $genericObjectTypeInstance->getTable() . "` WHERE notepad IS NOT NULL AND notepad <> ''"; - $DB->query($query) or die($DB->error()); + $DB->doQuery($query); } $migration->dropField($genericObjectTypeInstance->getTable(), "notepad"); $migration->migrationOneTable($genericObjectTypeInstance->getTable()); @@ -659,8 +666,7 @@ public static function uninstall() } //Delete table - $query = "DROP TABLE IF EXISTS `glpi_plugin_genericobject_types`"; - $DB->query($query) or die($DB->error()); + $DB->dropTable('glpi_plugin_genericobject_types', true); } @@ -720,7 +726,7 @@ private static function normalizeNamesAndItemtypes(Migration $migration) $DB->update( self::getTable(), [ - 'linked_itemtypes' => new \QueryExpression( + 'linked_itemtypes' => new QueryExpression( 'REPLACE(' . $DB->quoteName('linked_itemtypes') . ',' diff --git a/inc/typefamily.class.php b/inc/typefamily.class.php index 82bfbb9d..227e8586 100644 --- a/inc/typefamily.class.php +++ b/inc/typefamily.class.php @@ -29,7 +29,7 @@ */ if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + throw new \RuntimeException('Direct access to this file is not allowed'); } class PluginGenericobjectTypeFamily extends CommonDropdown @@ -62,7 +62,7 @@ public static function install(Migration $migration) KEY `date_mod` (`date_mod`), KEY `date_creation` (`date_creation`) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->doQuery($query) or die($DB->error()); + $DB->doQuery($query); } } @@ -72,9 +72,6 @@ public static function uninstall() global $DB; $table = getTableForItemType(__CLASS__); - if ($DB->tableExists($table)) { - $query = "DROP TABLE IF EXISTS `$table`"; - $DB->doQuery($query) or die($DB->error()); - } + $DB->dropTable($table, true); } } diff --git a/index.php b/index.php index dba0bcb9..357204e3 100644 --- a/index.php +++ b/index.php @@ -28,8 +28,6 @@ * ------------------------------------------------------------------------- */ -include('../../inc/includes.php'); - // Check if user has admin rights Session::checkRight('config', UPDATE); diff --git a/setup.php b/setup.php index a4065292..fbe06626 100644 --- a/setup.php +++ b/setup.php @@ -114,23 +114,9 @@ function plugin_init_genericobject() * @var array $GO_READONLY_FIELDS * @var array $CFG_GLPI */ - global $PLUGIN_HOOKS, $GO_BLACKLIST_FIELDS, - $GENERICOBJECT_PDF_TYPES, $GO_LINKED_TYPES, $GO_READONLY_FIELDS, $CFG_GLPI; - - $GO_READONLY_FIELDS = ["is_helpdesk_visible", "comment", "ticket_tco"]; - - $GO_BLACKLIST_FIELDS = ["itemtype", "table", "is_deleted", "id", "entities_id", - "is_recursive", "is_template", "notepad", "template_name", - "date_mod", "name", "is_helpdesk_visible", "comment", - "date_creation", "ticket_tco" - ]; - - $GO_LINKED_TYPES = ['Computer', 'Phone', 'Peripheral', 'Software', 'Monitor', - 'Printer', 'NetworkEquipment' - ]; + global $PLUGIN_HOOKS; $PLUGIN_HOOKS['csrf_compliant']['genericobject'] = true; - $GENERICOBJECT_PDF_TYPES = []; if (Plugin::isPluginActive("genericobject") && isset($_SESSION['glpiactiveprofile'])) { From b754f14fb2233dea369d26e299942afe912951d9 Mon Sep 17 00:00:00 2001 From: MyuTsu Date: Thu, 18 Sep 2025 14:56:55 +0200 Subject: [PATCH 04/15] phpstan5 --- inc/functions.php | 23 +++++++++++++++++++---- inc/object.class.php | 3 --- inc/singletonobjectfield.class.php | 6 +++--- inc/type.class.php | 27 ++++++++++++++------------- phpstan.neon | 6 +++--- setup.php | 5 ----- 6 files changed, 39 insertions(+), 31 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index eaf6ba0c..57ad35f7 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -36,15 +36,30 @@ */ function dropdown_getTypeName($class, $nb = 0) { + if (!class_exists($class, true)) { + return $class; + } + $fk = getForeignKeyFieldForTable(getTableForItemType($class)); - $instance = new $class(); - $options = PluginGenericobjectField::getFieldOptions($fk, $instance->linked_itemtype); + /** @var CommonDBTM $instance */ + $instance = new $class(); // @phpstan-ignore-line + + $linked_itemtype = null; + if (property_exists($instance, 'linked_itemtype')) { + $linked_itemtype = $instance->linked_itemtype; + } + + $options = PluginGenericobjectField::getFieldOptions($fk, $linked_itemtype); $dropdown_type = isset($options['dropdown_type']) ? $options['dropdown_type'] : null; $label = $options['name'] ?? "no-name"; - if (!is_null($dropdown_type) and $dropdown_type === 'isolated') { - $linked_itemtype_object = new $instance->linked_itemtype(); + if (!is_null($dropdown_type) and $dropdown_type === 'isolated' and !is_null($linked_itemtype)) { + if (!class_exists($linked_itemtype, true)) { + return $label; + } + /** @var CommonDBTM $linked_itemtype_object */ + $linked_itemtype_object = new $linked_itemtype(); // @phpstan-ignore-line $label .= " (" . __($linked_itemtype_object::getTypeName(), 'genericobject') . ")"; } if ($label != '') { diff --git a/inc/object.class.php b/inc/object.class.php index ac61cf6e..c9ea3820 100644 --- a/inc/object.class.php +++ b/inc/object.class.php @@ -33,9 +33,6 @@ class PluginGenericobjectObject extends CommonDBTM protected $objecttype; - //Internal field counter - private $cpt = 0; - public function getCloneRelations(): array { return []; diff --git a/inc/singletonobjectfield.class.php b/inc/singletonobjectfield.class.php index 3131c672..468c0e45 100644 --- a/inc/singletonobjectfield.class.php +++ b/inc/singletonobjectfield.class.php @@ -45,10 +45,10 @@ class PluginGenericobjectSingletonObjectField * Singleton to store DB fields definition * * @since 2.1.0 - * @param itemtype itemtype to query - * @param reload reload db fields configuration from DB + * @param string $itemtype itemtype to query + * @param bool $reload reload db fields configuration from DB * - * @return an array which contains DB fields definition + * @return array an array which contains DB fields definition */ public static function getInstance($itemtype, $reload = false) { diff --git a/inc/type.class.php b/inc/type.class.php index d723234b..62ad5d36 100644 --- a/inc/type.class.php +++ b/inc/type.class.php @@ -346,9 +346,9 @@ public static function deleteSimcardAssignation($itemtype) public static function removeDataInjectionModels($itemtype) { //Delete if exists datainjection models - if (Plugin::isPluginActive("datainjection")) { - //@phpstan-ignore-next-line - $model = new PluginDatainjectionModel(); + if (Plugin::isPluginActive("datainjection") && class_exists('PluginDatainjectionModel')) { + /** @var CommonDBTM $model */ + $model = new PluginDatainjectionModel(); // @phpstan-ignore-line foreach ($model->find(['itemtype' => $itemtype]) as $data) { $model->delete($data); } @@ -596,7 +596,12 @@ public static function install(Migration $migration) $notepad = new Notepad(); foreach ($allGenericObjectTypes as $genericObjectType => $genericObjectData) { - $genericObjectTypeInstance = new $genericObjectType(); + if (!class_exists($genericObjectType, true)) { + // Skip missing classes during migration + continue; + } + /** @var CommonDBTM $genericObjectTypeInstance */ + $genericObjectTypeInstance = new $genericObjectType(); // @phpstan-ignore-line if ($DB->fieldExists($genericObjectTypeInstance->getTable(), "notepad")) { $query = "INSERT INTO `" . $notepad->getTable() . "` (`items_id`, @@ -658,7 +663,7 @@ public static function uninstall() //Delete references to PluginGenericobjectType in the following tables self::deleteItemtypeReferencesInGLPI(__CLASS__); - foreach ($DB->request("glpi_plugin_genericobject_types") as $type) { + foreach ($DB->request(['FROM' => 'glpi_plugin_genericobject_types']) as $type) { //Delete references to PluginGenericobjectType in the following tables self::deleteItemtypeReferencesInGLPI($type['itemtype']); //Dropd files and classes @@ -839,9 +844,8 @@ private static function updateNameAndItemtype( ); } } else { - $migration->displayWarning( + $migration->displayMessage( sprintf('Unable to rename "%s" locale directory to "%s"', $old_locale_dir, $new_locale_dir), - true ); } } @@ -875,9 +879,8 @@ private static function updateNameAndItemtype( if ($old_filename != $new_filename) { if (!rename($old_filename, $new_filename)) { - $migration->displayWarning( + $migration->displayMessage( sprintf('Unable to rename "%s" file to "%s"', $old_filename, $new_filename), - true ); continue; } @@ -889,9 +892,8 @@ private static function updateNameAndItemtype( $file_contents = file_get_contents($new_filename); if (!$file_contents) { - $migration->displayWarning( + $migration->displayMessage( sprintf('Unable to read "%s" file contents', $new_filename), - true ); continue; } @@ -906,9 +908,8 @@ private static function updateNameAndItemtype( $replace_count ); if ($replace_count > 0 && !file_put_contents($new_filename, $file_contents)) { - $migration->displayWarning( + $migration->displayMessage( sprintf('Unable to update "%s" file contents', $new_filename), - true ); } } diff --git a/phpstan.neon b/phpstan.neon index 60bb85d3..3905d94e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,13 +1,13 @@ parameters: parallel: maximumNumberOfProcesses: 2 - level: 1 + level: 5 bootstrapFiles: - - ../../inc/based_config.php + - ../../stubs/glpi_constants.php + - ../../vendor/autoload.php paths: - inc - front - - ajax - hook.php - setup.php scanDirectories: diff --git a/setup.php b/setup.php index fbe06626..d0c5bbe6 100644 --- a/setup.php +++ b/setup.php @@ -108,11 +108,6 @@ function plugin_init_genericobject() { /** * @var array $PLUGIN_HOOKS - * @var array $GO_BLACKLIST_FIELDS - * @var array $GENERICOBJECT_PDF_TYPES - * @var array $GO_LINKED_TYPES - * @var array $GO_READONLY_FIELDS - * @var array $CFG_GLPI */ global $PLUGIN_HOOKS; From 6f70fe854ac00c5f605a48d8642ad929e6543cd8 Mon Sep 17 00:00:00 2001 From: MyuTsu Date: Thu, 18 Sep 2025 15:07:28 +0200 Subject: [PATCH 05/15] add view items button --- front/migration_status.php | 3 ++- templates/migration_status.html.twig | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/front/migration_status.php b/front/migration_status.php index 5182204e..8760e62b 100644 --- a/front/migration_status.php +++ b/front/migration_status.php @@ -17,7 +17,7 @@ /** @var \DBmysql $DB */ global $DB; -// Collect basic statistics - simple and reliable +// Get all GenericObject types $genericobject_types = []; if ($DB->tableExists(PluginGenericobjectType::getTable())) { $query = [ @@ -31,6 +31,7 @@ } +// Get all custom asset definitions $customassets = []; if ($DB->tableExists(AssetDefinition::getTable())) { $query = [ diff --git a/templates/migration_status.html.twig b/templates/migration_status.html.twig index f8225a71..a6953c52 100644 --- a/templates/migration_status.html.twig +++ b/templates/migration_status.html.twig @@ -116,7 +116,12 @@ {{ customassets[genericobject_type.name].items }}
-
+ -
+
+