diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..46a6d7a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 +updates: + # Ensure GitHub Actions are used in their latest version + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + + # Strategy for composer dependencies + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "monthly" + allow: + - dependency-type: "direct" + open-pull-requests-limit: 100 + versioning-strategy: "increase" + groups: + dev-dependencies: + dependency-type: "development" diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..7a81c5b --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,21 @@ +in(__DIR__) + ->name('*.php') + ->ignoreVCSIgnored(true); + +$config = new Config(); + +$rules = [ + '@PER-CS2.0' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arguments', 'array_destructuring', 'arrays']], // For PHP 7.4 compatibility +]; + +return $config + ->setRules($rules) + ->setFinder($finder) + ->setUsingCache(false); diff --git a/composer.json b/composer.json index 903a755..4f2b5cb 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,8 @@ "php": ">=7.4" }, "require-dev": { - "glpi-project/tools": "^0.5" + "friendsofphp/php-cs-fixer": "^3.75", + "glpi-project/tools": "^0.7.5" }, "config": { "optimize-autoloader": true, diff --git a/composer.lock b/composer.lock index da853a5..ff925e8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,82 +4,182 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0163b1c6232cea04e21b7dbb15bbf8e8", + "content-hash": "d8d19ce9a976b90be57e3b72b58a5b7e", "packages": [], "packages-dev": [ { - "name": "glpi-project/tools", - "version": "0.5.1", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/glpi-project/tools.git", - "reference": "8d32c53bd9fb6c4cd85cbbb405a63ea88ca033e4" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/glpi-project/tools/zipball/8d32c53bd9fb6c4cd85cbbb405a63ea88ca033e4", - "reference": "8d32c53bd9fb6c4cd85cbbb405a63ea88ca033e4", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "symfony/console": "^4.4 || ^5.0", - "twig/twig": "^3.3" + "php": ">=5.3", + "react/stream": "^1.2" }, - "bin": [ - "bin/extract-locales", - "bin/licence-headers-check", - "tools/plugin-release" + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Glpi\\": "src/" + "Composer\\Pcre\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "GPL-3.0-or-later" + "MIT" ], "authors": [ { - "name": "Teclib'", - "email": "glpi@teclib.com", - "homepage": "http://teclib-group.com" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" } ], - "description": "Various tools for GLPI and its plugins", + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "glpi", - "plugins", - "tools" + "PCRE", + "preg", + "regex", + "regular expression" ], "support": { - "issues": "https://github.com/glpi-project/tools/issues", - "source": "https://github.com/glpi-project/tools" + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" }, - "time": "2022-06-28T11:18:30+00:00" + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" }, { - "name": "psr/container", - "version": "1.1.2", + "name": "composer/semver", + "version": "3.4.3", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { - "php": ">=7.4.0" + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -88,78 +188,1543 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" + "semantic", + "semver", + "validation", + "versioning" ], "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" }, - "time": "2021-11-05T16:50:12+00:00" + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" }, { - "name": "symfony/console", - "version": "v5.4.10", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.75.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c", + "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.2", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/polyfill-mbstring": "^1.31", + "symfony/polyfill-php80": "^1.31", + "symfony/polyfill-php81": "^1.31", + "symfony/process": "^5.4 || ^6.4 || ^7.2", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.6", + "infection/infection": "^0.29.14", + "justinrainbow/json-schema": "^5.3 || ^6.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", + "phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12", + "symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3", + "symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2025-03-31T18:40:42+00:00" + }, + { + "name": "glpi-project/tools", + "version": "0.7.5", + "source": { + "type": "git", + "url": "https://github.com/glpi-project/tools.git", + "reference": "c6ff4a7640384232ead150b46d4a647a14d12ab3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/glpi-project/tools/zipball/c6ff4a7640384232ead150b46d4a647a14d12ab3", + "reference": "c6ff4a7640384232ead150b46d4a647a14d12ab3", + "shasum": "" + }, + "require": { + "symfony/console": "^5.4 || ^6.0", + "twig/twig": "^3.3" + }, + "require-dev": { + "nikic/php-parser": "^4.13", + "phpstan/phpstan-src": "^1.10" + }, + "bin": [ + "bin/extract-locales", + "bin/licence-headers-check", + "tools/plugin-release" + ], + "type": "library", + "autoload": { + "psr-4": { + "GlpiProject\\Tools\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Teclib'", + "email": "glpi@teclib.com", + "homepage": "http://teclib-group.com" + } + ], + "description": "Various tools for GLPI and its plugins", + "keywords": [ + "glpi", + "plugins", + "tools" + ], + "support": { + "issues": "https://github.com/glpi-project/tools/issues", + "source": "https://github.com/glpi-project/tools" + }, + "time": "2025-05-22T07:31:28+00:00" + }, + { + "name": "psr/container", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "symfony/console", + "version": "v5.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^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" + }, + "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" + }, + "provide": { + "psr/log-implementation": "1.0|2.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": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-06T11:30:55+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "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" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "72982eb416f61003e9bb6e91f8b3213600dcf9e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/72982eb416f61003e9bb6e91f8b3213600dcf9e9", + "reference": "72982eb416f61003e9bb6e91f8b3213600dcf9e9", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f", + "reference": "e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "57c8294ed37d4a055b77057827c67f9558c95c54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/57c8294ed37d4a055b77057827c67f9558c95c54", + "reference": "57c8294ed37d4a055b77057827c67f9558c95c54", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/process": "^5.4|^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-22T13:05:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "63741784cd7b9967975eec610b256eed3ede022b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/4d671ab4ddac94ee439ea73649c69d9d200b5000", - "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000", + "url": "https://api.github.com/repos/symfony/finder/zipball/63741784cd7b9967975eec610b256eed3ede022b", + "reference": "63741784cd7b9967975eec610b256eed3ede022b", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1|^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" - }, - "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" - }, - "provide": { - "psr/log-implementation": "1.0|2.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": "" + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" + "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -179,16 +1744,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command line", - "console", - "terminal" - ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.10" + "source": "https://github.com/symfony/finder/tree/v5.4.45" }, "funding": [ { @@ -204,38 +1763,35 @@ "type": "tidelift" } ], - "time": "2022-06-26T13:00:04+00:00" + "time": "2024-09-28T13:32:08+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v2.5.2", + "name": "symfony/options-resolver", + "version": "v5.4.45", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "74e5b6f0db3e8589e6cfd5efb317a1fc2bb52fb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/74e5b6f0db3e8589e6cfd5efb317a1fc2bb52fb6", + "reference": "74e5b6f0db3e8589e6cfd5efb317a1fc2bb52fb6", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, "autoload": { - "files": [ - "function.php" + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -244,18 +1800,23 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "A generic function and convention to trigger deprecation notices", + "description": "Provides an improved replacement for the array_replace PHP function", "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/options-resolver/tree/v5.4.45" }, "funding": [ { @@ -271,24 +1832,24 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -298,12 +1859,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -337,7 +1895,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, "funding": [ { @@ -353,36 +1911,33 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -418,7 +1973,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" }, "funding": [ { @@ -434,36 +1989,33 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -502,7 +2054,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" }, "funding": [ { @@ -518,24 +2070,25 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -545,12 +2098,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -585,7 +2135,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, "funding": [ { @@ -601,33 +2151,30 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.26.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -664,7 +2211,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.32.0" }, "funding": [ { @@ -680,33 +2227,30 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -747,7 +2291,145 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.32.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.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v5.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "5d1662fb32ebc94f17ddb8d635454a776066733d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/5d1662fb32ebc94f17ddb8d635454a776066733d", + "reference": "5d1662fb32ebc94f17ddb8d635454a776066733d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.4.47" }, "funding": [ { @@ -763,20 +2445,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2024-11-06T11:36:42+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.2", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300", + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300", "shasum": "" }, "require": { @@ -792,12 +2474,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -830,7 +2512,69 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:11:13+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "fb2c199cf302eb207f8c23e7ee174c1c31a5c004" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fb2c199cf302eb207f8c23e7ee174c1c31a5c004", + "reference": "fb2c199cf302eb207f8c23e7ee174c1c31a5c004", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.4.45" }, "funding": [ { @@ -846,20 +2590,20 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/string", - "version": "v5.4.10", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097" + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4432bc7df82a554b3e413a8570ce2fea90e94097", - "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097", + "url": "https://api.github.com/repos/symfony/string/zipball/136ca7d72f72b599f2631aca474a4f8e26719799", + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799", "shasum": "" }, "require": { @@ -916,7 +2660,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.10" + "source": "https://github.com/symfony/string/tree/v5.4.47" }, "funding": [ { @@ -932,38 +2676,42 @@ "type": "tidelift" } ], - "time": "2022-06-26T15:57:47+00:00" + "time": "2024-11-10T20:33:58+00:00" }, { "name": "twig/twig", - "version": "v3.4.1", + "version": "v3.11.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e939eae92386b69b49cfa4599dd9bead6bf4a342" + "reference": "3b06600ff3abefaf8ff55d5c336cd1c4253f8c7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e939eae92386b69b49cfa4599dd9bead6bf4a342", - "reference": "e939eae92386b69b49cfa4599dd9bead6bf4a342", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3b06600ff3abefaf8ff55d5c336cd1c4253f8c7e", + "reference": "3b06600ff3abefaf8ff55d5c336cd1c4253f8c7e", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.22", + "symfony/polyfill-php81": "^1.29" }, "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -996,7 +2744,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.1" + "source": "https://github.com/twigphp/Twig/tree/v3.11.3" }, "funding": [ { @@ -1008,20 +2756,20 @@ "type": "tidelift" } ], - "time": "2022-05-17T05:48:52+00:00" + "time": "2024-11-07T12:34:41+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=7.4" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { "php": "7.4.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/front/config.php b/front/config.php index 516e32a..34dc261 100644 --- a/front/config.php +++ b/front/config.php @@ -37,13 +37,13 @@ //header("Location:../../central.php"); // Entry menu case -include ("../../../inc/includes.php"); +include('../../../inc/includes.php'); -Session::checkRight("config", UPDATE); +Session::checkRight('config', UPDATE); // To be available when plugin in not activated Plugin::load('example'); -Html::header("TITRE", $_SERVER['PHP_SELF'], "config", "plugins"); -echo __("This is the plugin config page", 'example'); +Html::header('TITRE', $_SERVER['PHP_SELF'], 'config', 'plugins'); +echo __('This is the plugin config page', 'example'); Html::footer(); diff --git a/front/devicecamera.form.php b/front/devicecamera.form.php index 2da3152..df30c36 100644 --- a/front/devicecamera.form.php +++ b/front/devicecamera.form.php @@ -35,8 +35,8 @@ use GlpiPlugin\Example\DeviceCamera; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); $dropdown = new DeviceCamera(); -include (GLPI_ROOT . "/front/dropdown.common.form.php"); +include(GLPI_ROOT . '/front/dropdown.common.form.php'); diff --git a/front/devicecamera.php b/front/devicecamera.php index be1a436..0abc8c0 100644 --- a/front/devicecamera.php +++ b/front/devicecamera.php @@ -33,8 +33,8 @@ // Purpose of file: // ---------------------------------------------------------------------- -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); $dropdown = new DeviceCamera(); -include (GLPI_ROOT . "/front/dropdown.common.php"); +include(GLPI_ROOT . '/front/dropdown.common.php'); diff --git a/front/dropdown.form.php b/front/dropdown.form.php index cf88c33..2c514f7 100644 --- a/front/dropdown.form.php +++ b/front/dropdown.form.php @@ -35,10 +35,10 @@ use GlpiPlugin\Example\Dropdown; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); Plugin::load('example', true); $dropdown = new Dropdown(); -include (GLPI_ROOT . "/front/dropdown.common.form.php"); +include(GLPI_ROOT . '/front/dropdown.common.form.php'); diff --git a/front/dropdown.php b/front/dropdown.php index df91884..4bb99a4 100644 --- a/front/dropdown.php +++ b/front/dropdown.php @@ -35,10 +35,10 @@ use GlpiPlugin\Example\Dropdown; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); Plugin::load('example', true); $dropdown = new Dropdown(); -include (GLPI_ROOT . "/front/dropdown.common.php"); +include(GLPI_ROOT . '/front/dropdown.common.php'); diff --git a/front/example.form.php b/front/example.form.php index 9650560..3180563 100644 --- a/front/example.form.php +++ b/front/example.form.php @@ -35,13 +35,13 @@ use GlpiPlugin\Example\Example; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); -if ($_SESSION["glpiactiveprofile"]["interface"] == "central") { - Html::header("TITRE", $_SERVER['PHP_SELF'], "plugins", Example::class, ""); +if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { + Html::header('TITRE', $_SERVER['PHP_SELF'], 'plugins', Example::class, ''); } else { - Html::helpHeader("TITRE", $_SERVER['PHP_SELF']); + Html::helpHeader('TITRE', $_SERVER['PHP_SELF']); } $example = new Example(); diff --git a/front/example.php b/front/example.php index 64def29..da6a757 100644 --- a/front/example.php +++ b/front/example.php @@ -35,13 +35,13 @@ use GlpiPlugin\Example\Example; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkRight(Example::$rightname, READ); -if ($_SESSION["glpiactiveprofile"]["interface"] == "central") { - Html::header("TITRE", $_SERVER['PHP_SELF'], "plugins", Example::class, ""); +if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { + Html::header('TITRE', $_SERVER['PHP_SELF'], 'plugins', Example::class, ''); } else { - Html::helpHeader("TITRE", $_SERVER['PHP_SELF']); + Html::helpHeader('TITRE', $_SERVER['PHP_SELF']); } diff --git a/front/popup.php b/front/popup.php index 36f19f8..a75896b 100644 --- a/front/popup.php +++ b/front/popup.php @@ -28,32 +28,32 @@ * ------------------------------------------------------------------------- */ -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); -if (isset($_GET["popup"])) { - $_SESSION["glpipopup"]["name"] = $_GET["popup"]; +if (isset($_GET['popup'])) { + $_SESSION['glpipopup']['name'] = $_GET['popup']; } -if (isset($_SESSION["glpipopup"]["name"])) { - switch ($_SESSION["glpipopup"]["name"]) { - case "test_rule" : - Html::popHeader(__('Test'), $_SERVER['PHP_SELF']); - include "../../../front/rule.test.php"; - break; +if (isset($_SESSION['glpipopup']['name'])) { + switch ($_SESSION['glpipopup']['name']) { + case 'test_rule': + Html::popHeader(__('Test'), $_SERVER['PHP_SELF']); + include '../../../front/rule.test.php'; + break; - case "test_all_rules" : - Html::popHeader(__('Test rules engine'), $_SERVER['PHP_SELF']); - include "../../../front/rulesengine.test.php"; - break; + case 'test_all_rules': + Html::popHeader(__('Test rules engine'), $_SERVER['PHP_SELF']); + include '../../../front/rulesengine.test.php'; + break; - case "show_cache" : - Html::popHeader(__('Cache information'), $_SERVER['PHP_SELF']); - include "../../../front/rule.cache.php"; - break; - } - echo "

".__('Back').""; - echo "
"; - Html::popFooter(); + case 'show_cache': + Html::popHeader(__('Cache information'), $_SERVER['PHP_SELF']); + include '../../../front/rule.cache.php'; + break; + } + echo "

