From 597612271218157e64f9b30bbd6d5caabad11168 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Fri, 13 Dec 2024 09:01:05 -0500 Subject: [PATCH] Remove Laminas JSON library (#18501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove laminas json library * fix changing wrong axis label for bar graph * fix line markers * Update src/Glpi/Dashboard/Widget.php Co-authored-by: Cédric Anne * missed if statement --------- Co-authored-by: Cédric Anne --- composer.json | 1 - composer.lock | 106 ++++----------- src/Config.php | 3 - src/Glpi/Dashboard/Widget.php | 247 ++++++++++++++++------------------ src/Stat.php | 79 ++++++----- 5 files changed, 181 insertions(+), 255 deletions(-) diff --git a/composer.json b/composer.json index 86e96d0ee07..627667bfc5c 100644 --- a/composer.json +++ b/composer.json @@ -41,7 +41,6 @@ "guzzlehttp/psr7": "^2.6", "html2text/html2text": "^4.3", "laminas/laminas-i18n": "^2.29", - "laminas/laminas-json": "^3.7", "laminas/laminas-mail": "^2.25", "laminas/laminas-mime": "^2.12", "league/commonmark": "^2.5", diff --git a/composer.lock b/composer.lock index abc1d48f967..66d2e668191 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": "9f2d91a2e8eadd35f60401ccd22b8ee4", + "content-hash": "0324dd94f3c5b3974b046fe77e6e95fa", "packages": [ { "name": "apereo/phpcas", @@ -1349,67 +1349,6 @@ ], "time": "2024-10-11T09:44:53+00:00" }, - { - "name": "laminas/laminas-json", - "version": "3.7.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-json.git", - "reference": "1931b26ac677f418f39cd0af6d0740e8f4a67d18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-json/zipball/1931b26ac677f418f39cd0af6d0740e8f4a67d18", - "reference": "1931b26ac677f418f39cd0af6d0740e8f4a67d18", - "shasum": "" - }, - "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" - }, - "conflict": { - "zendframework/zend-json": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "laminas/laminas-stdlib": "^2.7.7 || ^3.19", - "phpunit/phpunit": "^9.5.25" - }, - "suggest": { - "laminas/laminas-json-server": "For implementing JSON-RPC servers", - "laminas/laminas-xml2json": "For converting XML documents to JSON" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Json\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", - "homepage": "https://laminas.dev", - "keywords": [ - "json", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-json/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-json/issues", - "rss": "https://github.com/laminas/laminas-json/releases.atom", - "source": "https://github.com/laminas/laminas-json" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2024-10-25T09:02:25+00:00" - }, { "name": "laminas/laminas-loader", "version": "2.10.0", @@ -1464,6 +1403,7 @@ "type": "community_bridge" } ], + "abandoned": true, "time": "2023-10-18T09:58:51+00:00" }, { @@ -1539,6 +1479,7 @@ "type": "community_bridge" } ], + "abandoned": "symfony/mailer", "time": "2023-11-02T10:32:34+00:00" }, { @@ -1600,6 +1541,7 @@ "type": "community_bridge" } ], + "abandoned": "symfony/mime", "time": "2023-11-02T16:47:19+00:00" }, { @@ -5273,8 +5215,8 @@ "type": "library", "extra": { "bamarni-bin": { - "forward-command": false, - "bin-links": false + "bin-links": false, + "forward-command": false } }, "autoload": { @@ -7196,8 +7138,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7355,8 +7297,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7429,8 +7371,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -8803,19 +8745,19 @@ "type": "library", "extra": { "phar-builder": { - "compression": "BZip2", "name": "cam.phar", - "output-dir": "./", - "entry-point": "bin/cam", + "events": { + "command.package.end": "chmod +x cam.phar && rm bin/version.txt", + "command.package.start": "git describe --tags > bin/version.txt" + }, "include": [ "bin", "src", "vendor" ], - "events": { - "command.package.start": "git describe --tags > bin/version.txt", - "command.package.end": "chmod +x cam.phar && rm bin/version.txt" - } + "output-dir": "./", + "compression": "BZip2", + "entry-point": "bin/cam" } }, "autoload": { @@ -11281,12 +11223,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -11764,5 +11706,5 @@ "platform-overrides": { "php": "8.2.99" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/src/Config.php b/src/Config.php index b3f3bb12b10..b0ad9844494 100644 --- a/src/Config.php +++ b/src/Config.php @@ -908,9 +908,6 @@ public static function getLibraries($all = false) [ 'name' => 'laminas/laminas-i18n', 'check' => 'Laminas\\I18n\\Module' ], - [ 'name' => 'laminas/laminas-json', - 'check' => 'Laminas\Json\Json' - ], [ 'name' => 'monolog/monolog', 'check' => 'Monolog\\Logger' ], diff --git a/src/Glpi/Dashboard/Widget.php b/src/Glpi/Dashboard/Widget.php index 4306e6c4707..f9b248b7820 100644 --- a/src/Glpi/Dashboard/Widget.php +++ b/src/Glpi/Dashboard/Widget.php @@ -35,18 +35,12 @@ namespace Glpi\Dashboard; +use Glpi\Application\View\TemplateRenderer; use Glpi\Debug\Profiler; use Glpi\Plugin\Hooks; use Glpi\RichText\RichText; use Glpi\Toolbox\MarkdownRenderer; -use Html; -use Laminas\Json\Expr as Json_Expr; -use Laminas\Json\Json; use Mexitek\PHPColors\Color; -use League\CommonMark\Environment\Environment; -use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; -use League\CommonMark\MarkdownConverter; -use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; use Plugin; use Symfony\Component\DomCrawler\Crawler; use Search; @@ -744,39 +738,34 @@ public static function pie(array $params = []): string ]; } - $options_json = Json::encode( - $options, - false, - ['enableJsonExprFinder' => true] - ); - - $js = << 0) { - window.location.href = data_url; - } - }); + $twig_params = [ + 'chart_id' => $chart_id, + 'options' => $options, + ]; + // language=Twig + $js = TemplateRenderer::getInstance()->renderFromStringTemplate(<< + const target = GLPI.Dashboard.getActiveDashboard() ? + GLPI.Dashboard.getActiveDashboard().element.find('#{{ chart_id }} .chart') + : $('#{{ chart_id }} .chart'); + const myChart = echarts.init(target[0]); + myChart.setOption({{ options|json_encode|raw }}); + myChart + .on('click', function (params) { + const data_url = _.get(params, 'data.url', ''); + if (data_url.length > 0) { + window.location.href = data_url; + } + }); - target - .on('mouseover', function (params) { + target.on('mouseover', () => { myChart.setOption({'toolbox': {'show': true}}); - }) - .on('mouseout', function (params) { + }).on('mouseout', () => { myChart.setOption({'toolbox': {'show': false}}); }); - }); -JAVASCRIPT; - $js = \Html::scriptBlock($js); + +TWIG, $twig_params); + return $html . $js; } @@ -1048,7 +1037,6 @@ private static function getBarsGraph( $nb_colors )['colors']; } - $palette_json = json_encode($palette); $echarts_series = []; $serie_i = 0; @@ -1061,15 +1049,6 @@ private static function getBarsGraph( 'legendHoverLink' => true, ]; - if ($p['distributed']) { - $serie['itemStyle']['color'] = new Json_Expr(<< true, 'overflow' => 'truncate', - 'formatter' => new Json_Expr(<< $p['stacked'] ? '#000' : 'inherit', 'position' => $p['horizontal'] ? 'right' @@ -1190,20 +1163,6 @@ function(param) { if ($p['horizontal']) { $options['xAxis'] = array_merge($options['xAxis'], [ 'type' => 'value', - 'axisLabel' => [ - 'formatter' => new Json_Expr(<< 'category', @@ -1223,40 +1182,67 @@ function (value) { ]; } - $options_json = Json::encode( - $options, - false, - ['enableJsonExprFinder' => true] - ); - - $js = << 0) { - window.location.href = data_url; + $twig_params = [ + 'chart_id' => $chart_id, + 'options' => $options, + 'palette' => $palette, + 'distributed' => $p['distributed'], + 'horizontal' => $p['horizontal'], + ]; + // language=Twig + $js = TemplateRenderer::getInstance()->renderFromStringTemplate(<< + const target = GLPI.Dashboard.getActiveDashboard() ? + GLPI.Dashboard.getActiveDashboard().element.find('#{{ chart_id }} .chart') + : $('#{{ chart_id }} .chart'); + const chart_options = {{ options|json_encode|raw }}; + const palette = {{ palette|json_encode|raw }}; + $.each(chart_options.series, function (index, serie) { + if ({{ distributed ? 'true' : 'false' }}) { + serie['itemStyle'] = { + ...serie['itemStyle'], + 'color': (param) => palette[param.dataIndex] + } } + serie['label'] = { + ...serie['label'], + 'formatter': (param) => param.data.value == 0 ? '' : param.data.value + }; }); + if ({{ horizontal ? 'true' : 'false' }}) { + chart_options['xAxis'] = { + ...chart_options['xAxis'], + 'axisLabel': { + 'formatter': (value) => { + if (value < 1e3) { + return value; + } else if (value < 1e6) { + return value / 1e3 + "K"; + } else { + return value / 1e6 + "M"; + } + } + } + }; + } + + const myChart = echarts.init(target[0]); + myChart.setOption(chart_options); + myChart + .on('click', function (params) { + const data_url = _.get(params, 'data.url', ''); + if (data_url.length > 0) { + window.location.href = data_url; + } + }); - target - .on('mouseover', function (params) { + target.on('mouseover', () => { myChart.setOption({'toolbox': {'show': true}}); - }) - .on('mouseout', function (params) { + }).on('mouseout', () => { myChart.setOption({'toolbox': {'show': false}}); }); - }); -JAVASCRIPT; - $js = \Html::scriptBlock($js); + +TWIG, $twig_params); return $html . $js; } @@ -1443,12 +1429,6 @@ private static function getLinesGraph( } if ($p['show_points']) { - $echart_serie['symbol'] = new Json_Expr(<< 0 ? 'circle': 'none'; - } -JAVASCRIPT - ); $echart_serie['symbolSize'] = 8; } @@ -1457,12 +1437,6 @@ function(value) { 'show' => true, 'distance' => 1, 'color' => 'inherit', - 'formatter' => new Json_Expr(<< true] - ); - - $js = << 0) { - window.location.href = data_url; + $twig_params = [ + 'chart_id' => $chart_id, + 'options' => $options, + 'show_points' => $p['show_points'], + 'point_labels' => $p['point_labels'], + ]; + // language=Twig + $js = TemplateRenderer::getInstance()->renderFromStringTemplate(<< + const target = GLPI.Dashboard.getActiveDashboard() ? + GLPI.Dashboard.getActiveDashboard().element.find('#{{ chart_id }} .chart') + : $('#{{ chart_id }} .chart'); + const chart_options = {{ options|json_encode|raw }}; + + $.each(chart_options.series, function (index, serie) { + if ({{ show_points ? 'true' : 'false' }}) { + serie['symbol'] = (value) => value > 0 ? 'circle': 'none'; + } + if ({{ point_labels ? 'true' : 'false' }}) { + serie['label']['formatter'] = (param) => param.data.value == 0 ? '': param.data.value; } }); - target - .on('mouseover', function (params) { + const myChart = echarts.init(target[0]); + myChart.setOption(chart_options); + myChart + .on('click', function (params) { + const data_url = _.get(params, 'data.url', ''); + if (data_url.length > 0) { + window.location.href = data_url; + } + }); + + target.on('mouseover', () => { myChart.setOption({'toolbox': {'show': true}}); - }) - .on('mouseout', function (params) { + }).on('mouseout', () => { myChart.setOption({'toolbox': {'show': false}}); }); - }); -JAVASCRIPT; - $js = Html::scriptBlock($js); + +TWIG, $twig_params); return $html . $js; } diff --git a/src/Stat.php b/src/Stat.php index c21204e7b02..3fdc3fa48d7 100644 --- a/src/Stat.php +++ b/src/Stat.php @@ -41,8 +41,6 @@ use Glpi\Search\SearchEngine; use Glpi\Stat\StatData; use Glpi\Application\View\TemplateRenderer; -use Laminas\Json\Expr as Json_Expr; -use Laminas\Json\Json; /** * Stat class @@ -1998,12 +1996,6 @@ public function displayLineGraph( 'lineStyle' => [ 'width' => 4 ], - 'symbol' => new Json_Expr(<< 0 ? 'circle': 'none'; - } -JAVASCRIPT - ), 'symbolSize' => 8, 'legendHoverLink' => true, ]; @@ -2013,12 +2005,6 @@ function(value) { $chart_options['toolbox']['feature']['myCsvExport'] = [ 'icon' => 'path://M14,3v4a1,1,0,0,0,1,1h4 M17,21h-10a2,2,0,0,1,-2,-2v-14a2,2,0,0,1,2,-2h7l5,5v11a2,2,0,0,1,-2,2z M12,17v-6 M9.5,14.5l2.5,2.5l2.5,-2.5', 'title' => __('Export to CSV'), - 'onclick' => new Json_Expr(<< HTML; - $chart_options_json = Json::encode($chart_options, false, ['enableJsonExprFinder' => true]); - $js = << $slug, + 'chart_options' => $chart_options, + 'csv_link' => $csv_link + ]; + // language=Twig + $js = TemplateRenderer::getInstance()->renderFromStringTemplate(<< + function exportToCSV() { + location.href = '{{ csv_link|e('js') }}'; + } + const chart_options = {{ chart_options|json_encode|raw }}; + const myChart = echarts.init(document.getElementById('{{ slug }}')); + + $.each(chart_options.series, function (index, serie) { + serie.symbol = (value) => value > 0 ? 'circle': 'none'; + }); + if (chart_options['toolbox']['feature']['myCsvExport'] !== undefined) { + chart_options['toolbox']['feature']['myCsvExport']['onclick'] = exportToCSV; + } + myChart.setOption(chart_options); + +TWIG, $twig_params); $out = $html . $js; @@ -2136,12 +2137,6 @@ public function displayPieGraph( 'myCsvExport' => [ 'icon' => 'path://M14,3v4a1,1,0,0,0,1,1h4 M17,21h-10a2,2,0,0,1,-2,-2v-14a2,2,0,0,1,2,-2h7l5,5v11a2,2,0,0,1,-2,2z M12,17v-6 M9.5,14.5l2.5,2.5l2.5,-2.5', 'title' => __('Export to CSV'), - 'onclick' => new Json_Expr(<< [ 'icon' => 'path://M15,8L15.01,8 M7,4h10s3,0,3,3v10s0,3,-3,3h-10s-3,0,-3,-3v-10s0,-3,3,-3 M4,15l4,-4a3,5,0,0,1,3,0l5,5 M14,14l1,-1a3,5,0,0,1,3,0l2,2', @@ -2195,14 +2190,26 @@ function () { HTML; - $chart_options_json = Json::encode($chart_options, false, ['enableJsonExprFinder' => true]); - $js = << $slug, + 'chart_options' => $chart_options, + 'csv_link' => $csv_link + ]; + // language=Twig + $js = TemplateRenderer::getInstance()->renderFromStringTemplate(<< + function exportToCSV() { + location.href = '{{ csv_link|e('js') }}'; + } + const chart_options = {{ chart_options|json_encode|raw }}; + const myChart = echarts.init(document.getElementById('{{ slug }}')); + + if (chart_options['toolbox']['feature']['myCsvExport'] !== undefined) { + chart_options['toolbox']['feature']['myCsvExport']['onclick'] = exportToCSV; + } + myChart.setOption(chart_options); + +TWIG, $twig_params); $out = $html . $js;