diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index dc3f4f9a..6530865b 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -22,7 +22,7 @@ jobs:
name: "Generate CI matrix"
uses: "glpi-project/plugin-ci-workflows/.github/workflows/generate-ci-matrix.yml@v1"
with:
- glpi-version: "11.0.x"
+ glpi-version: "12.0.x"
ci:
name: "GLPI ${{ matrix.glpi-version }} - php:${{ matrix.php-version }} - ${{ matrix.db-image }}"
needs: "generate-ci-matrix"
diff --git a/SECURITY.md b/SECURITY.md
index 0484177c..32d96350 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -19,6 +19,8 @@ Thank you for improving the security of glpi-agent.
| Version | Supported |
| ------- | ------------------ |
-| 1.0.x | :heavy_check_mark: |
+| 1.0.x | :x: |
| 1.2.x | :x: |
| 1.3.x | :heavy_check_mark: |
+| 1.3.x | :heavy_check_mark: |
+| 1.4.x | :heavy_check_mark: |
diff --git a/composer.json b/composer.json
index e9a9a0b1..8cba91a4 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,6 @@
"php-http/message-factory": "^1.1"
},
"require-dev": {
- "glpi-project/tools": "^0.8.1",
"marcocesarato/php-conventional-changelog": "^1.17"
},
"config": {
@@ -35,5 +34,5 @@
"license-headers": "vendor/bin/licence-headers-check --ansi --no-interaction",
"build-schema": "tools/build-db-schema.php carbon | plantuml -p -tpng > docs/db-schema.png"
},
- "version": "1.3.0-dev"
+ "version": "1.4.0-dev"
}
diff --git a/composer.lock b/composer.lock
index 3a534dbe..547f38e4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "a821ef4c2ae32d2c6dce28a1a3b4ceb9",
+ "content-hash": "108f5d181fd03cee818d694c22fa7d8b",
"packages": [
{
"name": "clue/stream-filter",
@@ -637,62 +637,6 @@
}
],
"packages-dev": [
- {
- "name": "glpi-project/tools",
- "version": "0.8.3",
- "source": {
- "type": "git",
- "url": "https://github.com/glpi-project/tools.git",
- "reference": "8ea2a7d4702a858f4b0360ba7d4f1841a5e77026"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/glpi-project/tools/zipball/8ea2a7d4702a858f4b0360ba7d4f1841a5e77026",
- "reference": "8ea2a7d4702a858f4b0360ba7d4f1841a5e77026",
- "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-10-14T10:26:06+00:00"
- },
{
"name": "marcocesarato/php-conventional-changelog",
"version": "1.17.3",
@@ -826,47 +770,47 @@
},
{
"name": "symfony/console",
- "version": "v6.4.44",
+ "version": "v7.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "60e3944c4859c487aa6ea2f0f7754917f70f7524"
+ "reference": "23d6f88a29f6d0eac45bd77d70307adf83ba7ab0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/60e3944c4859c487aa6ea2f0f7754917f70f7524",
- "reference": "60e3944c4859c487aa6ea2f0f7754917f70f7524",
+ "url": "https://api.github.com/repos/symfony/console/zipball/23d6f88a29f6d0eac45bd77d70307adf83ba7ab0",
+ "reference": "23d6f88a29f6d0eac45bd77d70307adf83ba7ab0",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/string": "^5.4|^6.0|^7.0"
+ "symfony/string": "^7.2|^8.0"
},
"conflict": {
- "symfony/dependency-injection": "<5.4",
- "symfony/dotenv": "<5.4",
- "symfony/event-dispatcher": "<5.4",
- "symfony/lock": "<5.4",
- "symfony/process": "<5.4"
+ "symfony/dependency-injection": "<6.4",
+ "symfony/dotenv": "<6.4",
+ "symfony/event-dispatcher": "<6.4",
+ "symfony/lock": "<6.4",
+ "symfony/process": "<6.4"
},
"provide": {
"psr/log-implementation": "1.0|2.0|3.0"
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0|^7.0",
- "symfony/dependency-injection": "^5.4|^6.0|^7.0",
- "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/lock": "^5.4|^6.0|^7.0",
- "symfony/messenger": "^5.4|^6.0|^7.0",
- "symfony/process": "^5.4|^6.0|^7.0",
- "symfony/stopwatch": "^5.4|^6.0|^7.0",
- "symfony/var-dumper": "^5.4|^6.0|^7.0"
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/lock": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -900,7 +844,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.4.44"
+ "source": "https://github.com/symfony/console/tree/v7.4.18"
},
"funding": [
{
@@ -920,7 +864,7 @@
"type": "tidelift"
}
],
- "time": "2026-08-21T07:42:12+00:00"
+ "time": "2026-08-25T14:18:37+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -1330,16 +1274,16 @@
},
{
"name": "symfony/service-contracts",
- "version": "v3.7.1",
+ "version": "v3.7.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0"
+ "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0",
- "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257",
+ "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257",
"shasum": ""
},
"require": {
@@ -1393,7 +1337,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.7.1"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.7.3"
},
"funding": [
{
@@ -1413,7 +1357,7 @@
"type": "tidelift"
}
],
- "time": "2026-06-16T09:55:08+00:00"
+ "time": "2026-07-27T15:39:01+00:00"
},
{
"name": "symfony/string",
@@ -1505,86 +1449,6 @@
}
],
"time": "2026-07-28T07:33:02+00:00"
- },
- {
- "name": "twig/twig",
- "version": "v3.28.0",
- "source": {
- "type": "git",
- "url": "https://github.com/twigphp/Twig.git",
- "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b",
- "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1.0",
- "symfony/deprecation-contracts": "^2.5|^3",
- "symfony/polyfill-ctype": "^1.8",
- "symfony/polyfill-mbstring": "^1.3"
- },
- "require-dev": {
- "php-cs-fixer/shim": "^3.0@stable",
- "phpstan/phpstan": "^2.0@stable",
- "psr/container": "^1.0|^2.0",
- "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/Resources/core.php",
- "src/Resources/debug.php",
- "src/Resources/escaper.php",
- "src/Resources/string_loader.php"
- ],
- "psr-4": {
- "Twig\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
- },
- {
- "name": "Twig Team",
- "role": "Contributors"
- },
- {
- "name": "Armin Ronacher",
- "email": "armin.ronacher@active-4.com",
- "role": "Project Founder"
- }
- ],
- "description": "Twig, the flexible, fast, and secure template language for PHP",
- "homepage": "https://twig.symfony.com",
- "keywords": [
- "templating"
- ],
- "support": {
- "issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.28.0"
- },
- "funding": [
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/twig/twig",
- "type": "tidelift"
- }
- ],
- "time": "2026-07-03T20:44:34+00:00"
}
],
"aliases": [],
diff --git a/install/install/init_datasources.php b/install/install/init_datasources.php
index a195c0fa..b70935e7 100644
--- a/install/install/init_datasources.php
+++ b/install/install/init_datasources.php
@@ -125,7 +125,9 @@
$progress_bar->setProgress($rows_count);
}
$file = null; // close the file
-
+ if (isset($output)) {
+ $output->writeln("");
+ }
Config::setPluginConfigurationValues(['ember_dataset_date' => EMBER_DATASET_DATE]);
}
diff --git a/package-lock.json b/package-lock.json
index be53cdf3..3cb71d8f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "carbon",
- "version": "1.3.0-dev",
+ "version": "1.4.0-dev",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "carbon",
- "version": "1.3.0-dev",
+ "version": "1.4.0-dev",
"hasInstallScript": true,
"license": "GPL-3.0-or-later",
"dependencies": {
diff --git a/package.json b/package.json
index 831cb333..dcf9a0ed 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "carbon",
"description": "Measurement of carbon emissions of GLPI devices",
"license": "GPL-3.0-or-later",
- "version": "1.3.0-dev",
+ "version": "1.4.0-dev",
"engines": {
"node": ">= 18.12.0"
},
diff --git a/setup.php b/setup.php
index f2aedb35..7f8f48c5 100644
--- a/setup.php
+++ b/setup.php
@@ -47,9 +47,9 @@
use Profile as GlpiProfile;
// Version of the plugin (major.minor.bugfix)
-define('PLUGIN_CARBON_VERSION', '1.3.0-dev');
+define('PLUGIN_CARBON_VERSION', '1.4.0-dev');
// Schema version of this version (major.minor.bugfix)
-define('PLUGIN_CARBON_SCHEMA_VERSION', '1.3.0');
+define('PLUGIN_CARBON_SCHEMA_VERSION', '1.4.0');
// Version compatibility check -- from GLPI developer documentation
// > A bug in GLPI prior to 11.0.7 caused plugin routes with method constraints other than GET to never match.
@@ -63,9 +63,9 @@
// Watch it when adding new controllers.
// Minimal GLPI version, inclusive
-define('PLUGIN_CARBON_MIN_GLPI_VERSION', '11.0.0');
+define('PLUGIN_CARBON_MIN_GLPI_VERSION', '12.0.0');
// Maximum GLPI version, exclusive
-define('PLUGIN_CARBON_MAX_GLPI_VERSION', '12.0.0');
+define('PLUGIN_CARBON_MAX_GLPI_VERSION', '13.0.0');
define('PLUGIN_CARBON_DECIMALS', 3);
define('EMBER_DATASET_DATE', '2025-07-30');
@@ -223,8 +223,9 @@ function plugin_carbon_check_prerequisites()
$prerequisitesSuccess = true;
+ // In case GLPI is so old that the modern version checker is not implemented
/** @phpstan-ignore if.alwaysFalse */
- if (version_compare(GLPI_VERSION, PLUGIN_CARBON_MIN_GLPI_VERSION, 'lt')) {
+ if (version_compare(GLPI_VERSION, "10.0.0", 'lt')) {
echo "This plugin requires GLPI >= " . PLUGIN_CARBON_MIN_GLPI_VERSION . " and GLPI < " . PLUGIN_CARBON_MAX_GLPI_VERSION . "
";
$prerequisitesSuccess = false;
}
@@ -239,22 +240,23 @@ function plugin_carbon_check_prerequisites()
$prerequisitesSuccess = false;
}
- if (getenv('CI') === false) {
- // only when not under test
- $version_string = $DB->getVersion();
-
- $server = preg_match('/-MariaDB/', $version_string) ? 'MariaDB' : 'MySQL';
- $version = preg_replace('/^((\d+\.?)+).*$/', '$1', $version_string);
- if ($server === 'MySQL' && version_compare($version, '8.0.0', '<')) {
- echo 'This plugin requires MySQL >= 8.0 or MariaDB >= 10.2
';
- $prerequisitesSuccess = false;
- }
-
- if ($server === 'MariaDB' && version_compare($version, '10.2.0', '<')) {
- echo 'This plugin requires MySQL >= 8.0 or MariaDB >= 10.2
';
- $prerequisitesSuccess = false;
- }
- }
+ // GLPI 12 requires MySQL >= 8.0 or MariaDB >= 10.2, then the check below can be disabled
+ // if (getenv('CI') === false) {
+ // // only when not under test
+ // $version_string = $DB->getVersion();
+
+ // $server = preg_match('/-MariaDB/', $version_string) ? 'MariaDB' : 'MySQL';
+ // $version = preg_replace('/^((\d+\.?)+).*$/', '$1', $version_string);
+ // if ($server === 'MySQL' && version_compare($version, '8.0.0', '<')) {
+ // echo 'This plugin requires MySQL >= 8.0 or MariaDB >= 10.2
';
+ // $prerequisitesSuccess = false;
+ // }
+
+ // if ($server === 'MariaDB' && version_compare($version, '10.2.0', '<')) {
+ // echo 'This plugin requires MySQL >= 8.0 or MariaDB >= 10.2
';
+ // $prerequisitesSuccess = false;
+ // }
+ // }
return $prerequisitesSuccess;
}
diff --git a/src/AbstractChildDropdown.php b/src/AbstractChildDropdown.php
index 64675fb5..54994398 100644
--- a/src/AbstractChildDropdown.php
+++ b/src/AbstractChildDropdown.php
@@ -41,7 +41,7 @@
abstract class AbstractChildDropdown extends CommonDBChild
{
- public static $rightname = 'dropdown';
+ public static string $rightname = 'dropdown';
#[Override]
public static function getIcon(): string
diff --git a/src/AbstractImpact.php b/src/AbstractImpact.php
index 103ddc09..95a9fa71 100644
--- a/src/AbstractImpact.php
+++ b/src/AbstractImpact.php
@@ -44,10 +44,10 @@
abstract class AbstractImpact extends CommonDBChild
{
- public static $itemtype = 'itemtype';
- public static $items_id = 'items_id';
+ public static string $itemtype = 'itemtype';
+ public static string $items_id = 'items_id';
- public static $rightname = 'carbon:report';
+ public static string $rightname = 'carbon:report';
#[Override]
public function canEdit($ID): bool
@@ -255,6 +255,6 @@ public function truncate(): bool
return false;
}
- return $DB->delete(static::getTable(), [1]);
+ return $DB->delete(static::getTable(), ['NOT' => ['id' => null]]);
}
}
diff --git a/src/Application/View/Extension/DataHelpersExtension.php b/src/Application/View/Extension/DataHelpersExtension.php
deleted file mode 100644
index 2ccec211..00000000
--- a/src/Application/View/Extension/DataHelpersExtension.php
+++ /dev/null
@@ -1,303 +0,0 @@
-.
- *
- * -------------------------------------------------------------------------
- */
-
-namespace GlpiPlugin\Carbon\Application\View\Extension;
-
-use Glpi\RichText\RichText;
-use Glpi\Toolbox\Sanitizer;
-use Html;
-use Override;
-use Toolbox;
-use Twig\Extension\AbstractExtension;
-use Twig\TwigFilter;
-
-/**
- * @since 10.0.0
- */
-class DataHelpersExtension extends AbstractExtension
-{
- #[Override]
- public function getFilters(): array
- {
- return [
- new TwigFilter('formatted_datetime', [$this, 'getFormattedDatetime']),
- new TwigFilter('formatted_date', [$this, 'getFormattedDate']),
- new TwigFilter('formatted_duration', [$this, 'getFormattedDuration']),
- new TwigFilter('formatted_integer', [$this, 'getFormattedInteger']),
- new TwigFilter('formatted_number', [$this, 'getFormattedNumber']),
- new TwigFilter('formatted_size', [$this, 'getFormattedSize']),
- new TwigFilter('html_to_text', [$this, 'getTextFromHtml']),
- new TwigFilter('long2ip', 'long2ip'),
- new TwigFilter('picture_url', [$this, 'getPictureUrl']),
- new TwigFilter('relative_datetime', [$this, 'getRelativeDatetime']),
- new TwigFilter('safe_html', [$this, 'getSafeHtml'], ['is_safe' => ['html']]),
- new TwigFilter('verbatim_value', [$this, 'getVerbatimValue']),
- new TwigFilter('shortcut', [$this, 'underlineShortcutLetter'], ['is_safe' => ['html']]),
- new TwigFilter('enhanced_html', [$this, 'getEnhancedHtml'], ['is_safe' => ['html']]),
- new TwigFilter('truncate_left', [$this, 'truncateLeft']),
- ];
- }
-
- /**
- * Return date formatted to user preferred format.
- *
- * @param mixed $datetime
- * @param bool $with_seconds
- *
- * @return string|null
- */
- public function getFormattedDatetime($datetime, bool $with_seconds = false): ?string
- {
- if (!is_string($datetime)) {
- return null;
- }
- return Html::convDateTime($datetime, null, $with_seconds);
- }
-
- /**
- * Return date formatted to user preferred format.
- *
- * @param mixed $date
- *
- * @return string|null
- */
- public function getFormattedDate($date): ?string
- {
- if (!is_string($date)) {
- return null;
- }
- return Html::convDate($date);
- }
-
- /**
- * Return relative representation of given date.
- *
- * @param mixed $datetime
- *
- * @return string|null
- */
- public function getRelativeDatetime($datetime): ?string
- {
- if (!is_string($datetime)) {
- return null;
- }
- return Html::timestampToRelativeStr($datetime);
- }
-
- /**
- * Return human readable duration.
- *
- * @param mixed $duration
- * @param bool $display_seconds (default: true)
- *
- * @return string|null
- */
- public function getFormattedDuration(
- $duration,
- bool $display_seconds = true
- ): ?string {
- if (!is_numeric($duration)) {
- return null;
- }
- return Html::timestampToString($duration, $display_seconds);
- }
-
- /**
- * Return integer formatted to user preferred format.
- *
- * @param mixed $number Number to display
- *
- * @return string
- */
- public function getFormattedInteger($number): string
- {
- return Html::formatNumber($number, false, 0);
- }
-
- /**
- * Return number formatted to user preferred format.
- *
- * @param mixed $number Number to display
- *
- * @return string
- */
- public function getFormattedNumber($number): string
- {
- return Html::formatNumber($number);
- }
-
- /**
- * Return size formatted in a compact way (mo, ko, etc).
- *
- * @param mixed $number
- *
- * @return string
- */
- public function getFormattedSize($number): string
- {
- if (!is_numeric($number)) {
- return '';
- }
- return Toolbox::getSize($number);
- }
-
- /**
- * Return URL for given picture.
- *
- * @param mixed $path
- *
- * @return null|string
- */
- public function getPictureUrl($path): ?string
- {
- if (!is_string($path)) {
- return null;
- }
-
- return Toolbox::getPictureUrl($path, true);
- }
-
- /**
- * Return string having its shortcut letter underlined.
- *
- * @param string $string
- * @param string $shortcut_letter
- *
- * @return string
- */
- public function underlineShortcutLetter(string $string, string $shortcut_letter): string
- {
- if (empty($shortcut_letter)) {
- return $string;
- }
- return Toolbox::shortcut($string, $shortcut_letter);
- }
-
- /**
- * Return plain text from HTML (rich text).
- *
- * @param mixed $string HTML string to be made safe
- * @param bool $keep_presentation Indicates whether the presentation elements have to be replaced by plaintext equivalents
- * @param bool $compact Indicates whether the output should be compact (limited line length, no links URL, ...)
- *
- * @return mixed
- */
- public function getTextFromHtml($string, bool $keep_presentation = true, bool $compact = false)
- {
- if (!is_string($string)) {
- return $string;
- }
-
- return RichText::getTextFromHtml($string, $keep_presentation, $compact);
- }
-
- /**
- * Return safe HTML (rich text).
- * Value will be made safe, whenever it has been sanitize (value fetched from DB),
- * or not (value computed during runtime).
- * Result will not be escaped, to prevent having to use `|raw` filter.
- *
- * @param mixed $string
- *
- * @return mixed
- */
- public function getSafeHtml($string)
- {
- if (!is_string($string)) {
- return $string;
- }
-
- return RichText::getSafeHtml($string);
- }
-
- /**
- * Return enhanced HTML (rich text).
- * Value will be made safe, whenever it has been sanitize (value fetched from DB),
- * or not (value computed during runtime).
- * Result will not be escaped, to prevent having to use `|raw` filter.
- *
- * @param mixed $string
- *
- * @return mixed
- */
- public function getEnhancedHtml($string, array $params = [])
- {
- if (!is_string($string)) {
- return $string;
- }
-
- return RichText::getEnhancedHtml($string, $params);
- }
-
- /**
- * Return verbatim value for an itemtype field.
- * Returned value will be unsanitized if it has been transformed by GLPI sanitizing process (value fetched from DB).
- * Twig autoescaping system will then ensure that value is correctly escaped in rendered HTML.
- *
- * @param mixed $string
- *
- * @return mixed
- *
- * @deprecated 11.0
- */
- public function getVerbatimValue($string)
- {
- Toolbox::deprecated();
-
- if (!is_string($string)) {
- return $string;
- }
-
- return Sanitizer::unsanitize($string);
- }
-
-
- /**
- * return the provided string truncated on the left and prepend a prefix separator if length is reached
- *
- * @param string $string the string to left truncate
- * @param int $length number of char to preserve
- * @param string $separator prefix to prepend to the string
- *
- * @return string truncated string
- */
- public function truncateLeft(string $string = "", int $length = 30, string $separator = "...")
- {
- if (mb_strlen($string) <= $length) {
- return $string;
- }
-
- return $separator . mb_substr($string, -$length);
- }
-}
diff --git a/src/CarbonEmission.php b/src/CarbonEmission.php
index 95619e15..5c717a49 100644
--- a/src/CarbonEmission.php
+++ b/src/CarbonEmission.php
@@ -44,8 +44,8 @@
class CarbonEmission extends CommonDBChild
{
- public static $itemtype = 'itemtype';
- public static $items_id = 'items_id';
+ public static string $itemtype = 'itemtype';
+ public static string $items_id = 'items_id';
#[Override]
public static function getTypeName($nb = 0)
@@ -229,6 +229,6 @@ public function truncate(): bool
return false;
}
- return $DB->delete(static::getTable(), [1]);
+ return $DB->delete(static::getTable(), ['NOT' => ['id' => null]]);
}
}
diff --git a/src/CarbonIntensity.php b/src/CarbonIntensity.php
index 4c9fc7ec..99d3a7b3 100644
--- a/src/CarbonIntensity.php
+++ b/src/CarbonIntensity.php
@@ -59,7 +59,7 @@ class CarbonIntensity extends CommonDropdown
{
private const MIN_HISTORY_LENGTH = '13 months ago';
- public static $rightname = 'carbon:report';
+ public static string $rightname = 'carbon:report';
#[Override]
public static function getTypeName($nb = 0)
diff --git a/src/Command/CollectCarbonIntensityCommand.php b/src/Command/CollectCarbonIntensityCommand.php
index 09941081..90cdfab2 100644
--- a/src/Command/CollectCarbonIntensityCommand.php
+++ b/src/Command/CollectCarbonIntensityCommand.php
@@ -117,7 +117,7 @@ protected function interact(InputInterface $input, OutputInterface $output)
}
#[Override]
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
if (count($this->zones) > 1 && $input->getArgument('zone') === null) {
// Null is not a valid key if there are several zones available for the source
diff --git a/src/Command/CreateFakeCarbonIntensityCommand.php b/src/Command/CreateFakeCarbonIntensityCommand.php
index 516b9d1e..afb5855e 100644
--- a/src/Command/CreateFakeCarbonIntensityCommand.php
+++ b/src/Command/CreateFakeCarbonIntensityCommand.php
@@ -63,7 +63,7 @@ protected function configure()
}
#[Override]
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->output = $output;
diff --git a/src/Command/CreateTestInventoryCommand.php b/src/Command/CreateTestInventoryCommand.php
index 1ea9c7cf..882f4d50 100644
--- a/src/Command/CreateTestInventoryCommand.php
+++ b/src/Command/CreateTestInventoryCommand.php
@@ -141,7 +141,7 @@ protected function configure()
}
#[Override]
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->output = $output;
diff --git a/src/Command/ExportDashboardCommand.php b/src/Command/ExportDashboardCommand.php
index 9c36d94b..988250bb 100644
--- a/src/Command/ExportDashboardCommand.php
+++ b/src/Command/ExportDashboardCommand.php
@@ -60,7 +60,7 @@ protected function configure()
}
#[Override]
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var DBmysql $DB */
global $DB;
diff --git a/src/ComputerModel.php b/src/ComputerModel.php
index f08fb727..85ce4795 100644
--- a/src/ComputerModel.php
+++ b/src/ComputerModel.php
@@ -36,6 +36,6 @@
class ComputerModel extends AbstractModel
{
- public static $itemtype = GlpiComputerModel::class;
- public static $items_id = 'computermodels_id';
+ public static string $itemtype = GlpiComputerModel::class;
+ public static string $items_id = 'computermodels_id';
}
diff --git a/src/ComputerType.php b/src/ComputerType.php
index c20955d7..2ef95b35 100644
--- a/src/ComputerType.php
+++ b/src/ComputerType.php
@@ -41,8 +41,8 @@
class ComputerType extends AbstractChildDropdown
{
- public static $itemtype = GlpiComputerType::class;
- public static $items_id = 'computertypes_id';
+ public static string $itemtype = GlpiComputerType::class;
+ public static string $items_id = 'computertypes_id';
public const CATEGORY_UNDEFINED = 0;
public const CATEGORY_DESKTOP = 1;
diff --git a/src/Config.php b/src/Config.php
index e9b38b9e..03e728d6 100644
--- a/src/Config.php
+++ b/src/Config.php
@@ -123,7 +123,6 @@ public function showForm($ID, $options = [])
$current_config = array_diff_key($current_config, array_flip($secured_config));
$reset_args = json_encode([
- '_glpi_csrf_token' => Session::getNewCSRFToken(),
'reset_all' => '',
]);
$usage_impact_action_url = 'submitGetLink("' . $CFG_GLPI['root_doc'] . '/plugins/carbon/front/usageimpact.form.php", ' . $reset_args . ')';
@@ -148,6 +147,32 @@ public function showForm($ID, $options = [])
return true;
}
+ /**
+ * Set config values : create or update entry
+ *
+ * @param string $context context to get values (default for glpi is core)
+ * @param array $values config names to set
+ *
+ * @return void
+ */
+ public static function setConfigurationValues($context, array $values = [])
+ {
+ GlpiConfig::setConfigurationValues($context, $values);
+ }
+
+ /**
+ * Get config value
+ *
+ * @param $context string context to get values (default for glpi is core)
+ * @param $name string config name
+ *
+ * @return mixed
+ */
+ public static function getConfigurationValue(string $context, string $name)
+ {
+ return GlpiConfig::getConfigurationValue($context, $name);
+ }
+
/**
* Prepare input for configuration update
*
diff --git a/src/DataSource/CarbonIntensity/ElectricityMaps/Client.php b/src/DataSource/CarbonIntensity/ElectricityMaps/Client.php
index 1c9a6c08..16d5ae6e 100644
--- a/src/DataSource/CarbonIntensity/ElectricityMaps/Client.php
+++ b/src/DataSource/CarbonIntensity/ElectricityMaps/Client.php
@@ -37,7 +37,6 @@
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
-use DBmysql;
use GLPIKey;
use GlpiPlugin\Carbon\CarbonIntensity;
use GlpiPlugin\Carbon\DataSource\CarbonIntensity\AbortException;
@@ -412,11 +411,8 @@ protected function formatOutput(array $response, int $step): array
*/
protected function shiftToLocalTimezone(array $response): array
{
- /** @var DBmysql $DB */
- global $DB;
-
$shifted_response = [];
- $local_timezone = new DateTimeZone($DB->guessTimezone());
+ $local_timezone = new DateTimeZone(date_default_timezone_get());
array_walk($response, function ($item, $key) use (&$shifted_response, $local_timezone) {
$shifted_date_object = DateTime::createFromFormat('Y-m-d\TH:i:s.vp', $item['datetime'])
->setTimezone($local_timezone);
diff --git a/src/DataSource/CarbonIntensity/Rte/Client.php b/src/DataSource/CarbonIntensity/Rte/Client.php
index ec7b66c7..8b16ff62 100644
--- a/src/DataSource/CarbonIntensity/Rte/Client.php
+++ b/src/DataSource/CarbonIntensity/Rte/Client.php
@@ -37,7 +37,6 @@
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
-use DBmysql;
use GlpiPlugin\Carbon\DataSource\CarbonIntensity\AbstractClient;
use GlpiPlugin\Carbon\DataSource\RestApiClientInterface;
use GlpiPlugin\Carbon\DataTracking\AbstractTracked;
@@ -387,11 +386,8 @@ protected function formatOutput(array $response, int $step): array
*/
protected function shiftToLocalTimezone(array $response): array
{
- /** @var DBmysql $DB */
- global $DB;
-
$shifted_response = [];
- $local_timezone = new DateTimeZone($DB->guessTimezone());
+ $local_timezone = new DateTimeZone(date_default_timezone_get());
array_walk($response, function ($item, $key) use (&$shifted_response, $local_timezone) {
$shifted_date_object = DateTime::createFromFormat('Y-m-d\TH:i:sP', $item['date_heure'])
->setTimezone($local_timezone);
diff --git a/src/Location.php b/src/Location.php
index 8306426a..f08870de 100644
--- a/src/Location.php
+++ b/src/Location.php
@@ -60,8 +60,8 @@
class Location extends CommonDBChild
{
// From CommonDBRelation
- public static $itemtype = GlpiLocation::class;
- public static $items_id = 'locations_id';
+ public static string $itemtype = GlpiLocation::class;
+ public static string $items_id = 'locations_id';
#[Override]
public static function getIcon()
diff --git a/src/MonitorModel.php b/src/MonitorModel.php
index d929e3d2..f144bb5f 100644
--- a/src/MonitorModel.php
+++ b/src/MonitorModel.php
@@ -36,6 +36,6 @@
class MonitorModel extends AbstractModel
{
- public static $itemtype = GlpiMonitorModel::class;
- public static $items_id = 'monitormodels_id';
+ public static string $itemtype = GlpiMonitorModel::class;
+ public static string $items_id = 'monitormodels_id';
}
diff --git a/src/MonitorType.php b/src/MonitorType.php
index 9d104059..e4e994bb 100644
--- a/src/MonitorType.php
+++ b/src/MonitorType.php
@@ -40,8 +40,8 @@
class MonitorType extends AbstractChildDropdown
{
- public static $itemtype = GlpiMonitorType::class;
- public static $items_id = 'monitortypes_id';
+ public static string $itemtype = GlpiMonitorType::class;
+ public static string $items_id = 'monitortypes_id';
#[Override]
public static function showMassiveActionsSubForm(MassiveAction $ma)
diff --git a/src/NetworkEquipmentModel.php b/src/NetworkEquipmentModel.php
index 70bde975..1ed55dfe 100644
--- a/src/NetworkEquipmentModel.php
+++ b/src/NetworkEquipmentModel.php
@@ -36,6 +36,6 @@
class NetworkEquipmentModel extends AbstractModel
{
- public static $itemtype = GlpiNetworkEquipmentModel::class;
- public static $items_id = 'networkequipmentmodels_id';
+ public static string $itemtype = GlpiNetworkEquipmentModel::class;
+ public static string $items_id = 'networkequipmentmodels_id';
}
diff --git a/src/NetworkEquipmentType.php b/src/NetworkEquipmentType.php
index 64e0cb3e..c49e9d33 100644
--- a/src/NetworkEquipmentType.php
+++ b/src/NetworkEquipmentType.php
@@ -40,8 +40,8 @@
class NetworkEquipmentType extends AbstractChildDropdown
{
- public static $itemtype = GlpiNetworkEquipmentType::class;
- public static $items_id = 'networkequipmenttypes_id';
+ public static string $itemtype = GlpiNetworkEquipmentType::class;
+ public static string $items_id = 'networkequipmenttypes_id';
#[Override]
public static function showMassiveActionsSubForm(MassiveAction $ma)
diff --git a/src/Report.php b/src/Report.php
index c0511dfa..46ccf202 100644
--- a/src/Report.php
+++ b/src/Report.php
@@ -42,8 +42,8 @@
class Report extends CommonDBTM
{
- public static $rightname = 'carbon:report';
- protected static $notable = true;
+ public static string $rightname = 'carbon:report';
+ protected static bool $notable = true;
#[Override]
public static function getTypeName($nb = 0)
diff --git a/src/SearchOptions.php b/src/SearchOptions.php
index 738952e7..774204f4 100644
--- a/src/SearchOptions.php
+++ b/src/SearchOptions.php
@@ -220,18 +220,22 @@ public static function getCoreSearchOptions(string $itemtype): array
$fallback_carbon_intensity_subquery = Location::getCarbonIntensityDataSourceRequest([
Location::getTableField('id') => new QueryExpression('glpi_plugin_carbon_locations_3d6da7fccf9233a3f1a4e41183391a41.id'),
]);
- $fallback_carbon_intensity_subquery = (new QuerySubQuery($fallback_carbon_intensity_subquery))->getQuery();
- $computation = "IF(`glpi_computers_id_963cd5e903dddc7ab00a3b70933369df`.`is_deleted` = 0
- AND `glpi_computers_id_963cd5e903dddc7ab00a3b70933369df`.`is_template` = 0
- AND `glpi_plugin_carbon_locations_3d6da7fccf9233a3f1a4e41183391a41`.`plugin_carbon_sources_zones_id` > 0
- AND `glpi_plugin_carbon_computerusageprofiles_09f8403aa14af64cd70f350288a0331b`.`id` > 0"
- // Do not check if an asset is ignored
- // . "AND COALESCE(`glpi_plugin_carbon_computertypes_a643ab3ffd70abf99533ed214da87d60`.`is_ignore`, 0) = 0"
- . " AND (
- `glpi_plugin_carbon_computertypes_a643ab3ffd70abf99533ed214da87d60`.`power_consumption` > 0
- OR `glpi_computermodels`.`power_consumption` > 0
- )
- AND ($fallback_carbon_intensity_subquery) > 0, 1, 0)";
+ $fallback_carbon_intensity_subquery = (new QuerySubQuery($fallback_carbon_intensity_subquery));
+ $computation = new QueryExpression(
+ "IF(`glpi_computers_id_963cd5e903dddc7ab00a3b70933369df`.`is_deleted` = 0
+ AND `glpi_computers_id_963cd5e903dddc7ab00a3b70933369df`.`is_template` = 0
+ AND `glpi_plugin_carbon_locations_3d6da7fccf9233a3f1a4e41183391a41`.`plugin_carbon_sources_zones_id` > 0
+ AND `glpi_plugin_carbon_computerusageprofiles_09f8403aa14af64cd70f350288a0331b`.`id` > 0"
+ // Do not check if an asset is ignored
+ // . "AND COALESCE(`glpi_plugin_carbon_computertypes_a643ab3ffd70abf99533ed214da87d60`.`is_ignore`, 0) = 0"
+ . " AND (
+ `glpi_plugin_carbon_computertypes_a643ab3ffd70abf99533ed214da87d60`.`power_consumption` > 0
+ OR `glpi_computermodels`.`power_consumption` > 0
+ )
+ AND ($fallback_carbon_intensity_subquery) > 0, 1, 0)",
+ null,
+ $fallback_carbon_intensity_subquery->getParams()
+ );
$sopt[] = [
'id' => SearchOptions::IS_HISTORIZABLE,
'table' => getTableForItemType($itemtype),
diff --git a/src/Source_Zone.php b/src/Source_Zone.php
index c485486f..61fc3bb9 100644
--- a/src/Source_Zone.php
+++ b/src/Source_Zone.php
@@ -46,13 +46,13 @@
class Source_Zone extends CommonDBRelation
{
- public static $itemtype_1 = Source::class; // Type ref or field name (must start with itemtype)
- public static $items_id_1 = 'plugin_carbon_sources_id'; // Field name
- public static $checkItem_1_Rights = self::HAVE_SAME_RIGHT_ON_ITEM;
+ public static ?string $itemtype_1 = Source::class; // Type ref or field name (must start with itemtype)
+ public static ?string $items_id_1 = 'plugin_carbon_sources_id'; // Field name
+ public static int $checkItem_1_Rights = self::HAVE_SAME_RIGHT_ON_ITEM;
- public static $itemtype_2 = Zone::class; // Type ref or field name (must start with itemtype)
- public static $items_id_2 = 'plugin_carbon_zones_id'; // Field name
- public static $checkItem_2_Rights = self::HAVE_SAME_RIGHT_ON_ITEM;
+ public static ?string $itemtype_2 = Zone::class; // Type ref or field name (must start with itemtype)
+ public static ?string $items_id_2 = 'plugin_carbon_zones_id'; // Field name
+ public static int $checkItem_2_Rights = self::HAVE_SAME_RIGHT_ON_ITEM;
#[Override]
public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0)
diff --git a/src/UsageInfo.php b/src/UsageInfo.php
index 06274f96..f0736434 100644
--- a/src/UsageInfo.php
+++ b/src/UsageInfo.php
@@ -53,10 +53,10 @@
*/
class UsageInfo extends CommonDBChild
{
- public static $itemtype = 'itemtype';
- public static $items_id = 'items_id';
+ public static string $itemtype = 'itemtype';
+ public static string $items_id = 'items_id';
- public static $rightname = 'carbon:report';
+ public static string $rightname = 'carbon:report';
#[Override]
public static function getTypeName($nb = 0)
diff --git a/templates/config.html.twig b/templates/config.html.twig
index 3f688a71..d199f31d 100644
--- a/templates/config.html.twig
+++ b/templates/config.html.twig
@@ -35,7 +35,6 @@