" . __('Back') . ''; + echo '
'; + Html::popFooter(); } diff --git a/front/ruletest.form.php b/front/ruletest.form.php index 5578d10..e48a834 100644 --- a/front/ruletest.form.php +++ b/front/ruletest.form.php @@ -35,9 +35,9 @@ use GlpiPlugin\Example\RuleTestCollection; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); $rulecollection = new RuleTestCollection(); -include (GLPI_ROOT . "/front/rule.common.form.php"); +include(GLPI_ROOT . '/front/rule.common.form.php'); diff --git a/front/ruletest.php b/front/ruletest.php index 8976275..16ea9e6 100644 --- a/front/ruletest.php +++ b/front/ruletest.php @@ -35,9 +35,9 @@ use GlpiPlugin\Example\RuleTestCollection; -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); Session::checkLoginUser(); $rulecollection = new RuleTestCollection(); -include (GLPI_ROOT . "/front/rule.common.php"); +include(GLPI_ROOT . '/front/rule.common.php'); diff --git a/hook.php b/hook.php index 73e0af8..2484b2e 100644 --- a/hook.php +++ b/hook.php @@ -37,21 +37,24 @@ use GlpiPlugin\Example\Example; use Dropdown as GlpiDropdown; -function plugin_change_profile_example() { - // Some logic that runs when the profile is changed +function plugin_change_profile_example() +{ + // Some logic that runs when the profile is changed } // Define dropdown relations -function plugin_example_getDatabaseRelations() { - return ["glpi_plugin_example_dropdowns" => ["glpi_plugin_example" => "plugin_example_dropdowns_id"]]; +function plugin_example_getDatabaseRelations() +{ + return ['glpi_plugin_example_dropdowns' => ['glpi_plugin_example' => 'plugin_example_dropdowns_id']]; } // Define Dropdown tables to be manage in GLPI : -function plugin_example_getDropdown() { - // Table => Name - return [Dropdown::class => __("Plugin Example Dropdown", 'example')]; +function plugin_example_getDropdown() +{ + // Table => Name + return [Dropdown::class => __('Plugin Example Dropdown', 'example')]; } @@ -59,199 +62,230 @@ function plugin_example_getDropdown() { ////// SEARCH FUNCTIONS ///////(){ // Define Additionnal search options for types (other than the plugin ones) -function plugin_example_getAddSearchOptions($itemtype) { - $sopt = []; - if ($itemtype == 'Computer') { - // Just for example, not working... - $sopt[1001]['table'] = 'glpi_plugin_example_dropdowns'; - $sopt[1001]['field'] = 'name'; - $sopt[1001]['linkfield'] = 'plugin_example_dropdowns_id'; - $sopt[1001]['name'] = __('Example plugin', 'example'); - } - return $sopt; -} - -function plugin_example_getAddSearchOptionsNew($itemtype) { - $options = []; - if ($itemtype == 'Computer') { - //Just for example, not working - $options[] = [ - 'id' => '1002', - 'table' => 'glpi_plugin_example_dropdowns', - 'field' => 'name', - 'linkfield' => 'plugin_example_dropdowns_id', - 'name' => __('Example plugin new', 'example') - ]; - } - return $options; +function plugin_example_getAddSearchOptions($itemtype) +{ + $sopt = []; + if ($itemtype == 'Computer') { + // Just for example, not working... + $sopt[1001]['table'] = 'glpi_plugin_example_dropdowns'; + $sopt[1001]['field'] = 'name'; + $sopt[1001]['linkfield'] = 'plugin_example_dropdowns_id'; + $sopt[1001]['name'] = __('Example plugin', 'example'); + } + + return $sopt; +} + +function plugin_example_getAddSearchOptionsNew($itemtype) +{ + $options = []; + if ($itemtype == 'Computer') { + //Just for example, not working + $options[] = [ + 'id' => '1002', + 'table' => 'glpi_plugin_example_dropdowns', + 'field' => 'name', + 'linkfield' => 'plugin_example_dropdowns_id', + 'name' => __('Example plugin new', 'example'), + ]; + } + + return $options; } // See also GlpiPlugin\Example\Example::getSpecificValueToDisplay() -function plugin_example_giveItem($type, $ID, $data, $num) { - $searchopt = &Search::getOptions($type); - $table = $searchopt[$ID]["table"]; - $field = $searchopt[$ID]["field"]; - - switch ($table.'.'.$field) { - case "glpi_plugin_example_examples.name" : - $out = ""; - $out .= $data[$num][0]['name']; - if ($_SESSION["glpiis_ids_visible"] || empty($data[$num][0]['name'])) { - $out .= " (".$data["id"].")"; - } - $out .= ""; - return $out; - } - return ""; -} - - -function plugin_example_displayConfigItem($type, $ID, $data, $num) { - $searchopt = &Search::getOptions($type); - $table = $searchopt[$ID]["table"]; - $field = $searchopt[$ID]["field"]; - - // Example of specific style options - // No need of the function if you do not have specific cases - switch ($table.'.'.$field) { - case "glpi_plugin_example_examples.name" : - return " style=\"background-color:#DDDDDD;\" "; - } - return ""; -} - - -function plugin_example_addDefaultJoin($type, $ref_table, &$already_link_tables) { - // Example of default JOIN clause - // No need of the function if you do not have specific cases - switch ($type) { - // case Example::class : - case "MyType" : - return Search::addLeftJoin($type, $ref_table, $already_link_tables, - "newtable", "linkfield"); - } - return ""; -} - - -function plugin_example_addDefaultSelect($type) { - // Example of default SELECT item to be added - // No need of the function if you do not have specific cases - switch ($type) { - // case Example::class : - case "MyType" : - return "`mytable`.`myfield` = 'myvalue' AS MYNAME, "; - } - return ""; -} - - -function plugin_example_addDefaultWhere($type) { - // Example of default WHERE item to be added - // No need of the function if you do not have specific cases - switch ($type) { - // case Example::class : - case "MyType" : - return " `mytable`.`myfield` = 'myvalue' "; - } - return ""; -} - - -function plugin_example_addLeftJoin($type, $ref_table, $new_table, $linkfield) { - // Example of standard LEFT JOIN clause but use it ONLY for specific LEFT JOIN - // No need of the function if you do not have specific cases - switch ($new_table) { - case "glpi_plugin_example_dropdowns" : - return " LEFT JOIN `$new_table` ON (`$ref_table`.`$linkfield` = `$new_table`.`id`) "; - } - return ""; -} - - -function plugin_example_forceGroupBy($type) { - switch ($type) { - case Example::class : - // Force add GROUP BY IN REQUEST - return true; - } - return false; -} - - -function plugin_example_addWhere($link, $nott, $type, $ID, $val, $searchtype) { - $searchopt = &Search::getOptions($type); - $table = $searchopt[$ID]["table"]; - $field = $searchopt[$ID]["field"]; - - $SEARCH = Search::makeTextSearch($val, $nott); - - // Example of standard Where clause but use it ONLY for specific Where - // No need of the function if you do not have specific cases - switch ($table.".".$field) { - /*case "glpi_plugin_example.name" : - $ADD = ""; - if ($nott && $val!="NULL") { - $ADD = " OR `$table`.`$field` IS NULL"; - } - return $link." (`$table`.`$field` $SEARCH ".$ADD." ) ";*/ - case "glpi_plugin_example_examples.serial" : - return $link." `$table`.`$field` = '$val' "; - } - return ""; +function plugin_example_giveItem($type, $ID, $data, $num) +{ + $searchopt = &Search::getOptions($type); + $table = $searchopt[$ID]['table']; + $field = $searchopt[$ID]['field']; + + switch ($table . '.' . $field) { + case 'glpi_plugin_example_examples.name': + $out = ""; + $out .= $data[$num][0]['name']; + if ($_SESSION['glpiis_ids_visible'] || empty($data[$num][0]['name'])) { + $out .= ' (' . $data['id'] . ')'; + } + $out .= ''; + + return $out; + } + + return ''; +} + + +function plugin_example_displayConfigItem($type, $ID, $data, $num) +{ + $searchopt = &Search::getOptions($type); + $table = $searchopt[$ID]['table']; + $field = $searchopt[$ID]['field']; + + // Example of specific style options + // No need of the function if you do not have specific cases + switch ($table . '.' . $field) { + case 'glpi_plugin_example_examples.name': + return ' style="background-color:#DDDDDD;" '; + } + + return ''; +} + + +function plugin_example_addDefaultJoin($type, $ref_table, &$already_link_tables) +{ + // Example of default JOIN clause + // No need of the function if you do not have specific cases + switch ($type) { + // case Example::class : + case 'MyType': + return Search::addLeftJoin( + $type, + $ref_table, + $already_link_tables, + 'newtable', + 'linkfield', + ); + } + + return ''; +} + + +function plugin_example_addDefaultSelect($type) +{ + // Example of default SELECT item to be added + // No need of the function if you do not have specific cases + switch ($type) { + // case Example::class : + case 'MyType': + return "`mytable`.`myfield` = 'myvalue' AS MYNAME, "; + } + + return ''; +} + + +function plugin_example_addDefaultWhere($type) +{ + // Example of default WHERE item to be added + // No need of the function if you do not have specific cases + switch ($type) { + // case Example::class : + case 'MyType': + return " `mytable`.`myfield` = 'myvalue' "; + } + + return ''; +} + + +function plugin_example_addLeftJoin($type, $ref_table, $new_table, $linkfield) +{ + // Example of standard LEFT JOIN clause but use it ONLY for specific LEFT JOIN + // No need of the function if you do not have specific cases + switch ($new_table) { + case 'glpi_plugin_example_dropdowns': + return " LEFT JOIN `$new_table` ON (`$ref_table`.`$linkfield` = `$new_table`.`id`) "; + } + + return ''; +} + + +function plugin_example_forceGroupBy($type) +{ + switch ($type) { + case Example::class: + // Force add GROUP BY IN REQUEST + return true; + } + + return false; +} + + +function plugin_example_addWhere($link, $nott, $type, $ID, $val, $searchtype) +{ + $searchopt = &Search::getOptions($type); + $table = $searchopt[$ID]['table']; + $field = $searchopt[$ID]['field']; + + $SEARCH = Search::makeTextSearch($val, $nott); + + // Example of standard Where clause but use it ONLY for specific Where + // No need of the function if you do not have specific cases + switch ($table . '.' . $field) { + /*case "glpi_plugin_example.name" : + $ADD = ""; + if ($nott && $val!="NULL") { + $ADD = " OR `$table`.`$field` IS NULL"; + } + return $link." (`$table`.`$field` $SEARCH ".$ADD." ) ";*/ + case 'glpi_plugin_example_examples.serial': + return $link . " `$table`.`$field` = '$val' "; + } + + return ''; } // This is not a real example because the use of Having condition in this case is not suitable -function plugin_example_addHaving($link, $nott, $type, $ID, $val, $num) { - $searchopt = &Search::getOptions($type); - $table = $searchopt[$ID]["table"]; - $field = $searchopt[$ID]["field"]; +function plugin_example_addHaving($link, $nott, $type, $ID, $val, $num) +{ + $searchopt = &Search::getOptions($type); + $table = $searchopt[$ID]['table']; + $field = $searchopt[$ID]['field']; + + $SEARCH = Search::makeTextSearch($val, $nott); + + // Example of standard Having clause but use it ONLY for specific Having + // No need of the function if you do not have specific cases + switch ($table . '.' . $field) { + case 'glpi_plugin_example.serial': + $ADD = ''; + if (($nott && $val != 'NULL') + || $val == '^$') { + $ADD = " OR ITEM_$num IS NULL"; + } - $SEARCH = Search::makeTextSearch($val, $nott); + return " $LINK ( ITEM_" . $num . $SEARCH . " $ADD ) "; + } - // Example of standard Having clause but use it ONLY for specific Having - // No need of the function if you do not have specific cases - switch ($table.".".$field) { - case "glpi_plugin_example.serial" : - $ADD = ""; - if (($nott && $val!="NULL") - || $val == '^$') { - $ADD = " OR ITEM_$num IS NULL"; - } - return " $LINK ( ITEM_".$num.$SEARCH." $ADD ) "; - } - return ""; + return ''; } -function plugin_example_addSelect($type, $ID, $num) { - $searchopt = &Search::getOptions($type); - $table = $searchopt[$ID]["table"]; - $field = $searchopt[$ID]["field"]; +function plugin_example_addSelect($type, $ID, $num) +{ + $searchopt = &Search::getOptions($type); + $table = $searchopt[$ID]['table']; + $field = $searchopt[$ID]['field']; - // Example of standard Select clause but use it ONLY for specific Select - // No need of the function if you do not have specific cases - // switch ($table.".".$field) { - // case "glpi_plugin_example.name" : - // return $table.".".$field." AS ITEM_$num, "; - // } - return ""; + // Example of standard Select clause but use it ONLY for specific Select + // No need of the function if you do not have specific cases + // switch ($table.".".$field) { + // case "glpi_plugin_example.name" : + // return $table.".".$field." AS ITEM_$num, "; + // } + return ''; } -function plugin_example_addOrderBy($type, $ID, $order, $key = 0) { - $searchopt = &Search::getOptions($type); - $table = $searchopt[$ID]["table"]; - $field = $searchopt[$ID]["field"]; +function plugin_example_addOrderBy($type, $ID, $order, $key = 0) +{ + $searchopt = &Search::getOptions($type); + $table = $searchopt[$ID]['table']; + $field = $searchopt[$ID]['field']; - // Example of standard OrderBy clause but use it ONLY for specific order by - // No need of the function if you do not have specific cases - // switch ($table.".".$field) { - // case "glpi_plugin_example.name" : - // return " ORDER BY $table.$field $order "; - // } - return ""; + // Example of standard OrderBy clause but use it ONLY for specific order by + // No need of the function if you do not have specific cases + // switch ($table.".".$field) { + // case "glpi_plugin_example.name" : + // return " ORDER BY $table.$field $order "; + // } + return ''; } @@ -260,192 +294,226 @@ function plugin_example_addOrderBy($type, $ID, $order, $key = 0) { // Define actions : -function plugin_example_MassiveActions($type) { - switch ($type) { - // New action for core and other plugin types : name = plugin_PLUGINNAME_actionname - case 'Computer' : - return [Example::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'DoIt' => - __("plugin_example_DoIt", 'example')]; +function plugin_example_MassiveActions($type) +{ + switch ($type) { + // New action for core and other plugin types : name = plugin_PLUGINNAME_actionname + case 'Computer': + return [Example::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'DoIt' => __('plugin_example_DoIt', 'example')]; + + // Actions for types provided by the plugin are included inside the classes + } - // Actions for types provided by the plugin are included inside the classes - } - return []; + return []; } // How to display specific update fields ? // options must contain at least itemtype and options array -function plugin_example_MassiveActionsFieldsDisplay($options = []) { - //$type,$table,$field,$linkfield - - $table = $options['options']['table']; - $field = $options['options']['field']; - $linkfield = $options['options']['linkfield']; - - if ($table == getTableForItemType($options['itemtype'])) { - // Table fields - switch ($table.".".$field) { - case 'glpi_plugin_example_examples.serial' : - echo __("Not really specific - Just for example", 'example'); - // Dropdown::showYesNo($linkfield); - // Need to return true if specific display - return true; - } +function plugin_example_MassiveActionsFieldsDisplay($options = []) +{ + //$type,$table,$field,$linkfield + + $table = $options['options']['table']; + $field = $options['options']['field']; + $linkfield = $options['options']['linkfield']; + + if ($table == getTableForItemType($options['itemtype'])) { + // Table fields + switch ($table . '.' . $field) { + case 'glpi_plugin_example_examples.serial': + echo __('Not really specific - Just for example', 'example'); + + // Dropdown::showYesNo($linkfield); + // Need to return true if specific display + return true; + } + } else { + // Linked Fields + switch ($table . '.' . $field) { + case 'glpi_plugin_example_dropdowns.name': + echo __('Not really specific - Just for example', 'example'); + + // Need to return true if specific display + return true; + } + } - } else { - // Linked Fields - switch ($table.".".$field) { - case "glpi_plugin_example_dropdowns.name" : - echo __("Not really specific - Just for example", 'example'); - // Need to return true if specific display - return true; - } - } - // Need to return false on non display item - return false; + // Need to return false on non display item + return false; } // How to display specific search fields or dropdown ? // options must contain at least itemtype and options array // MUST Use a specific AddWhere & $tab[X]['searchtype'] = 'equals'; declaration -function plugin_example_searchOptionsValues($options = []) { - $table = $options['searchoption']['table']; - $field = $options['searchoption']['field']; +function plugin_example_searchOptionsValues($options = []) +{ + $table = $options['searchoption']['table']; + $field = $options['searchoption']['field']; // Table fields - switch ($table.".".$field) { - case "glpi_plugin_example_examples.serial" : - echo __("Not really specific - Use your own dropdown - Just for example", 'example'); - GlpiDropdown::show(getItemTypeForTable($options['searchoption']['table']), - ['value' => $options['value'], - 'name' => $options['name'], - 'comments' => 0]); + switch ($table . '.' . $field) { + case 'glpi_plugin_example_examples.serial': + echo __('Not really specific - Use your own dropdown - Just for example', 'example'); + GlpiDropdown::show( + getItemTypeForTable($options['searchoption']['table']), + ['value' => $options['value'], + 'name' => $options['name'], + 'comments' => 0], + ); + // Need to return true if specific display return true; - } - return false; + } + + return false; } ////////////////////////////// // Hook done on before update item case -function plugin_pre_item_update_example($item) { - /* Manipulate data if needed - if (!isset($item->input['comment'])) { - $item->input['comment'] = addslashes($item->fields['comment']); - } - $item->input['comment'] .= addslashes("\nUpdate: ".date('r')); - */ - Session::addMessageAfterRedirect(__("Pre Update Computer Hook", 'example'), true); +function plugin_pre_item_update_example($item) +{ + /* Manipulate data if needed + if (!isset($item->input['comment'])) { + $item->input['comment'] = addslashes($item->fields['comment']); + } + $item->input['comment'] .= addslashes("\nUpdate: ".date('r')); + */ + Session::addMessageAfterRedirect(__('Pre Update Computer Hook', 'example'), true); } // Hook done on update item case -function plugin_item_update_example($item) { - Session::addMessageAfterRedirect(sprintf(__("Update Computer Hook (%s)", 'example'), implode(',', $item->updates)), true); - return true; +function plugin_item_update_example($item) +{ + Session::addMessageAfterRedirect(sprintf(__('Update Computer Hook (%s)', 'example'), implode(',', $item->updates)), true); + + return true; } // Hook done on get empty item case -function plugin_item_empty_example($item) { - if (empty($_SESSION['Already displayed "Empty Computer Hook"'])) { - Session::addMessageAfterRedirect(__("Empty Computer Hook", 'example'), true); - $_SESSION['Already displayed "Empty Computer Hook"'] = true; - } - return true; +function plugin_item_empty_example($item) +{ + if (empty($_SESSION['Already displayed "Empty Computer Hook"'])) { + Session::addMessageAfterRedirect(__('Empty Computer Hook', 'example'), true); + $_SESSION['Already displayed "Empty Computer Hook"'] = true; + } + + return true; } // Hook done on before delete item case -function plugin_pre_item_delete_example($object) { - // Manipulate data if needed - Session::addMessageAfterRedirect(__("Pre Delete Computer Hook", 'example'), true); +function plugin_pre_item_delete_example($object) +{ + // Manipulate data if needed + Session::addMessageAfterRedirect(__('Pre Delete Computer Hook', 'example'), true); } // Hook done on delete item case -function plugin_item_delete_example($object) { - Session::addMessageAfterRedirect(__("Delete Computer Hook", 'example'), true); - return true; +function plugin_item_delete_example($object) +{ + Session::addMessageAfterRedirect(__('Delete Computer Hook', 'example'), true); + + return true; } // Hook done on before purge item case -function plugin_pre_item_purge_example($object) { - // Manipulate data if needed - Session::addMessageAfterRedirect(__("Pre Purge Computer Hook", 'example'), true); +function plugin_pre_item_purge_example($object) +{ + // Manipulate data if needed + Session::addMessageAfterRedirect(__('Pre Purge Computer Hook', 'example'), true); } // Hook done on purge item case -function plugin_item_purge_example($object) { - Session::addMessageAfterRedirect(__("Purge Computer Hook", 'example'), true); - return true; +function plugin_item_purge_example($object) +{ + Session::addMessageAfterRedirect(__('Purge Computer Hook', 'example'), true); + + return true; } // Hook done on before restore item case -function plugin_pre_item_restore_example($item) { - // Manipulate data if needed - Session::addMessageAfterRedirect(__("Pre Restore Computer Hook", 'example')); +function plugin_pre_item_restore_example($item) +{ + // Manipulate data if needed + Session::addMessageAfterRedirect(__('Pre Restore Computer Hook', 'example')); } // Hook done on before restore item case -function plugin_pre_item_restore_example2($item) { - // Manipulate data if needed - Session::addMessageAfterRedirect(__("Pre Restore Phone Hook", 'example')); +function plugin_pre_item_restore_example2($item) +{ + // Manipulate data if needed + Session::addMessageAfterRedirect(__('Pre Restore Phone Hook', 'example')); } // Hook done on restore item case -function plugin_item_restore_example($item) { - Session::addMessageAfterRedirect(__("Restore Computer Hook", 'example')); - return true; +function plugin_item_restore_example($item) +{ + Session::addMessageAfterRedirect(__('Restore Computer Hook', 'example')); + + return true; } // Hook done on restore item case -function plugin_item_transfer_example($parm) { - //TRANS: %1$s is the source type, %2$d is the source ID, %3$d is the destination ID - Session::addMessageAfterRedirect(sprintf(__('Transfer Computer Hook %1$s %2$d -> %3$d', 'example'), $parm['type'], $parm['id'], - $parm['newID'])); +function plugin_item_transfer_example($parm) +{ + //TRANS: %1$s is the source type, %2$d is the source ID, %3$d is the destination ID + Session::addMessageAfterRedirect(sprintf( + __('Transfer Computer Hook %1$s %2$d -> %3$d', 'example'), + $parm['type'], + $parm['id'], + $parm['newID'], + )); - return false; + return false; } // Do special actions for dynamic report -function plugin_example_dynamicReport($parm) { - if ($parm["item_type"] == Example::class) { - // Do all what you want for export depending on $parm - echo "Personalized export for type ".$parm["display_type"]; - echo 'with additional datas :
'; - echo "Single data : add1
"; - print $parm['add1'].'
'; - echo "Array data : add2
"; - Html::printCleanArray($parm['add2']); - // Return true if personalized display is done - return true; - } - // Return false if no specific display is done, then use standard display - return false; +function plugin_example_dynamicReport($parm) +{ + if ($parm['item_type'] == Example::class) { + // Do all what you want for export depending on $parm + echo 'Personalized export for type ' . $parm['display_type']; + echo 'with additional datas :
'; + echo 'Single data : add1
'; + print $parm['add1'] . '
'; + echo 'Array data : add2
'; + Html::printCleanArray($parm['add2']); + + // Return true if personalized display is done + return true; + } + + // Return false if no specific display is done, then use standard display + return false; } // Add parameters to Html::printPager in search system -function plugin_example_addParamFordynamicReport($itemtype) { - if ($itemtype == Example::class) { - // Return array data containing all params to add : may be single data or array data - // Search config are available from session variable - return ['add1' => $_SESSION['glpisearch'][$itemtype]['order'], - 'add2' => ['tutu' => 'Second Add', - 'Other Data']]; - } - // Return false or a non array data if not needed - return false; +function plugin_example_addParamFordynamicReport($itemtype) +{ + if ($itemtype == Example::class) { + // Return array data containing all params to add : may be single data or array data + // Search config are available from session variable + return ['add1' => $_SESSION['glpisearch'][$itemtype]['order'], + 'add2' => ['tutu' => 'Second Add', + 'Other Data']]; + } + + // Return false or a non array data if not needed + return false; } @@ -454,24 +522,25 @@ function plugin_example_addParamFordynamicReport($itemtype) { * * @return boolean */ -function plugin_example_install() { - global $DB; +function plugin_example_install() +{ + global $DB; - $migration = new Migration(PLUGIN_EXAMPLE_VERSION); - Config::setConfigurationValues('plugin:Example', ['configuration' => false]); + $migration = new Migration(PLUGIN_EXAMPLE_VERSION); + Config::setConfigurationValues('plugin:Example', ['configuration' => false]); - // Adds the right(s) to all pre-existing profiles with no access by default - ProfileRight::addProfileRights([Example::$rightname]); + // Adds the right(s) to all pre-existing profiles with no access by default + ProfileRight::addProfileRights([Example::$rightname]); - // Grants full access to profiles that can update the Config (super-admins) - $migration->addRight(Example::$rightname, ALLSTANDARDRIGHT, [Config::$rightname => UPDATE]); + // Grants full access to profiles that can update the Config (super-admins) + $migration->addRight(Example::$rightname, ALLSTANDARDRIGHT, [Config::$rightname => UPDATE]); - $default_charset = DBConnection::getDefaultCharset(); - $default_collation = DBConnection::getDefaultCollation(); - $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); + $default_charset = DBConnection::getDefaultCharset(); + $default_collation = DBConnection::getDefaultCollation(); + $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); - if (!$DB->tableExists("glpi_plugin_example_examples")) { - $query = "CREATE TABLE `glpi_plugin_example_examples` ( + if (!$DB->tableExists('glpi_plugin_example_examples')) { + $query = "CREATE TABLE `glpi_plugin_example_examples` ( `id` int {$default_key_sign} NOT NULL auto_increment, `name` varchar(255) default NULL, `serial` varchar(255) NOT NULL, @@ -482,19 +551,19 @@ function plugin_example_install() { PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die("error creating glpi_plugin_example_examples ". $DB->error()); + $DB->query($query) or die('error creating glpi_plugin_example_examples ' . $DB->error()); - $query = "INSERT INTO `glpi_plugin_example_examples` + $query = "INSERT INTO `glpi_plugin_example_examples` (`id`, `name`, `serial`, `plugin_example_dropdowns_id`, `is_deleted`, `is_template`, `template_name`) VALUES (1, 'example 1', 'serial 1', 1, 0, 0, NULL), (2, 'example 2', 'serial 2', 2, 0, 0, NULL), (3, 'example 3', 'serial 3', 1, 0, 0, NULL)"; - $DB->query($query) or die("error populate glpi_plugin_example ". $DB->error()); - } + $DB->query($query) or die('error populate glpi_plugin_example ' . $DB->error()); + } - if (!$DB->tableExists("glpi_plugin_example_dropdowns")) { - $query = "CREATE TABLE `glpi_plugin_example_dropdowns` ( + if (!$DB->tableExists('glpi_plugin_example_dropdowns')) { + $query = "CREATE TABLE `glpi_plugin_example_dropdowns` ( `id` int {$default_key_sign} NOT NULL auto_increment, `name` varchar(255) default NULL, `comment` text, @@ -502,19 +571,18 @@ function plugin_example_install() { KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die("error creating glpi_plugin_example_dropdowns". $DB->error()); + $DB->query($query) or die('error creating glpi_plugin_example_dropdowns' . $DB->error()); - $query = "INSERT INTO `glpi_plugin_example_dropdowns` + $query = "INSERT INTO `glpi_plugin_example_dropdowns` (`id`, `name`, `comment`) VALUES (1, 'dp 1', 'comment 1'), (2, 'dp2', 'comment 2')"; - $DB->query($query) or die("error populate glpi_plugin_example_dropdowns". $DB->error()); - - } + $DB->query($query) or die('error populate glpi_plugin_example_dropdowns' . $DB->error()); + } - if (!$DB->tableExists('glpi_plugin_example_devicecameras')) { - $query = "CREATE TABLE `glpi_plugin_example_devicecameras` ( + if (!$DB->tableExists('glpi_plugin_example_devicecameras')) { + $query = "CREATE TABLE `glpi_plugin_example_devicecameras` ( `id` int {$default_key_sign} NOT NULL AUTO_INCREMENT, `designation` varchar(255) DEFAULT NULL, `comment` text, @@ -524,11 +592,11 @@ function plugin_example_install() { KEY `manufacturers_id` (`manufacturers_id`) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die("error creating glpi_plugin_example_examples ". $DB->error()); - } + $DB->query($query) or die('error creating glpi_plugin_example_examples ' . $DB->error()); + } - if (!$DB->tableExists('glpi_plugin_example_items_devicecameras')) { - $query = "CREATE TABLE `glpi_plugin_example_items_devicecameras` ( + if (!$DB->tableExists('glpi_plugin_example_items_devicecameras')) { + $query = "CREATE TABLE `glpi_plugin_example_items_devicecameras` ( `id` int {$default_key_sign} NOT NULL AUTO_INCREMENT, `items_id` int {$default_key_sign} NOT NULL DEFAULT '0', `itemtype` varchar(255) DEFAULT NULL, @@ -542,13 +610,14 @@ function plugin_example_install() { KEY `is_dynamic` (`is_dynamic`) ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die("error creating glpi_plugin_example_examples ". $DB->error()); - } + $DB->query($query) or die('error creating glpi_plugin_example_examples ' . $DB->error()); + } + + // To be called for each task the plugin manage + // task in class + CronTask::Register(Example::class, 'Sample', DAY_TIMESTAMP, ['param' => 50]); - // To be called for each task the plugin manage - // task in class - CronTask::Register(Example::class, 'Sample', DAY_TIMESTAMP, ['param' => 50]); - return true; + return true; } @@ -557,74 +626,81 @@ function plugin_example_install() { * * @return boolean */ -function plugin_example_uninstall() { - global $DB; +function plugin_example_uninstall() +{ + global $DB; + + $config = new Config(); + $config->deleteConfigurationValues('plugin:Example', ['configuration' => false]); - $config = new Config(); - $config->deleteConfigurationValues('plugin:Example', ['configuration' => false]); + ProfileRight::deleteProfileRights([Example::$rightname]); - ProfileRight::deleteProfileRights([Example::$rightname]); + $notif = new Notification(); + $options = ['itemtype' => 'Ticket', + 'event' => 'plugin_example', + 'FIELDS' => 'id']; + foreach ($DB->request('glpi_notifications', $options) as $data) { + $notif->delete($data); + } + // Old version tables + if ($DB->tableExists('glpi_dropdown_plugin_example')) { + $query = 'DROP TABLE `glpi_dropdown_plugin_example`'; + $DB->query($query) or die('error deleting glpi_dropdown_plugin_example'); + } + if ($DB->tableExists('glpi_plugin_example')) { + $query = 'DROP TABLE `glpi_plugin_example`'; + $DB->query($query) or die('error deleting glpi_plugin_example'); + } + // Current version tables + if ($DB->tableExists('glpi_plugin_example_example')) { + $query = 'DROP TABLE `glpi_plugin_example_example`'; + $DB->query($query) or die('error deleting glpi_plugin_example_example'); + } + if ($DB->tableExists('glpi_plugin_example_dropdowns')) { + $query = 'DROP TABLE `glpi_plugin_example_dropdowns`;'; + $DB->query($query) or die('error deleting glpi_plugin_example_dropdowns'); + } + if ($DB->tableExists('glpi_plugin_example_devicecameras')) { + $query = 'DROP TABLE `glpi_plugin_example_devicecameras`;'; + $DB->query($query) or die('error deleting glpi_plugin_example_devicecameras'); + } + if ($DB->tableExists('glpi_plugin_example_items_devicecameras')) { + $query = 'DROP TABLE `glpi_plugin_example_items_devicecameras`;'; + $DB->query($query) or die('error deleting glpi_plugin_example_items_devicecameras'); + } - $notif = new Notification(); - $options = ['itemtype' => 'Ticket', - 'event' => 'plugin_example', - 'FIELDS' => 'id']; - foreach ($DB->request('glpi_notifications', $options) as $data) { - $notif->delete($data); - } - // Old version tables - if ($DB->tableExists("glpi_dropdown_plugin_example")) { - $query = "DROP TABLE `glpi_dropdown_plugin_example`"; - $DB->query($query) or die("error deleting glpi_dropdown_plugin_example"); - } - if ($DB->tableExists("glpi_plugin_example")) { - $query = "DROP TABLE `glpi_plugin_example`"; - $DB->query($query) or die("error deleting glpi_plugin_example"); - } - // Current version tables - if ($DB->tableExists("glpi_plugin_example_example")) { - $query = "DROP TABLE `glpi_plugin_example_example`"; - $DB->query($query) or die("error deleting glpi_plugin_example_example"); - } - if ($DB->tableExists("glpi_plugin_example_dropdowns")) { - $query = "DROP TABLE `glpi_plugin_example_dropdowns`;"; - $DB->query($query) or die("error deleting glpi_plugin_example_dropdowns"); - } - if ($DB->tableExists("glpi_plugin_example_devicecameras")) { - $query = "DROP TABLE `glpi_plugin_example_devicecameras`;"; - $DB->query($query) or die("error deleting glpi_plugin_example_devicecameras"); - } - if ($DB->tableExists("glpi_plugin_example_items_devicecameras")) { - $query = "DROP TABLE `glpi_plugin_example_items_devicecameras`;"; - $DB->query($query) or die("error deleting glpi_plugin_example_items_devicecameras"); - } - return true; + return true; } -function plugin_example_AssignToTicket($types) { - $types[Example::class] = "Example"; - return $types; +function plugin_example_AssignToTicket($types) +{ + $types[Example::class] = 'Example'; + + return $types; } -function plugin_example_get_events(NotificationTargetTicket $target) { - $target->events['plugin_example'] = __("Example event", 'example'); +function plugin_example_get_events(NotificationTargetTicket $target) +{ + $target->events['plugin_example'] = __('Example event', 'example'); } -function plugin_example_get_datas(NotificationTargetTicket $target) { - $target->data['##ticket.example##'] = __("Example datas", 'example'); +function plugin_example_get_datas(NotificationTargetTicket $target) +{ + $target->data['##ticket.example##'] = __('Example datas', 'example'); } -function plugin_example_postinit() { - global $CFG_GLPI; +function plugin_example_postinit() +{ + global $CFG_GLPI; - // All plugins are initialized, so all types are registered - //foreach (Infocom::getItemtypesThatCanHave() as $type) { - // do something - //} + // All plugins are initialized, so all types are registered + //foreach (Infocom::getItemtypesThatCanHave() as $type) { + // do something + //} } @@ -636,8 +712,9 @@ function plugin_example_postinit() { * * @return un tableau **/ -function plugin_retrieve_more_data_from_ldap_example(array $datas) { - return $datas; +function plugin_retrieve_more_data_from_ldap_example(array $datas) +{ + return $datas; } @@ -648,47 +725,54 @@ function plugin_retrieve_more_data_from_ldap_example(array $datas) { * * @return un tableau **/ -function plugin_retrieve_more_field_from_ldap_example($fields) { - return $fields; +function plugin_retrieve_more_field_from_ldap_example($fields) +{ + return $fields; } // Check to add to status page -function plugin_example_Status($param) { - // Do checks (no check for example) - $ok = true; - echo "example plugin: example"; - if ($ok) { - echo "_OK"; - } else { - echo "_PROBLEM"; - // Only set ok to false if trouble (global status) - $param['ok'] = false; - } - echo "\n"; - return $param; -} - -function plugin_example_display_central() { - echo ""; - echo "
"; - echo __("Plugin example displays on central page", "example"); - echo "
"; - echo ""; -} - -function plugin_example_display_login() { - echo "
"; - echo __("Plugin example displays on login page", "example"); - echo "
"; -} - -function plugin_example_infocom_hook($params) { - echo ""; - echo __("Plugin example displays on central page", "example"); - echo ""; -} - -function plugin_example_filter_actors(array $params = []): array { +function plugin_example_Status($param) +{ + // Do checks (no check for example) + $ok = true; + echo 'example plugin: example'; + if ($ok) { + echo '_OK'; + } else { + echo '_PROBLEM'; + // Only set ok to false if trouble (global status) + $param['ok'] = false; + } + echo "\n"; + + return $param; +} + +function plugin_example_display_central() +{ + echo ""; + echo "
"; + echo __('Plugin example displays on central page', 'example'); + echo '
'; + echo ''; +} + +function plugin_example_display_login() +{ + echo "
"; + echo __('Plugin example displays on login page', 'example'); + echo '
'; +} + +function plugin_example_infocom_hook($params) +{ + echo ""; + echo __('Plugin example displays on central page', 'example'); + echo ''; +} + +function plugin_example_filter_actors(array $params = []): array +{ $itemtype = $params['params']['itemtype']; $items_id = $params['params']['items_id']; @@ -704,7 +788,8 @@ function plugin_example_filter_actors(array $params = []): array { return $params; } -function plugin_example_set_impact_icon(array $params) { +function plugin_example_set_impact_icon(array $params) +{ $itemtype = $params['itemtype']; $items_id = $params['items_id']; @@ -712,5 +797,6 @@ function plugin_example_set_impact_icon(array $params) { if ($item instanceof Computer && $item->getFromDB($items_id)) { return Plugin::getWebDir('example', true, false) . '/public/computer_icon.svg'; } + return null; } diff --git a/report.php b/report.php index 51853f3..47251ef 100644 --- a/report.php +++ b/report.php @@ -38,12 +38,12 @@ // Entry menu case define('GLPI_ROOT', '../..'); -include (GLPI_ROOT . "/inc/includes.php"); +include(GLPI_ROOT . '/inc/includes.php'); Session::checkRight(Config::$rightname, UPDATE); -Html::header("TITRE", $_SERVER['PHP_SELF'], "plugins"); +Html::header('TITRE', $_SERVER['PHP_SELF'], 'plugins'); -echo "This is the plugin report page"; +echo 'This is the plugin report page'; Html::footer(); diff --git a/setup.php b/setup.php index 6d3c216..8d71794 100644 --- a/setup.php +++ b/setup.php @@ -52,249 +52,256 @@ * * @return void */ -function plugin_init_example() { - global $PLUGIN_HOOKS,$CFG_GLPI; - - // Params : plugin name - string type - ID - Array of attributes - // No specific information passed so not needed - //Plugin::registerClass(Example::getType(), - // array('classname' => Example::class, - // )); - - Plugin::registerClass(Config::class, ['addtabon' => 'Config']); - - // Params : plugin name - string type - ID - Array of attributes - Plugin::registerClass(Dropdown::class); - - $types = ['Central', 'Computer', 'ComputerDisk', 'Notification', 'Phone', - 'Preference', 'Profile', 'Supplier']; - Plugin::registerClass(Example::class, - ['notificationtemplates_types' => true, - 'addtabon' => $types, - 'link_types' => true]); - - Plugin::registerClass(RuleTestCollection::class, - ['rulecollections_types' => true]); - - Plugin::registerClass(DeviceCamera::class, - ['device_types' => true]); - - if (version_compare(GLPI_VERSION, '9.1', 'ge')) { - if (class_exists(Example::class)) { - Link::registerTag(Example::$tags); - } - } - // Display a menu entry ? - Plugin::registerClass(\GlpiPlugin\Example\Profile::class, ['addtabon' => ['Profile']]); - if (Example::canView()) { // Right set in change_profile hook - $PLUGIN_HOOKS['menu_toadd']['example'] = ['plugins' => Example::class, - 'tools' => Example::class]; - - // Old menu style - // $PLUGIN_HOOKS['menu_entry']['example'] = 'front/example.php'; - // - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['title'] = "Search"; - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['page'] = '/plugins/example/front/example.php'; - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']['search'] = '/plugins/example/front/example.php'; - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']['add'] = '/plugins/example/front/example.form.php'; - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']['config'] = '/plugins/example/index.php'; - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']["".__s("] = '/plugins/example/index.php'; - // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links'][__s('Test link', 'example')] = '/plugins/example/index.php'; - - $PLUGIN_HOOKS[Hooks::HELPDESK_MENU_ENTRY]['example'] = true; - $PLUGIN_HOOKS[Hooks::HELPDESK_MENU_ENTRY_ICON]['example'] = 'fas fa-puzzle-piece'; - } - - // Config page - if (Session::haveRight('config', UPDATE)) { - $PLUGIN_HOOKS['config_page']['example'] = 'front/config.php'; - } - - // Init session - //$PLUGIN_HOOKS['init_session']['example'] = 'plugin_init_session_example'; - // Change profile - $PLUGIN_HOOKS['change_profile']['example'] = 'plugin_change_profile_example'; - // Change entity - //$PLUGIN_HOOKS['change_entity']['example'] = 'plugin_change_entity_example'; - - // Item action event // See define.php for defined ITEM_TYPE - $PLUGIN_HOOKS[Hooks::PRE_ITEM_UPDATE]['example'] = [Computer::class => 'plugin_pre_item_update_example']; - $PLUGIN_HOOKS[hooks::ITEM_UPDATE]['example'] = [Computer::class => 'plugin_item_update_example']; - - $PLUGIN_HOOKS[Hooks::ITEM_EMPTY]['example'] = [Computer::class => 'plugin_item_empty_example']; - - // Restrict right - $PLUGIN_HOOKS[Hooks::ITEM_CAN]['example'] = [Computer::class => [Example::class, 'item_can']]; - $PLUGIN_HOOKS['add_default_where']['example'] = [Computer::class => [Example::class, 'add_default_where']]; - - // Example using a method in class - $PLUGIN_HOOKS[Hooks::PRE_ITEM_ADD]['example'] = [Computer::class => [Example::class, - 'pre_item_add_computer']]; - $PLUGIN_HOOKS[Hooks::POST_PREPAREADD]['example'] = [Computer::class => [Example::class, - 'post_prepareadd_computer']]; - $PLUGIN_HOOKS[Hooks::ITEM_ADD]['example'] = [Computer::class => [Example::class, - 'item_add_computer']]; - - $PLUGIN_HOOKS[Hooks::PRE_ITEM_DELETE]['example'] = [Computer::class => 'plugin_pre_item_delete_example']; - $PLUGIN_HOOKS[Hooks::ITEM_DELETE]['example'] = [Computer::class => 'plugin_item_delete_example']; - - // Example using the same function - $PLUGIN_HOOKS[Hooks::PRE_ITEM_PURGE]['example'] = [Computer::class => 'plugin_pre_item_purge_example', - 'Phone' => 'plugin_pre_item_purge_example']; - $PLUGIN_HOOKS[Hooks::ITEM_PURGE]['example'] = [Computer::class => 'plugin_item_purge_example', - 'Phone' => 'plugin_item_purge_example']; - - // Example with 2 different functions - $PLUGIN_HOOKS[Hooks::PRE_ITEM_RESTORE]['example'] = [Computer::class => 'plugin_pre_item_restore_example', - 'Phone' => 'plugin_pre_item_restore_example2']; - $PLUGIN_HOOKS[Hooks::ITEM_RESTORE]['example'] = [Computer::class => 'plugin_item_restore_example']; - - // Add event to GLPI core itemtype, event will be raised by the plugin. - // See plugin_example_uninstall for cleanup of notification - $PLUGIN_HOOKS[Hooks::ITEM_GET_EVENTS]['example'] - = ['NotificationTargetTicket' => 'plugin_example_get_events']; - - // Add datas to GLPI core itemtype for notifications template. - $PLUGIN_HOOKS[Hooks::ITEM_GET_DATA]['example'] - = ['NotificationTargetTicket' => 'plugin_example_get_datas']; - - $PLUGIN_HOOKS[Hooks::ITEM_TRANSFER]['example'] = 'plugin_item_transfer_example'; - - // function to populate planning - // No more used since GLPI 0.84 - // $PLUGIN_HOOKS['planning_populate']['example'] = 'plugin_planning_populate_example'; - // Use instead : add class to planning types and define populatePlanning in class - $CFG_GLPI['planning_types'][] = Example::class; - - //function to display planning items - // No more used sinc GLPi 0.84 - // $PLUGIN_HOOKS['display_planning']['example'] = 'plugin_display_planning_example'; - // Use instead : displayPlanningItem of the specific itemtype - - // Massive Action definition - $PLUGIN_HOOKS['use_massive_action']['example'] = 1; - - $PLUGIN_HOOKS['assign_to_ticket']['example'] = 1; - - // Add specific files to add to the header : javascript or css - $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['example'] = 'example.js'; - $PLUGIN_HOOKS[Hooks::ADD_CSS]['example'] = 'example.css'; - - // Add specific tags to the header - $PLUGIN_HOOKS[Hooks::ADD_HEADER_TAG]['example'] = [ - [ - 'tag' => 'meta', - 'properties' => [ - 'name' => 'robots', - 'content' => 'noindex, nofollow', - ] - ], - [ - 'tag' => 'link', - 'properties' => [ - 'rel' => 'alternate', - 'type' => 'application/rss+xml', - 'title' => 'The company RSS feed', - 'href' => 'https://example.org/feed.xml', - ] - ], - ]; - - // Add specific files to add to the header into anonymous page : javascript or css - $PLUGIN_HOOKS[Hooks::ADD_CSS_ANONYMOUS_PAGE]['example'] = 'example_anonymous.css'; - $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT_MODULE_ANONYMOUS_PAGE]['example'] = 'mymodule_anonymous.js'; - $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT_ANONYMOUS_PAGE]['example'] = 'example_anonymous.js'; - - // Add specific tags to the header into anonymous page - $PLUGIN_HOOKS[Hooks::ADD_HEADER_TAG_ANONYMOUS_PAGE]['example'] = [ - [ - 'tag' => 'meta', - 'properties' => [ - 'name' => 'robots', - 'content' => 'noindex, nofollow', - ] - ], - [ - 'tag' => 'link', - 'properties' => [ - 'rel' => 'alternate', - 'type' => 'application/rss+xml', - 'title' => 'The company RSS feed', - 'href' => 'https://example.org/feed.xml', - ] - ], - ]; - - // request more attributes from ldap - //$PLUGIN_HOOKS['retrieve_more_field_from_ldap']['example']="plugin_retrieve_more_field_from_ldap_example"; - - // Retrieve others datas from LDAP - //$PLUGIN_HOOKS['retrieve_more_data_from_ldap']['example']="plugin_retrieve_more_data_from_ldap_example"; - - // Reports - $PLUGIN_HOOKS['reports']['example'] = ['report.php' => 'New Report', - 'report.php?other' => 'New Report 2']; - - // Stats - $PLUGIN_HOOKS['stats']['example'] = ['stat.php' => 'New stat', - 'stat.php?other' => 'New stats 2',]; - - $PLUGIN_HOOKS[Hooks::POST_INIT]['example'] = 'plugin_example_postinit'; - - $PLUGIN_HOOKS['status']['example'] = 'plugin_example_Status'; - - // CSRF compliance : All actions must be done via POST and forms closed by Html::closeForm(); - $PLUGIN_HOOKS[Hooks::CSRF_COMPLIANT]['example'] = true; - - $PLUGIN_HOOKS[Hooks::DISPLAY_CENTRAL]['example'] = "plugin_example_display_central"; - $PLUGIN_HOOKS[Hooks::DISPLAY_LOGIN]['example'] = "plugin_example_display_login"; - $PLUGIN_HOOKS[Hooks::INFOCOM]['example'] = "plugin_example_infocom_hook"; - - // pre_show and post_show for tabs and items, - // see GlpiPlugin\Example\Showtabitem class for implementation explanations - $PLUGIN_HOOKS[Hooks::PRE_SHOW_TAB]['example'] = [Showtabitem::class, 'pre_show_tab']; - $PLUGIN_HOOKS[Hooks::POST_SHOW_TAB]['example'] = [Showtabitem::class, 'post_show_tab']; - $PLUGIN_HOOKS[Hooks::PRE_SHOW_ITEM]['example'] = [Showtabitem::class, 'pre_show_item']; - $PLUGIN_HOOKS[Hooks::POST_SHOW_ITEM]['example'] = [Showtabitem::class, 'post_show_item']; - - $PLUGIN_HOOKS[Hooks::PRE_ITEM_FORM]['example'] = [ItemForm::class, 'preItemForm']; - $PLUGIN_HOOKS[Hooks::POST_ITEM_FORM]['example'] = [ItemForm::class, 'postItemForm']; - - //TODO: remove check when GLPI 11.0.0 is released - if (version_compare(GLPI_VERSION, '11.0.0', 'ge')) { - $PLUGIN_HOOKS[Hooks::PRE_ITIL_INFO_SECTION]['example'] = [ItemForm::class, 'preSection']; - $PLUGIN_HOOKS[Hooks::POST_ITIL_INFO_SECTION]['example'] = [ItemForm::class, 'postSection']; - } - - // Add new actions to timeline - $PLUGIN_HOOKS[Hooks::TIMELINE_ACTIONS]['example'] = [ - ItemForm::class, 'timelineActions' - ]; - - // declare this plugin as an import plugin for Computer itemtype - $PLUGIN_HOOKS['import_item']['example'] = [Computer::class => ['Plugin']]; - - // add additional informations on Computer::showForm - $PLUGIN_HOOKS[Hooks::AUTOINVENTORY_INFORMATION]['example'] = [ - Computer::class => [Computer::class, 'showInfo'] - ]; - - $PLUGIN_HOOKS[Hooks::FILTER_ACTORS]['example'] = "plugin_example_filter_actors"; - - // add new cards to dashboard grid - $PLUGIN_HOOKS['dashboard_types']['example'] = [Example::class, 'dashboardTypes']; - $PLUGIN_HOOKS['dashboard_cards']['example'] = [Example::class, 'dashboardCards']; - - // Dashboard filter - $PLUGIN_HOOKS[Hooks::DASHBOARD_FILTERS]['example'] = [ - ComputerModelFilter::class - ]; - - //TODO: remove check when GLPI 11.0.0 is released - if (version_compare(GLPI_VERSION, '11.0.0', 'ge')) { - // Icon in the impact analysis - $PLUGIN_HOOKS[Hooks::SET_ITEM_IMPACT_ICON]['example'] = 'plugin_example_set_impact_icon'; - } +function plugin_init_example() +{ + global $PLUGIN_HOOKS,$CFG_GLPI; + + // Params : plugin name - string type - ID - Array of attributes + // No specific information passed so not needed + //Plugin::registerClass(Example::getType(), + // array('classname' => Example::class, + // )); + + Plugin::registerClass(Config::class, ['addtabon' => 'Config']); + + // Params : plugin name - string type - ID - Array of attributes + Plugin::registerClass(Dropdown::class); + + $types = ['Central', 'Computer', 'ComputerDisk', 'Notification', 'Phone', + 'Preference', 'Profile', 'Supplier']; + Plugin::registerClass( + Example::class, + ['notificationtemplates_types' => true, + 'addtabon' => $types, + 'link_types' => true], + ); + + Plugin::registerClass( + RuleTestCollection::class, + ['rulecollections_types' => true], + ); + + Plugin::registerClass( + DeviceCamera::class, + ['device_types' => true], + ); + + if (version_compare(GLPI_VERSION, '9.1', 'ge')) { + if (class_exists(Example::class)) { + Link::registerTag(Example::$tags); + } + } + // Display a menu entry ? + Plugin::registerClass(\GlpiPlugin\Example\Profile::class, ['addtabon' => ['Profile']]); + if (Example::canView()) { // Right set in change_profile hook + $PLUGIN_HOOKS['menu_toadd']['example'] = ['plugins' => Example::class, + 'tools' => Example::class]; + + // Old menu style + // $PLUGIN_HOOKS['menu_entry']['example'] = 'front/example.php'; + // + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['title'] = "Search"; + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['page'] = '/plugins/example/front/example.php'; + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']['search'] = '/plugins/example/front/example.php'; + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']['add'] = '/plugins/example/front/example.form.php'; + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']['config'] = '/plugins/example/index.php'; + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links']["".__s("] = '/plugins/example/index.php'; + // $PLUGIN_HOOKS['submenu_entry']['example']['options']['optionname']['links'][__s('Test link', 'example')] = '/plugins/example/index.php'; + + $PLUGIN_HOOKS[Hooks::HELPDESK_MENU_ENTRY]['example'] = true; + $PLUGIN_HOOKS[Hooks::HELPDESK_MENU_ENTRY_ICON]['example'] = 'fas fa-puzzle-piece'; + } + + // Config page + if (Session::haveRight('config', UPDATE)) { + $PLUGIN_HOOKS['config_page']['example'] = 'front/config.php'; + } + + // Init session + //$PLUGIN_HOOKS['init_session']['example'] = 'plugin_init_session_example'; + // Change profile + $PLUGIN_HOOKS['change_profile']['example'] = 'plugin_change_profile_example'; + // Change entity + //$PLUGIN_HOOKS['change_entity']['example'] = 'plugin_change_entity_example'; + + // Item action event // See define.php for defined ITEM_TYPE + $PLUGIN_HOOKS[Hooks::PRE_ITEM_UPDATE]['example'] = [Computer::class => 'plugin_pre_item_update_example']; + $PLUGIN_HOOKS[hooks::ITEM_UPDATE]['example'] = [Computer::class => 'plugin_item_update_example']; + + $PLUGIN_HOOKS[Hooks::ITEM_EMPTY]['example'] = [Computer::class => 'plugin_item_empty_example']; + + // Restrict right + $PLUGIN_HOOKS[Hooks::ITEM_CAN]['example'] = [Computer::class => [Example::class, 'item_can']]; + $PLUGIN_HOOKS['add_default_where']['example'] = [Computer::class => [Example::class, 'add_default_where']]; + + // Example using a method in class + $PLUGIN_HOOKS[Hooks::PRE_ITEM_ADD]['example'] = [Computer::class => [Example::class, + 'pre_item_add_computer']]; + $PLUGIN_HOOKS[Hooks::POST_PREPAREADD]['example'] = [Computer::class => [Example::class, + 'post_prepareadd_computer']]; + $PLUGIN_HOOKS[Hooks::ITEM_ADD]['example'] = [Computer::class => [Example::class, + 'item_add_computer']]; + + $PLUGIN_HOOKS[Hooks::PRE_ITEM_DELETE]['example'] = [Computer::class => 'plugin_pre_item_delete_example']; + $PLUGIN_HOOKS[Hooks::ITEM_DELETE]['example'] = [Computer::class => 'plugin_item_delete_example']; + + // Example using the same function + $PLUGIN_HOOKS[Hooks::PRE_ITEM_PURGE]['example'] = [Computer::class => 'plugin_pre_item_purge_example', + 'Phone' => 'plugin_pre_item_purge_example']; + $PLUGIN_HOOKS[Hooks::ITEM_PURGE]['example'] = [Computer::class => 'plugin_item_purge_example', + 'Phone' => 'plugin_item_purge_example']; + + // Example with 2 different functions + $PLUGIN_HOOKS[Hooks::PRE_ITEM_RESTORE]['example'] = [Computer::class => 'plugin_pre_item_restore_example', + 'Phone' => 'plugin_pre_item_restore_example2']; + $PLUGIN_HOOKS[Hooks::ITEM_RESTORE]['example'] = [Computer::class => 'plugin_item_restore_example']; + + // Add event to GLPI core itemtype, event will be raised by the plugin. + // See plugin_example_uninstall for cleanup of notification + $PLUGIN_HOOKS[Hooks::ITEM_GET_EVENTS]['example'] + = ['NotificationTargetTicket' => 'plugin_example_get_events']; + + // Add datas to GLPI core itemtype for notifications template. + $PLUGIN_HOOKS[Hooks::ITEM_GET_DATA]['example'] + = ['NotificationTargetTicket' => 'plugin_example_get_datas']; + + $PLUGIN_HOOKS[Hooks::ITEM_TRANSFER]['example'] = 'plugin_item_transfer_example'; + + // function to populate planning + // No more used since GLPI 0.84 + // $PLUGIN_HOOKS['planning_populate']['example'] = 'plugin_planning_populate_example'; + // Use instead : add class to planning types and define populatePlanning in class + $CFG_GLPI['planning_types'][] = Example::class; + + //function to display planning items + // No more used sinc GLPi 0.84 + // $PLUGIN_HOOKS['display_planning']['example'] = 'plugin_display_planning_example'; + // Use instead : displayPlanningItem of the specific itemtype + + // Massive Action definition + $PLUGIN_HOOKS['use_massive_action']['example'] = 1; + + $PLUGIN_HOOKS['assign_to_ticket']['example'] = 1; + + // Add specific files to add to the header : javascript or css + $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['example'] = 'example.js'; + $PLUGIN_HOOKS[Hooks::ADD_CSS]['example'] = 'example.css'; + + // Add specific tags to the header + $PLUGIN_HOOKS[Hooks::ADD_HEADER_TAG]['example'] = [ + [ + 'tag' => 'meta', + 'properties' => [ + 'name' => 'robots', + 'content' => 'noindex, nofollow', + ], + ], + [ + 'tag' => 'link', + 'properties' => [ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => 'The company RSS feed', + 'href' => 'https://example.org/feed.xml', + ], + ], + ]; + + // Add specific files to add to the header into anonymous page : javascript or css + $PLUGIN_HOOKS[Hooks::ADD_CSS_ANONYMOUS_PAGE]['example'] = 'example_anonymous.css'; + $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT_MODULE_ANONYMOUS_PAGE]['example'] = 'mymodule_anonymous.js'; + $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT_ANONYMOUS_PAGE]['example'] = 'example_anonymous.js'; + + // Add specific tags to the header into anonymous page + $PLUGIN_HOOKS[Hooks::ADD_HEADER_TAG_ANONYMOUS_PAGE]['example'] = [ + [ + 'tag' => 'meta', + 'properties' => [ + 'name' => 'robots', + 'content' => 'noindex, nofollow', + ], + ], + [ + 'tag' => 'link', + 'properties' => [ + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => 'The company RSS feed', + 'href' => 'https://example.org/feed.xml', + ], + ], + ]; + + // request more attributes from ldap + //$PLUGIN_HOOKS['retrieve_more_field_from_ldap']['example']="plugin_retrieve_more_field_from_ldap_example"; + + // Retrieve others datas from LDAP + //$PLUGIN_HOOKS['retrieve_more_data_from_ldap']['example']="plugin_retrieve_more_data_from_ldap_example"; + + // Reports + $PLUGIN_HOOKS['reports']['example'] = ['report.php' => 'New Report', + 'report.php?other' => 'New Report 2']; + + // Stats + $PLUGIN_HOOKS['stats']['example'] = ['stat.php' => 'New stat', + 'stat.php?other' => 'New stats 2', ]; + + $PLUGIN_HOOKS[Hooks::POST_INIT]['example'] = 'plugin_example_postinit'; + + $PLUGIN_HOOKS['status']['example'] = 'plugin_example_Status'; + + // CSRF compliance : All actions must be done via POST and forms closed by Html::closeForm(); + $PLUGIN_HOOKS[Hooks::CSRF_COMPLIANT]['example'] = true; + + $PLUGIN_HOOKS[Hooks::DISPLAY_CENTRAL]['example'] = 'plugin_example_display_central'; + $PLUGIN_HOOKS[Hooks::DISPLAY_LOGIN]['example'] = 'plugin_example_display_login'; + $PLUGIN_HOOKS[Hooks::INFOCOM]['example'] = 'plugin_example_infocom_hook'; + + // pre_show and post_show for tabs and items, + // see GlpiPlugin\Example\Showtabitem class for implementation explanations + $PLUGIN_HOOKS[Hooks::PRE_SHOW_TAB]['example'] = [Showtabitem::class, 'pre_show_tab']; + $PLUGIN_HOOKS[Hooks::POST_SHOW_TAB]['example'] = [Showtabitem::class, 'post_show_tab']; + $PLUGIN_HOOKS[Hooks::PRE_SHOW_ITEM]['example'] = [Showtabitem::class, 'pre_show_item']; + $PLUGIN_HOOKS[Hooks::POST_SHOW_ITEM]['example'] = [Showtabitem::class, 'post_show_item']; + + $PLUGIN_HOOKS[Hooks::PRE_ITEM_FORM]['example'] = [ItemForm::class, 'preItemForm']; + $PLUGIN_HOOKS[Hooks::POST_ITEM_FORM]['example'] = [ItemForm::class, 'postItemForm']; + + //TODO: remove check when GLPI 11.0.0 is released + if (version_compare(GLPI_VERSION, '11.0.0', 'ge')) { + $PLUGIN_HOOKS[Hooks::PRE_ITIL_INFO_SECTION]['example'] = [ItemForm::class, 'preSection']; + $PLUGIN_HOOKS[Hooks::POST_ITIL_INFO_SECTION]['example'] = [ItemForm::class, 'postSection']; + } + + // Add new actions to timeline + $PLUGIN_HOOKS[Hooks::TIMELINE_ACTIONS]['example'] = [ + ItemForm::class, 'timelineActions', + ]; + + // declare this plugin as an import plugin for Computer itemtype + $PLUGIN_HOOKS['import_item']['example'] = [Computer::class => ['Plugin']]; + + // add additional informations on Computer::showForm + $PLUGIN_HOOKS[Hooks::AUTOINVENTORY_INFORMATION]['example'] = [ + Computer::class => [Computer::class, 'showInfo'], + ]; + + $PLUGIN_HOOKS[Hooks::FILTER_ACTORS]['example'] = 'plugin_example_filter_actors'; + + // add new cards to dashboard grid + $PLUGIN_HOOKS['dashboard_types']['example'] = [Example::class, 'dashboardTypes']; + $PLUGIN_HOOKS['dashboard_cards']['example'] = [Example::class, 'dashboardCards']; + + // Dashboard filter + $PLUGIN_HOOKS[Hooks::DASHBOARD_FILTERS]['example'] = [ + ComputerModelFilter::class, + ]; + + //TODO: remove check when GLPI 11.0.0 is released + if (version_compare(GLPI_VERSION, '11.0.0', 'ge')) { + // Icon in the impact analysis + $PLUGIN_HOOKS[Hooks::SET_ITEM_IMPACT_ICON]['example'] = 'plugin_example_set_impact_icon'; + } } @@ -304,20 +311,21 @@ function plugin_init_example() { * * @return array */ -function plugin_version_example() { - return [ - 'name' => 'Plugin Example', - 'version' => PLUGIN_EXAMPLE_VERSION, - 'author' => 'Example plugin team', - 'license' => 'GPLv2+', - 'homepage' => 'https://github.com/pluginsGLPI/example', - 'requirements' => [ - 'glpi' => [ - 'min' => PLUGIN_EXAMPLE_MIN_GLPI, - 'max' => PLUGIN_EXAMPLE_MAX_GLPI, - ] - ] - ]; +function plugin_version_example() +{ + return [ + 'name' => 'Plugin Example', + 'version' => PLUGIN_EXAMPLE_VERSION, + 'author' => 'Example plugin team', + 'license' => 'GPLv2+', + 'homepage' => 'https://github.com/pluginsGLPI/example', + 'requirements' => [ + 'glpi' => [ + 'min' => PLUGIN_EXAMPLE_MIN_GLPI, + 'max' => PLUGIN_EXAMPLE_MAX_GLPI, + ], + ], + ]; } @@ -327,11 +335,13 @@ function plugin_version_example() { * * @return boolean */ -function plugin_example_check_prerequisites() { - if (false) { - return false; - } - return true; +function plugin_example_check_prerequisites() +{ + if (false) { + return false; + } + + return true; } /** @@ -341,13 +351,15 @@ function plugin_example_check_prerequisites() { * * @return boolean */ -function plugin_example_check_config($verbose = false) { - if (true) { // Your configuration check - return true; - } - - if ($verbose) { - echo __('Installed / not configured', 'example'); - } - return false; +function plugin_example_check_config($verbose = false) +{ + if (true) { // Your configuration check + return true; + } + + if ($verbose) { + echo __('Installed / not configured', 'example'); + } + + return false; } diff --git a/src/Child.php b/src/Child.php index ce2a4ed..b2960c8 100644 --- a/src/Child.php +++ b/src/Child.php @@ -34,6 +34,7 @@ // ---------------------------------------------------------------------- namespace GlpiPlugin\Example; + use CommonDBChild; use Session; @@ -43,64 +44,58 @@ // enhancements. // For CommonDBRelation, the variable are quiet equivalent, but they use _1 and _2 for each side // parent -class Child extends CommonDBChild { - - // A child rely on an item. If $itemtype=='itemtype', then that is a variable item. - static public $itemtype = 'itemtype'; - static public $items_id = 'items_id'; - - - // With 0.84, you have to specify each right (create, view, update and delete), because - // CommonDBChild(s) and CommonDBRelation(s) mainly depend on the rights on the parent item - // All these methods rely on parent:can*. Two attributs are usefull : - // * $checkParentRights: define what to check regarding the parent : - // - CommonDBConnexity::DONT_CHECK_ITEM_RIGHTS don't eaven relly on parents rights - // - CommonDBConnexity::HAVE_VIEW_RIGHT_ON_ITEM view right on the item is enough - // - CommonDBConnexity::HAVE_SAME_RIGHT_ON_ITEM we must have at least update right - // on the item - // * $mustBeAttached: some CommonDBChild can be free, without any parent. - static function canCreate() { - - return (Session::haveRight('internet', UPDATE) - && parent::canCreate()); - } - - - static function canView() { - - return (Session::haveRight('internet', READ) - && parent::canView()); - } - - - static function canUpdate() { - - return (Session::haveRight('internet', UPDATE) - && parent::canUpdate()); - } - - - static function canDelete() { - - return (Session::haveRight('internet', DELETE) - && parent::canDelete()); - } - - - // By default, post_addItem, post_updateItem and post_deleteFromDB are defined. - // They define the history to add to the parents - // This method define the name to set inside the history of the parent. - // All these methods use $log_history_add, $log_history_update and $log_history_delete to - // define the level of log (Log::HISTORY_ADD_DEVICE, Log::HISTORY_UPDATE_DEVICE ...) - function getHistoryName_for_item($case) { - } - - // CommonDBChild also check if we can add or updatethe item regarding the new item - // ($input[static::$itemtype] and $input[static::$items_id]). - // But don't forget to call parent::prepareInputForAdd() - function prepareInputForAdd($input) { - // My preparation on $input - return parent::prepareInputForAdd($input); - } - +class Child extends CommonDBChild +{ + // A child rely on an item. If $itemtype=='itemtype', then that is a variable item. + public static $itemtype = 'itemtype'; + public static $items_id = 'items_id'; + + // With 0.84, you have to specify each right (create, view, update and delete), because + // CommonDBChild(s) and CommonDBRelation(s) mainly depend on the rights on the parent item + // All these methods rely on parent:can*. Two attributs are usefull : + // * $checkParentRights: define what to check regarding the parent : + // - CommonDBConnexity::DONT_CHECK_ITEM_RIGHTS don't eaven relly on parents rights + // - CommonDBConnexity::HAVE_VIEW_RIGHT_ON_ITEM view right on the item is enough + // - CommonDBConnexity::HAVE_SAME_RIGHT_ON_ITEM we must have at least update right + // on the item + // * $mustBeAttached: some CommonDBChild can be free, without any parent. + public static function canCreate() + { + return (Session::haveRight('internet', UPDATE) + && parent::canCreate()); + } + + public static function canView() + { + return (Session::haveRight('internet', READ) + && parent::canView()); + } + + public static function canUpdate() + { + return (Session::haveRight('internet', UPDATE) + && parent::canUpdate()); + } + + public static function canDelete() + { + return (Session::haveRight('internet', DELETE) + && parent::canDelete()); + } + + // By default, post_addItem, post_updateItem and post_deleteFromDB are defined. + // They define the history to add to the parents + // This method define the name to set inside the history of the parent. + // All these methods use $log_history_add, $log_history_update and $log_history_delete to + // define the level of log (Log::HISTORY_ADD_DEVICE, Log::HISTORY_UPDATE_DEVICE ...) + public function getHistoryName_for_item($case) {} + + // CommonDBChild also check if we can add or updatethe item regarding the new item + // ($input[static::$itemtype] and $input[static::$items_id]). + // But don't forget to call parent::prepareInputForAdd() + public function prepareInputForAdd($input) + { + // My preparation on $input + return parent::prepareInputForAdd($input); + } } diff --git a/src/Computer.php b/src/Computer.php index 1834155..31a4cd5 100644 --- a/src/Computer.php +++ b/src/Computer.php @@ -34,50 +34,49 @@ // ---------------------------------------------------------------------- namespace GlpiPlugin\Example; + use CommonDBTM; // Class of the defined type if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + die("Sorry. You can't access directly to this file"); } -class Computer extends CommonDBTM { - - static function showInfo() { - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'.__('More information').'
'; - echo __('Test successful'); - echo '
'; - } - - - static function item_can($item) { - - if (($item->getType() == 'Computer') - && ($item->right == READ) - && ($item->fields['groups_id'] > 0) - && !in_array($item->fields['groups_id'], $_SESSION["glpigroups"])) { - $item->right = 0; // unknown, so denied. - } - } - +class Computer extends CommonDBTM +{ + public static function showInfo() + { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo '
' . __('More information') . '
'; + echo __('Test successful'); + echo '
'; + } - static function add_default_where($in) { + public static function item_can($item) + { + if (($item->getType() == 'Computer') + && ($item->right == READ) + && ($item->fields['groups_id'] > 0) + && !in_array($item->fields['groups_id'], $_SESSION['glpigroups'])) { + $item->right = 0; // unknown, so denied. + } + } - list($itemtype, $condition) = $in; - if ($itemtype == 'Computer') { - $table = getTableForItemType($itemtype); - $condition .= " (".$table.".groups_id NOT IN (".implode(',', $_SESSION["glpigroups"])."))"; - } - return [$itemtype, $condition]; - } + public static function add_default_where($in) + { + list($itemtype, $condition) = $in; + if ($itemtype == 'Computer') { + $table = getTableForItemType($itemtype); + $condition .= ' (' . $table . '.groups_id NOT IN (' . implode(',', $_SESSION['glpigroups']) . '))'; + } + return [$itemtype, $condition]; + } } diff --git a/src/Config.php b/src/Config.php index e22b906..baf00b3 100644 --- a/src/Config.php +++ b/src/Config.php @@ -29,6 +29,7 @@ */ namespace GlpiPlugin\Example; + use CommonDBTM; use CommonGLPI; use Config as GlpiConfig; @@ -37,60 +38,63 @@ use Session; use Toolbox; -class Config extends CommonDBTM { - - static protected $notable = true; - - function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { - - if (!$withtemplate) { - if ($item->getType() == 'Config') { - return __('Example plugin'); - } - } - return ''; - } - - static function configUpdate($input) { - $input['configuration'] = 1 - $input['configuration']; - return $input; - } - - function showFormExample() { - global $CFG_GLPI; - - if (!Session::haveRight("config", UPDATE)) { - return false; - } - - $my_config = GlpiConfig::getConfigurationValues('plugin:Example'); - - echo "
"; - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; - - echo "
" . __('Example setup') . "
" . __('My boolean choice :') . ""; - echo ""; - echo ""; - Dropdown::showYesNo("configuration", $my_config['configuration']); - echo "
"; - echo ""; - echo "
"; - Html::closeForm(); - } - - static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { - - if ($item->getType() == 'Config') { - $config = new self(); - $config->showFormExample(); - } - } - +class Config extends CommonDBTM +{ + protected static $notable = true; + + public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) + { + if (!$withtemplate) { + if ($item->getType() == 'Config') { + return __('Example plugin'); + } + } + + return ''; + } + + public static function configUpdate($input) + { + $input['configuration'] = 1 - $input['configuration']; + + return $input; + } + + public function showFormExample() + { + global $CFG_GLPI; + + if (!Session::haveRight('config', UPDATE)) { + return false; + } + + $my_config = GlpiConfig::getConfigurationValues('plugin:Example'); + + echo ""; + echo "
"; + echo ""; + echo "'; + echo ''; + echo "'; + + echo ""; + echo "'; + + echo '
" . __('Example setup') . '
' . __('My boolean choice :') . '"; + echo ""; + echo ""; + Dropdown::showYesNo('configuration', $my_config['configuration']); + echo '
"; + echo "'; + echo '
'; + Html::closeForm(); + } + + public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) + { + if ($item->getType() == 'Config') { + $config = new self(); + $config->showFormExample(); + } + } } diff --git a/src/DeviceCamera.php b/src/DeviceCamera.php index 64b52d2..83e56a1 100644 --- a/src/DeviceCamera.php +++ b/src/DeviceCamera.php @@ -34,19 +34,20 @@ // ---------------------------------------------------------------------- namespace GlpiPlugin\Example; + use CommonDevice; // Class of the defined type if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + die("Sorry. You can't access directly to this file"); } /// Class DeviceCamera -class DeviceCamera extends CommonDevice { - - static function getTypeName($nb = 0) { - return _n('Camera', 'Cameras', $nb); - } - +class DeviceCamera extends CommonDevice +{ + public static function getTypeName($nb = 0) + { + return _n('Camera', 'Cameras', $nb); + } } diff --git a/src/Document.php b/src/Document.php index a306c0a..267b40a 100644 --- a/src/Document.php +++ b/src/Document.php @@ -55,14 +55,15 @@ */ namespace GlpiPlugin\Example; + use Document as GlpiDocument; if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access this file directly"); + die("Sorry. You can't access this file directly"); } -class Document extends GlpiDocument { - +class Document extends GlpiDocument +{ /** * Return the table used to store this object. Overloads the implementation in CommonDBTM * @@ -70,155 +71,159 @@ class Document extends GlpiDocument { * * @return string **/ - public static function getTable($classname = null) { - if ($classname === null) { - $classname = get_called_class(); - } - if ($classname == get_called_class()) { - return parent::getTable(Document::class); - } - - return parent::getTable($classname); - } - - /** - * Prepare creation of an item - * - * @param array $input - * @return array|false - */ - public function prepareInputForAdd($input) { - $input['_only_if_upload_succeed'] = true; - if (!isset($_FILES['file'])) { - return false; - } - - // Move the uploaded file to GLPi's tmp dir - while (count($_FILES['file']['name']) > 0) { - $source = array_pop($_FILES['file']['name']); - $destination = GLPI_TMP_DIR . '/' . $source; - move_uploaded_file($source, $destination); - $input['_filename'][] = $source; - } - - return parent::prepareInputForAdd($input); - } - - /** - * Prepare update of an item - * - * @param array $input - * @return array|false - */ - public function prepareInputForUpdate($input) { - // Do not allow update of document - return false; - } - - /** - * Process required after loading an object from DB - * In this example, a file is sent as a byte strem then stops execution. - * - * @return void - */ - public function post_getFromDB() { - // Check the user can view this itemtype and can view this item - if ($this->canView() && $this->canViewItem()) { - if (isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT'] == 'application/octet-stream' - || isset($_GET['alt']) && $_GET['alt'] == 'media') { - $this->sendFile(); // and terminate script - } - } - } - - /** - * Send a byte stream to the HTTP client and stops execution - * - * @return void - */ - protected function sendFile() { - $streamSource = GLPI_DOC_DIR . '/' . $this->fields['filepath']; - - // Ensure the file exists - if (!file_exists($streamSource) || !is_file($streamSource)) { - header("HTTP/1.0 404 Not Found"); - exit(0); - } - - // Download range defaults to the full file - // get file metadata - $size = filesize($streamSource); - $begin = 0; - $end = $size - 1; - $mimeType = 'application/octet-stream'; - $time = date('r', filemtime($streamSource)); - - // Open the file - $fileHandle = @fopen($streamSource, 'rb'); - if (!$fileHandle) { - header ("HTTP/1.0 500 Internal Server Error"); - exit(0); - } - - // set range if specified by the client - if (isset($_SERVER['HTTP_RANGE'])) { - if (preg_match('/bytes=\h*(\d+)?-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) { - if (!empty($matches[1])) { - $begin = intval($matches[1]); - } - if (!empty($matches[2])) { - $end = min(intval($matches[2]), $end); + public static function getTable($classname = null) + { + if ($classname === null) { + $classname = get_called_class(); + } + if ($classname == get_called_class()) { + return parent::getTable(Document::class); + } + + return parent::getTable($classname); + } + + /** + * Prepare creation of an item + * + * @param array $input + * @return array|false + */ + public function prepareInputForAdd($input) + { + $input['_only_if_upload_succeed'] = true; + if (!isset($_FILES['file'])) { + return false; + } + + // Move the uploaded file to GLPi's tmp dir + while (count($_FILES['file']['name']) > 0) { + $source = array_pop($_FILES['file']['name']); + $destination = GLPI_TMP_DIR . '/' . $source; + move_uploaded_file($source, $destination); + $input['_filename'][] = $source; + } + + return parent::prepareInputForAdd($input); + } + + /** + * Prepare update of an item + * + * @param array $input + * @return array|false + */ + public function prepareInputForUpdate($input) + { + // Do not allow update of document + return false; + } + + /** + * Process required after loading an object from DB + * In this example, a file is sent as a byte strem then stops execution. + * + * @return void + */ + public function post_getFromDB() + { + // Check the user can view this itemtype and can view this item + if ($this->canView() && $this->canViewItem()) { + if (isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT'] == 'application/octet-stream' + || isset($_GET['alt']) && $_GET['alt'] == 'media') { + $this->sendFile(); // and terminate script } - } - } - - // seek to the begining of the range - $currentPosition = $begin; - if (fseek($fileHandle, $begin, SEEK_SET) < 0) { - header("HTTP/1.0 500 Internal Server Error"); - exit(0); - } - - // send headers to ensure the client is able to detect a corrupted download - // example : less bytes than the expected range - // send meta data - // setup client's cache behavior - header("Expires: Mon, 26 Nov 1962 00:00:00 GMT"); - header('Pragma: private'); /// IE BUG + SSL - header('Cache-control: private, must-revalidate'); /// IE BUG + SSL - header("Content-disposition: attachment; filename=\"" . $this->fields['filename'] . "\""); - header("Content-type: $mimeType"); - header("Last-Modified: $time"); - header('Accept-Ranges: bytes'); - header('Content-Length:' . ($end - $begin + 1)); - header("Content-Range: bytes $begin-$end/$size"); - header("Content-Transfer-Encoding: binary\n"); - header('Connection: close'); - - // Prepare HTTP response - if ($begin > 0 || $end < $size - 1) { - header('HTTP/1.0 206 Partial Content'); - } else { - header('HTTP/1.0 200 OK'); - } - - // Sends bytes until the end of the range or connection closed - while (!feof($fileHandle) && $currentPosition < $end && (connection_status() == 0)) { - // allow a few seconds to send a few KB. - set_time_limit(10); - $content = fread($fileHandle, min(1024 * 16, $end - $currentPosition + 1)); - if ($content === false) { - header("HTTP/1.0 500 Internal Server Error", true); // Replace previously sent headers + } + } + + /** + * Send a byte stream to the HTTP client and stops execution + * + * @return void + */ + protected function sendFile() + { + $streamSource = GLPI_DOC_DIR . '/' . $this->fields['filepath']; + + // Ensure the file exists + if (!file_exists($streamSource) || !is_file($streamSource)) { + header('HTTP/1.0 404 Not Found'); exit(0); - } else { - print $content; - } - flush(); - $currentPosition += 1024 * 16; - } + } + + // Download range defaults to the full file + // get file metadata + $size = filesize($streamSource); + $begin = 0; + $end = $size - 1; + $mimeType = 'application/octet-stream'; + $time = date('r', filemtime($streamSource)); + + // Open the file + $fileHandle = @fopen($streamSource, 'rb'); + if (!$fileHandle) { + header('HTTP/1.0 500 Internal Server Error'); + exit(0); + } + + // set range if specified by the client + if (isset($_SERVER['HTTP_RANGE'])) { + if (preg_match('/bytes=\h*(\d+)?-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) { + if (!empty($matches[1])) { + $begin = intval($matches[1]); + } + if (!empty($matches[2])) { + $end = min(intval($matches[2]), $end); + } + } + } - // End now to prevent any unwanted bytes - exit(0); - } + // seek to the begining of the range + $currentPosition = $begin; + if (fseek($fileHandle, $begin, SEEK_SET) < 0) { + header('HTTP/1.0 500 Internal Server Error'); + exit(0); + } + + // send headers to ensure the client is able to detect a corrupted download + // example : less bytes than the expected range + // send meta data + // setup client's cache behavior + header('Expires: Mon, 26 Nov 1962 00:00:00 GMT'); + header('Pragma: private'); /// IE BUG + SSL + header('Cache-control: private, must-revalidate'); /// IE BUG + SSL + header('Content-disposition: attachment; filename="' . $this->fields['filename'] . '"'); + header("Content-type: $mimeType"); + header("Last-Modified: $time"); + header('Accept-Ranges: bytes'); + header('Content-Length:' . ($end - $begin + 1)); + header("Content-Range: bytes $begin-$end/$size"); + header("Content-Transfer-Encoding: binary\n"); + header('Connection: close'); + + // Prepare HTTP response + if ($begin > 0 || $end < $size - 1) { + header('HTTP/1.0 206 Partial Content'); + } else { + header('HTTP/1.0 200 OK'); + } + + // Sends bytes until the end of the range or connection closed + while (!feof($fileHandle) && $currentPosition < $end && (connection_status() == 0)) { + // allow a few seconds to send a few KB. + set_time_limit(10); + $content = fread($fileHandle, min(1024 * 16, $end - $currentPosition + 1)); + if ($content === false) { + header('HTTP/1.0 500 Internal Server Error', true); // Replace previously sent headers + exit(0); + } else { + print $content; + } + flush(); + $currentPosition += 1024 * 16; + } + // End now to prevent any unwanted bytes + exit(0); + } } diff --git a/src/Dropdown.php b/src/Dropdown.php index 463324d..c3f29ea 100644 --- a/src/Dropdown.php +++ b/src/Dropdown.php @@ -32,18 +32,20 @@ // Original Author of file: // Purpose of file: // ---------------------------------------------------------------------- + namespace GlpiPlugin\Example; + use CommonDropdown; // Class for a Dropdown -class Dropdown extends CommonDropdown { - - - static function getTypeName($nb = 0) { +class Dropdown extends CommonDropdown +{ + public static function getTypeName($nb = 0) + { + if ($nb > 0) { + return __('Plugin Example Dropdowns', 'example'); + } - if ($nb > 0) { - return __('Plugin Example Dropdowns', 'example'); - } - return __('Plugin Example Dropdowns', 'example'); - } + return __('Plugin Example Dropdowns', 'example'); + } } diff --git a/src/Example.php b/src/Example.php index de4482a..2d1e90c 100644 --- a/src/Example.php +++ b/src/Example.php @@ -34,6 +34,7 @@ // ---------------------------------------------------------------------- namespace GlpiPlugin\Example; + use CommonDBTM; use CommonGLPI; use Computer; @@ -43,551 +44,578 @@ use Session; // Class of the defined type -class Example extends CommonDBTM { - - static $tags = '[EXAMPLE_ID]'; - public static $rightname = 'plugin_example'; - - // Should return the localized name of the type - static function getTypeName($nb = 0) { - return 'Example Type'; - } - - static function getMenuName() { - return __('Example plugin'); - } - - static function getAdditionalMenuLinks() { - global $CFG_GLPI; - $links = []; - - $links['config'] = '/plugins/example/index.php'; - $links["".__s("] = '/plugins/example/index.php'; - $links[__s('Test link', 'example')] = '/plugins/example/index.php'; - - return $links; - } - - function defineTabs($options = []) { - - $ong = []; - $this->addDefaultFormTab($ong); - $this->addStandardTab('Link', $ong, $options); - - return $ong; - } - - function showForm($ID, array $options = []) { - global $CFG_GLPI; - - $this->initForm($ID, $options); - $this->showFormHeader($options); - - echo ""; - - echo "" . __('ID') . ""; - echo ""; - echo $ID; - echo ""; - - $this->showFormButtons($options); - - return true; - } - - function rawSearchOptions() { - - $tab = []; - - $tab[] = [ - 'id' => 'common', - 'name' => __('Header Needed') - ]; - - $tab[] = [ - 'id' => '1', - 'table' => 'glpi_plugin_example_examples', - 'field' => 'name', - 'name' => __('Name'), - ]; - - $tab[] = [ - 'id' => '2', - 'table' => 'glpi_plugin_example_dropdowns', - 'field' => 'name', - 'name' => __('Dropdown'), - ]; - - $tab[] = [ - 'id' => '3', - 'table' => 'glpi_plugin_example_examples', - 'field' => 'serial', - 'name' => __('Serial number'), - 'usehaving' => true, - 'searchtype' => 'equals', - ]; - - $tab[] = [ - 'id' => '30', - 'table' => 'glpi_plugin_example_examples', - 'field' => 'id', - 'name' => __('ID'), - 'usehaving' => true, - 'searchtype' => 'equals', - ]; - - return $tab; - } - - - /** - * Give localized information about 1 task - * - * @param $name of the task - * - * @return array of strings - */ - static function cronInfo($name) { - - switch ($name) { - case 'Sample' : - return ['description' => __('Cron description for example', 'example'), - 'parameter' => __('Cron parameter for example', 'example')]; - } - return []; - } - - - /** - * Execute 1 task manage by the plugin - * - * @param $task Object of CronTask class for log / stat - * - * @return interger - * >0 : done - * <0 : to be run again (not finished) - * 0 : nothing to do - */ - static function cronSample($task) { - - $task->log("Example log message from class"); - $r = mt_rand(0, $task->fields['param']); - usleep(1000000+$r*1000); - $task->setVolume($r); - - return 1; - } - - - // Hook done on before add item case (data from form, not altered) - static function pre_item_add_computer(Computer $item) { - if (isset($item->input['name']) && empty($item->input['name'])) { - Session::addMessageAfterRedirect("Pre Add Computer Hook KO (name empty)", true); - return $item->input = false; - } else { - Session::addMessageAfterRedirect("Pre Add Computer Hook OK", true); - } - } - - // Hook done on before add item case (data altered by object prepareInputForAdd) - static function post_prepareadd_computer(Computer $item) { - Session::addMessageAfterRedirect("Post prepareAdd Computer Hook", true); - } - - - // Hook done on add item case - static function item_add_computer(Computer $item) { - - Session::addMessageAfterRedirect("Add Computer Hook, ID=".$item->getID(), true); - return true; - } - - - function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { - - if (!$withtemplate) { - switch ($item->getType()) { - case 'Profile' : - if ($item->getField('central')) { - return __('Example', 'example'); - } - break; - - case 'Phone' : - if ($_SESSION['glpishow_count_on_tabs']) { - return self::createTabEntry(__('Example', 'example'), - countElementsInTable($this->getTable())); - } - return __('Example', 'example'); - - case 'ComputerDisk' : - case 'Supplier' : - return [1 => __("Test Plugin", 'example'), - 2 => __("Test Plugin 2", 'example')]; - - case 'Computer' : - case 'Central' : - case 'Preference': - case 'Notification': - return [1 => __("Test Plugin", 'example')]; - - } - } - return ''; - } - - - static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { +class Example extends CommonDBTM +{ + public static $tags = '[EXAMPLE_ID]'; + public static $rightname = 'plugin_example'; + + // Should return the localized name of the type + public static function getTypeName($nb = 0) + { + return 'Example Type'; + } + + public static function getMenuName() + { + return __('Example plugin'); + } + + public static function getAdditionalMenuLinks() + { + global $CFG_GLPI; + $links = []; + + $links['config'] = '/plugins/example/index.php'; + $links["" . __s("] = '/plugins/example/index.php'; + $links[__s('Test link', 'example')] = '/plugins/example/index.php'; + + return $links; + } + + public function defineTabs($options = []) + { + $ong = []; + $this->addDefaultFormTab($ong); + $this->addStandardTab('Link', $ong, $options); + + return $ong; + } + + public function showForm($ID, array $options = []) + { + global $CFG_GLPI; + + $this->initForm($ID, $options); + $this->showFormHeader($options); + + echo ""; + + echo '' . __('ID') . ''; + echo ''; + echo $ID; + echo ''; + + $this->showFormButtons($options); + + return true; + } + + public function rawSearchOptions() + { + $tab = []; + + $tab[] = [ + 'id' => 'common', + 'name' => __('Header Needed'), + ]; + + $tab[] = [ + 'id' => '1', + 'table' => 'glpi_plugin_example_examples', + 'field' => 'name', + 'name' => __('Name'), + ]; + + $tab[] = [ + 'id' => '2', + 'table' => 'glpi_plugin_example_dropdowns', + 'field' => 'name', + 'name' => __('Dropdown'), + ]; + + $tab[] = [ + 'id' => '3', + 'table' => 'glpi_plugin_example_examples', + 'field' => 'serial', + 'name' => __('Serial number'), + 'usehaving' => true, + 'searchtype' => 'equals', + ]; + + $tab[] = [ + 'id' => '30', + 'table' => 'glpi_plugin_example_examples', + 'field' => 'id', + 'name' => __('ID'), + 'usehaving' => true, + 'searchtype' => 'equals', + ]; + + return $tab; + } + + /** + * Give localized information about 1 task + * + * @param $name of the task + * + * @return array of strings + */ + public static function cronInfo($name) + { + switch ($name) { + case 'Sample': + return ['description' => __('Cron description for example', 'example'), + 'parameter' => __('Cron parameter for example', 'example')]; + } + + return []; + } + + /** + * Execute 1 task manage by the plugin + * + * @param $task Object of CronTask class for log / stat + * + * @return interger + * >0 : done + * <0 : to be run again (not finished) + * 0 : nothing to do + */ + public static function cronSample($task) + { + $task->log('Example log message from class'); + $r = mt_rand(0, $task->fields['param']); + usleep(1000000 + $r * 1000); + $task->setVolume($r); + + return 1; + } + + // Hook done on before add item case (data from form, not altered) + public static function pre_item_add_computer(Computer $item) + { + if (isset($item->input['name']) && empty($item->input['name'])) { + Session::addMessageAfterRedirect('Pre Add Computer Hook KO (name empty)', true); + + return $item->input = false; + } else { + Session::addMessageAfterRedirect('Pre Add Computer Hook OK', true); + } + } + + // Hook done on before add item case (data altered by object prepareInputForAdd) + public static function post_prepareadd_computer(Computer $item) + { + Session::addMessageAfterRedirect('Post prepareAdd Computer Hook', true); + } + + // Hook done on add item case + public static function item_add_computer(Computer $item) + { + Session::addMessageAfterRedirect('Add Computer Hook, ID=' . $item->getID(), true); + + return true; + } + + public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) + { + if (!$withtemplate) { + switch ($item->getType()) { + case 'Profile': + if ($item->getField('central')) { + return __('Example', 'example'); + } + break; + + case 'Phone': + if ($_SESSION['glpishow_count_on_tabs']) { + return self::createTabEntry( + __('Example', 'example'), + countElementsInTable($this->getTable()), + ); + } + + return __('Example', 'example'); + + case 'ComputerDisk': + case 'Supplier': + return [1 => __('Test Plugin', 'example'), + 2 => __('Test Plugin 2', 'example')]; + + case 'Computer': + case 'Central': + case 'Preference': + case 'Notification': + return [1 => __('Test Plugin', 'example')]; + } + } - switch ($item->getType()) { - case 'Phone' : - echo __("Plugin Example on Phone", 'example'); - break; + return ''; + } - case 'Central' : - echo __("Plugin central action", 'example'); - break; + public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) + { + switch ($item->getType()) { + case 'Phone': + echo __('Plugin Example on Phone', 'example'); + break; - case 'Preference' : - // Complete form display - $data = plugin_version_example(); + case 'Central': + echo __('Plugin central action', 'example'); + break; - echo ""; - echo ""; - echo ""; + case 'Preference': + // Complete form display + $data = plugin_version_example(); - echo ""; - echo ""; + echo ""; + echo "
".$data['name']." - ".$data['version']; - echo "
Name of the prefInput to set the pref
"; + echo "'; - echo ""; - echo ""; + echo ""; + echo ''; - echo "
" . $data['name'] . ' - ' . $data['version']; + echo '
Name of the prefInput to set the pref
"; - echo "
"; - break; + echo ""; + echo ''; - case 'Notification' : - echo __("Plugin mailing action", 'example'); - break; + echo ''; + echo ''; + break; - case 'ComputerDisk' : - case 'Supplier' : - if ($tabnum==1) { - echo __('First tab of Plugin example', 'example'); - } else { - echo __('Second tab of Plugin example', 'example'); - } - break; - - default : - //TRANS: %1$s is a class name, %2$d is an item ID - printf(__('Plugin example CLASS=%1$s id=%2$d', 'example'), $item->getType(), $item->getField('id')); - break; - } - return true; - } - - static function getSpecificValueToDisplay($field, $values, array $options = []) { - - if (!is_array($values)) { - $values = [$field => $values]; - } - switch ($field) { - case 'serial' : - return "S/N: ".$values[$field]; - } - return ''; - } - - // Parm contains begin, end and who - // Create data to be displayed in the planning of $parm["who"] or $parm["who_group"] between $parm["begin"] and $parm["end"] - static function populatePlanning($parm) { - - // Add items in the output array - // Items need to have an unique index beginning by the begin date of the item to display - // needed to be correcly displayed - $output = []; - $key = $parm["begin"]."$$$"."plugin_example1"; - $output[$key]["begin"] = date("Y-m-d 17:00:00"); - $output[$key]["end"] = date("Y-m-d 18:00:00"); - $output[$key]["name"] = __("test planning example 1", 'example'); - // Specify the itemtype to be able to use specific display system - $output[$key]["itemtype"] = Example::class; - // Set the ID using the ID of the item in the database to have unique ID - $output[$key][getForeignKeyFieldForItemType(Example::class)] = 1; - return $output; - } - - /** - * Display a Planning Item - * - * @param $val Array of the item to display - * @param $who ID of the user (0 if all) - * @param $type position of the item in the time block (in, through, begin or end) - * @param $complete complete display (more details) - * - * @return Nothing (display function) + case 'Notification': + echo __('Plugin mailing action', 'example'); + break; + + case 'ComputerDisk': + case 'Supplier': + if ($tabnum == 1) { + echo __('First tab of Plugin example', 'example'); + } else { + echo __('Second tab of Plugin example', 'example'); + } + break; + + default: + //TRANS: %1$s is a class name, %2$d is an item ID + printf(__('Plugin example CLASS=%1$s id=%2$d', 'example'), $item->getType(), $item->getField('id')); + break; + } + + return true; + } + + public static function getSpecificValueToDisplay($field, $values, array $options = []) + { + if (!is_array($values)) { + $values = [$field => $values]; + } + switch ($field) { + case 'serial': + return 'S/N: ' . $values[$field]; + } + + return ''; + } + + // Parm contains begin, end and who + // Create data to be displayed in the planning of $parm["who"] or $parm["who_group"] between $parm["begin"] and $parm["end"] + public static function populatePlanning($parm) + { + // Add items in the output array + // Items need to have an unique index beginning by the begin date of the item to display + // needed to be correcly displayed + $output = []; + $key = $parm['begin'] . '$$$' . 'plugin_example1'; + $output[$key]['begin'] = date('Y-m-d 17:00:00'); + $output[$key]['end'] = date('Y-m-d 18:00:00'); + $output[$key]['name'] = __('test planning example 1', 'example'); + // Specify the itemtype to be able to use specific display system + $output[$key]['itemtype'] = Example::class; + // Set the ID using the ID of the item in the database to have unique ID + $output[$key][getForeignKeyFieldForItemType(Example::class)] = 1; + + return $output; + } + + /** + * Display a Planning Item + * + * @param $val Array of the item to display + * @param $who ID of the user (0 if all) + * @param $type position of the item in the time block (in, through, begin or end) + * @param $complete complete display (more details) + * + * @return Nothing (display function) + **/ + public static function displayPlanningItem(array $val, $who, $type = '', $complete = 0) + { + // $parm["type"] say begin end in or from type + // Add items in the items fields of the parm array + switch ($type) { + case 'in': + //TRANS: %1$s is the start time of a planned item, %2$s is the end + printf( + __('From %1$s to %2$s :'), + date('H:i', strtotime($val['begin'])), + date('H:i', strtotime($val['end'])), + ); + break; + + case 'through': + echo Html::resume_text($val['name'], 80); + break; + + case 'begin': + //TRANS: %s is the start time of a planned item + printf(__('Start at %s:'), date('H:i', strtotime($val['begin']))); + break; + + case 'end': + //TRANS: %s is the end time of a planned item + printf(__('End at %s:'), date('H:i', strtotime($val['end']))); + break; + } + echo '
'; + echo Html::resume_text($val['name'], 80); + } + + /** + * Get an history entry message + * + * @param $data Array from glpi_logs table + * + * @since GLPI version 0.84 + * + * @return string **/ - static function displayPlanningItem(array $val, $who, $type = "", $complete = 0) { - - // $parm["type"] say begin end in or from type - // Add items in the items fields of the parm array - switch ($type) { - case "in" : - //TRANS: %1$s is the start time of a planned item, %2$s is the end - printf(__('From %1$s to %2$s :'), - date("H:i", strtotime($val["begin"])), date("H:i", strtotime($val["end"]))); - break; - - case "through" : - echo Html::resume_text($val["name"], 80); - break; - - case "begin" : - //TRANS: %s is the start time of a planned item - printf(__('Start at %s:'), date("H:i", strtotime($val["begin"]))); - break; - - case "end" : - //TRANS: %s is the end time of a planned item - printf(__('End at %s:'), date("H:i", strtotime($val["end"]))); - break; - } - echo "
"; - echo Html::resume_text($val["name"], 80); - } - - /** - * Get an history entry message - * - * @param $data Array from glpi_logs table - * - * @since GLPI version 0.84 - * - * @return string - **/ - static function getHistoryEntry($data) { - - switch ($data['linked_action'] - Log::HISTORY_PLUGIN) { - case 0: - return __('History from plugin example', 'example'); - } - - return ''; - } - - - ////////////////////////////// - ////// SPECIFIC MODIF MASSIVE FUNCTIONS /////// - function getSpecificMassiveActions($checkitem = null) { - - $actions = parent::getSpecificMassiveActions($checkitem); - - $actions['Document_Item'.MassiveAction::CLASS_ACTION_SEPARATOR.'add'] = - _x('button', 'Add a document'); // GLPI core one - $actions[__CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'do_nothing'] = - __('Do Nothing - just for fun', 'example'); // Specific one - - return $actions; - } - - static function showMassiveActionsSubForm(MassiveAction $ma) { - - switch ($ma->getAction()) { - case 'DoIt': - echo " ". - Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']). - " ".__('Write in item history', 'example'); - return true; - case 'do_nothing' : - echo " ".Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']). - " ".__('but do nothing :)', 'example'); - return true; - } - return parent::showMassiveActionsSubForm($ma); - } - - - /** - * @since version 0.85 - * - * @see CommonDBTM::processMassiveActionsForOneItemtype() - **/ - static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item, - array $ids) { - global $DB; - - switch ($ma->getAction()) { - case 'DoIt' : - if ($item->getType() == 'Computer') { - Session::addMessageAfterRedirect(__("Right it is the type I want...", 'example')); - Session::addMessageAfterRedirect(__('Write in item history', 'example')); - $changes = [0, 'old value', 'new value']; - foreach ($ids as $id) { - if ($item->getFromDB($id)) { - Session::addMessageAfterRedirect("- ".$item->getField("name")); - Log::history($id, 'Computer', $changes, Example::class, - Log::HISTORY_PLUGIN); - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); - } else { - // Example of ko count - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); - } - } - } else { - // When nothing is possible ... - $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); - } - return; - - case 'do_nothing' : - If ($item->getType() == Example::class) { - Session::addMessageAfterRedirect(__("Right it is the type I want...", 'example')); - Session::addMessageAfterRedirect(__("But... I say I will do nothing for:", - 'example')); - foreach ($ids as $id) { - if ($item->getFromDB($id)) { - Session::addMessageAfterRedirect("- ".$item->getField("name")); - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); - } else { - // Example for noright / Maybe do it with can function is better - $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); - } - } - } else { - $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); - } - Return; - } - parent::processMassiveActionsForOneItemtype($ma, $item, $ids); - } - - static function generateLinkContents($link, CommonDBTM $item) { - - if (strstr($link, "[EXAMPLE_ID]")) { - $link = str_replace("[EXAMPLE_ID]", $item->getID(), $link); - return [$link]; - } - - return parent::generateLinkContents($link, $item); - } - - - static function dashboardTypes() { - return [ - 'example' => [ - 'label' => __("Plugin Example", 'example'), - 'function' => Example::class . "::cardWidget", - 'image' => "https://via.placeholder.com/100x86?text=example", - ], - 'example_static' => [ - 'label' => __("Plugin Example (static)", 'example'), - 'function' => Example::class . "::cardWidgetWithoutProvider", - 'image' => "https://via.placeholder.com/100x86?text=example+static", - ], - ]; - } - - - static function dashboardCards($cards = []) { - if (is_null($cards)) { - $cards = []; - } - $new_cards = [ - 'plugin_example_card' => [ - 'widgettype' => ["example"], - 'label' => __("Plugin Example card"), - 'provider' => Example::class . "::cardDataProvider", - ], - 'plugin_example_card_without_provider' => [ - 'widgettype' => ["example_static"], - 'label' => __("Plugin Example card without provider"), - ], - 'plugin_example_card_with_core_widget' => [ - 'widgettype' => ["bigNumber"], - 'label' => __("Plugin Example card with core provider"), - 'provider' => Example::class . "::cardBigNumberProvider", - ], - ]; - - return array_merge($cards, $new_cards); - } - - - static function cardWidget(array $params = []) { - $default = [ - 'data' => [], - 'title' => '', - // this property is "pretty" mandatory, - // as it contains the colors selected when adding widget on the grid send - // without it, your card will be transparent - 'color' => '', - ]; - $p = array_merge($default, $params); - - // you need to encapsulate your html in div.card to benefit core style - $html = "
"; - $html.= "

{$p['title']}

"; - $html.= ""; - $html.= "
"; - - return $html; - } - - static function cardDataProvider(array $params = []) { - $default_params = [ - 'label' => null, - 'icon' => "fas fa-smile-wink", - ]; - $params = array_merge($default_params, $params); - - return [ - 'title' => $params['label'], - 'icon' => $params['icon'], - 'data' => [ - 'test1', - 'test2', - 'test3', - ] - ]; - } - - static function cardWidgetWithoutProvider(array $params = []) { - $default = [ - // this property is "pretty" mandatory, - // as it contains the colors selected when adding widget on the grid send - // without it, your card will be transparent - 'color' => '', - ]; - $p = array_merge($default, $params); - - // you need to encapsulate your html in div.card to benefit core style - $html = "
+ public static function getHistoryEntry($data) + { + switch ($data['linked_action'] - Log::HISTORY_PLUGIN) { + case 0: + return __('History from plugin example', 'example'); + } + + return ''; + } + + ////////////////////////////// + ////// SPECIFIC MODIF MASSIVE FUNCTIONS /////// + public function getSpecificMassiveActions($checkitem = null) + { + $actions = parent::getSpecificMassiveActions($checkitem); + + $actions['Document_Item' . MassiveAction::CLASS_ACTION_SEPARATOR . 'add'] = _x('button', 'Add a document'); // GLPI core one + $actions[__CLASS__ . MassiveAction::CLASS_ACTION_SEPARATOR . 'do_nothing'] = __('Do Nothing - just for fun', 'example'); // Specific one + + return $actions; + } + + public static function showMassiveActionsSubForm(MassiveAction $ma) + { + switch ($ma->getAction()) { + case 'DoIt': + echo " " . + Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']) . + ' ' . __('Write in item history', 'example'); + + return true; + case 'do_nothing': + echo ' ' . Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']) . + ' ' . __('but do nothing :)', 'example'); + + return true; + } + + return parent::showMassiveActionsSubForm($ma); + } + + /** + * @since version 0.85 + * + * @see CommonDBTM::processMassiveActionsForOneItemtype() + **/ + public static function processMassiveActionsForOneItemtype( + MassiveAction $ma, + CommonDBTM $item, + array $ids + ) { + global $DB; + + switch ($ma->getAction()) { + case 'DoIt': + if ($item->getType() == 'Computer') { + Session::addMessageAfterRedirect(__('Right it is the type I want...', 'example')); + Session::addMessageAfterRedirect(__('Write in item history', 'example')); + $changes = [0, 'old value', 'new value']; + foreach ($ids as $id) { + if ($item->getFromDB($id)) { + Session::addMessageAfterRedirect('- ' . $item->getField('name')); + Log::history( + $id, + 'Computer', + $changes, + Example::class, + Log::HISTORY_PLUGIN, + ); + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); + } else { + // Example of ko count + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); + } + } + } else { + // When nothing is possible ... + $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); + } + + return; + + case 'do_nothing': + if ($item->getType() == Example::class) { + Session::addMessageAfterRedirect(__('Right it is the type I want...', 'example')); + Session::addMessageAfterRedirect(__( + 'But... I say I will do nothing for:', + 'example', + )); + foreach ($ids as $id) { + if ($item->getFromDB($id)) { + Session::addMessageAfterRedirect('- ' . $item->getField('name')); + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); + } else { + // Example for noright / Maybe do it with can function is better + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); + } + } + } else { + $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO); + } + + return; + } + parent::processMassiveActionsForOneItemtype($ma, $item, $ids); + } + + public static function generateLinkContents($link, CommonDBTM $item) + { + if (strstr($link, '[EXAMPLE_ID]')) { + $link = str_replace('[EXAMPLE_ID]', $item->getID(), $link); + + return [$link]; + } + + return parent::generateLinkContents($link, $item); + } + + public static function dashboardTypes() + { + return [ + 'example' => [ + 'label' => __('Plugin Example', 'example'), + 'function' => Example::class . '::cardWidget', + 'image' => 'https://via.placeholder.com/100x86?text=example', + ], + 'example_static' => [ + 'label' => __('Plugin Example (static)', 'example'), + 'function' => Example::class . '::cardWidgetWithoutProvider', + 'image' => 'https://via.placeholder.com/100x86?text=example+static', + ], + ]; + } + + public static function dashboardCards($cards = []) + { + if (is_null($cards)) { + $cards = []; + } + $new_cards = [ + 'plugin_example_card' => [ + 'widgettype' => ['example'], + 'label' => __('Plugin Example card'), + 'provider' => Example::class . '::cardDataProvider', + ], + 'plugin_example_card_without_provider' => [ + 'widgettype' => ['example_static'], + 'label' => __('Plugin Example card without provider'), + ], + 'plugin_example_card_with_core_widget' => [ + 'widgettype' => ['bigNumber'], + 'label' => __('Plugin Example card with core provider'), + 'provider' => Example::class . '::cardBigNumberProvider', + ], + ]; + + return array_merge($cards, $new_cards); + } + + public static function cardWidget(array $params = []) + { + $default = [ + 'data' => [], + 'title' => '', + // this property is "pretty" mandatory, + // as it contains the colors selected when adding widget on the grid send + // without it, your card will be transparent + 'color' => '', + ]; + $p = array_merge($default, $params); + + // you need to encapsulate your html in div.card to benefit core style + $html = "
"; + $html .= "

{$p['title']}

"; + $html .= ''; + $html .= '
'; + + return $html; + } + + public static function cardDataProvider(array $params = []) + { + $default_params = [ + 'label' => null, + 'icon' => 'fas fa-smile-wink', + ]; + $params = array_merge($default_params, $params); + + return [ + 'title' => $params['label'], + 'icon' => $params['icon'], + 'data' => [ + 'test1', + 'test2', + 'test3', + ], + ]; + } + + public static function cardWidgetWithoutProvider(array $params = []) + { + $default = [ + // this property is "pretty" mandatory, + // as it contains the colors selected when adding widget on the grid send + // without it, your card will be transparent + 'color' => '', + ]; + $p = array_merge($default, $params); + + // you need to encapsulate your html in div.card to benefit core style + $html = "
static html (+optional javascript) as card is not matched with a data provider
"; - return $html; - } - - static function cardBigNumberProvider(array $params = []) { - $default_params = [ - 'label' => null, - 'icon' => null, - ]; - $params = array_merge($default_params, $params); - - return [ - 'number' => rand(), - 'url' => "https://www.linux.org/", - 'label' => "plugin example - some text", - 'icon' => "fab fa-linux", // font awesome icon - ]; - } + return $html; + } + + public static function cardBigNumberProvider(array $params = []) + { + $default_params = [ + 'label' => null, + 'icon' => null, + ]; + $params = array_merge($default_params, $params); + + return [ + 'number' => rand(), + 'url' => 'https://www.linux.org/', + 'label' => 'plugin example - some text', + 'icon' => 'fab fa-linux', // font awesome icon + ]; + } } diff --git a/src/Filters/ComputerModelFilter.php b/src/Filters/ComputerModelFilter.php index e1ea1c1..d97b325 100644 --- a/src/Filters/ComputerModelFilter.php +++ b/src/Filters/ComputerModelFilter.php @@ -38,12 +38,12 @@ class ComputerModelFilter extends AbstractFilter { public static function getName(): string { - return __("Computer model"); + return __('Computer model'); } public static function getId(): string { - return "plugin_example_computer_model"; + return 'plugin_example_computer_model'; } public static function canBeApplied(string $table): bool @@ -57,9 +57,9 @@ public static function getHtml($value): string { return self::displayList( self::getName(), - is_string($value) ? $value : "", + is_string($value) ? $value : '', self::getId(), - ComputerModel::class + ComputerModel::class, ); } @@ -67,10 +67,11 @@ public static function getCriteria(string $table, $value): array { if ((int) $value > 0) { $field = ComputerModel::getForeignKeyField(); + return [ - "WHERE" => [ - "$table.$field" => (int) $value - ] + 'WHERE' => [ + "$table.$field" => (int) $value, + ], ]; } @@ -88,9 +89,9 @@ public static function getSearchCriteria(string $table, $value): array 'field' => self::getSearchOptionID( $table, ComputerModel::getForeignKeyField(), - ComputerModel::getTable() + ComputerModel::getTable(), ), - ] + ], ]; } diff --git a/src/ItemForm.php b/src/ItemForm.php index a6b882f..d1ba3c3 100644 --- a/src/ItemForm.php +++ b/src/ItemForm.php @@ -39,21 +39,21 @@ * Example of *_item_form implementation * @see http://glpi-developer-documentation.rtfd.io/en/master/plugins/hooks.html#items-display-related * */ -class ItemForm { - - - /** - * Display contents at the begining of ITILObject section (right panel). - * - * @param array $params Array with "item" and "options" keys - * - * @return void - */ - static public function preSection($params) { - $item = $params['item']; - $options = $params['options']; - - echo TemplateRenderer::getInstance()->renderFromStringTemplate(<<renderFromStringTemplate(<<

TWIG, []); - - } - - /** - * Display contents at the end of ITILObject section (right panel). - * - * @param array $params Array with "item" and "options" keys - * - * @return void - */ - static public function postSection($params) { - $item = $params['item']; - $options = $params['options']; - - echo TemplateRenderer::getInstance()->renderFromStringTemplate(<<renderFromStringTemplate(<<