first commit

This commit is contained in:
2025-08-07 13:15:31 +01:00
commit d903893b4c
21854 changed files with 4461308 additions and 0 deletions

551
inc/report.class.php Normal file
View File

@ -0,0 +1,551 @@
<?php
/**
* ---------------------------------------------------------------------
* GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2015-2020 Teclib' and contributors.
*
* http://glpi-project.org
*
* based on GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* GLPI is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}
/**
* Report class
*
* @ since version 0.84
**/
class Report extends CommonGLPI{
static protected $notable = false;
static $rightname = 'reports';
static function getTypeName($nb = 0) {
return _n('Report', 'Reports', $nb);
}
/**
* @see CommonGLPI::getMenuShorcut()
*
* @since 0.85
**/
static function getMenuShorcut() {
return 'e';
}
/**
* Show report title
**/
static function title() {
global $PLUGIN_HOOKS, $CFG_GLPI;
// Report generation
// Default Report included
$report_list = [];
$report_list["default"]["name"] = __('Default report');
$report_list["default"]["file"] = "report.default.php";
if (Contract::canView()) {
// Rapport ajoute par GLPI V0.2
$report_list["Contrats"]["name"] = __('By contract');
$report_list["Contrats"]["file"] = "report.contract.php";
}
if (Infocom::canView()) {
$report_list["Par_annee"]["name"] = __('By year');
$report_list["Par_annee"]["file"] = "report.year.php";
$report_list["Infocoms"]["name"] = __('Hardware financial and administrative information');
$report_list["Infocoms"]["file"] = "report.infocom.php";
$report_list["Infocoms2"]["name"] = __('Other financial and administrative information (licenses, cartridges, consumables)');
$report_list["Infocoms2"]["file"] = "report.infocom.conso.php";
}
if (Session::haveRight("networking", READ)) {
$report_list["Rapport prises reseau"]["name"] = __('Network report');
$report_list["Rapport prises reseau"]["file"] = "report.networking.php";
}
if (Session::haveRight("reservation", READ)) {
$report_list["reservation"]["name"] = __('Loan');
$report_list["reservation"]["file"] = "report.reservation.php";
}
if (Computer::canView()
|| Monitor::canView()
|| Session::haveRight("networking", READ)
|| Peripheral::canView()
|| Printer::canView()
|| Phone::canView()) {
$report_list["state"]["name"] = __('Status');
$report_list["state"]["file"] = "report.state.php";
}
//Affichage du tableau de presentation des stats
echo "<table class='tab_cadre_fixe'>";
echo "<tr><th colspan='2'>".__('Select the report you want to generate')."</th></tr>";
echo "<tr class='tab_bg_1'><td class='center'>";
$selected = -1;
$values = [$CFG_GLPI["root_doc"].'/front/report.php' => Dropdown::EMPTY_VALUE];
foreach ($report_list as $val => $data) {
$name = $data['name'];
$file = $data['file'];
$key = $CFG_GLPI["root_doc"]."/front/".$file;
$values[$key] = $name;
if (stripos($_SERVER['REQUEST_URI'], $key) !== false) {
$selected = $key;
}
}
$names = [];
$optgroup = [];
if (isset($PLUGIN_HOOKS["reports"]) && is_array($PLUGIN_HOOKS["reports"])) {
foreach ($PLUGIN_HOOKS["reports"] as $plug => $pages) {
if (!Plugin::isPluginActive($plug)) {
continue;
}
if (is_array($pages) && count($pages)) {
foreach ($pages as $page => $name) {
$names[$plug.'/'.$page] = ["name" => $name,
"plug" => $plug];
$optgroup[$plug] = Plugin::getInfo($plug, 'name');
}
}
}
asort($names);
}
foreach ($optgroup as $opt => $title) {
$group = $title;
foreach ($names as $key => $val) {
if ($opt == $val["plug"]) {
$file = $CFG_GLPI["root_doc"]."/plugins/".$key;
$values[$group][$file] = $val["name"];
if (stripos($_SERVER['REQUEST_URI'], $file) !== false) {
$selected = $file;
}
}
}
}
Dropdown::showFromArray('statmenu', $values,
['on_change' => "window.location.href=this.options[this.selectedIndex].value",
'value' => $selected]);
echo "</td>";
echo "</tr>";
echo "</table>";
}
/**
* Show Default Report
*
* @since 0.84
**/
static function showDefaultReport() {
global $DB;
// Title
echo "<span class='big b'>GLPI ".Report::getTypeName(Session::getPluralNumber())."</span><br><br>";
// 1. Get counts of itemtype
$items = ['Computer', 'Monitor', 'NetworkEquipment', 'Peripheral', 'Phone',
'Printer', 'Software'];
$linkitems = ['Monitor', 'Peripheral', 'Phone', 'Printer'];
echo "<table class='tab_cadrehov'>";
foreach ($items as $itemtype) {
$table_item = getTableForItemType($itemtype);
$criteria = [
'COUNT' => 'cpt',
'FROM' => $table_item,
'WHERE' => [
"$table_item.is_deleted" => 0,
"$table_item.is_template" => 0
] + getEntitiesRestrictCriteria($table_item)
];
if (in_array($itemtype, $linkitems)) {
$criteria['LEFT JOIN'] = [
'glpi_computers_items' => [
'ON' => [
'glpi_computers_items' => 'items_id',
$table_item => 'id', [
'AND' => [
'glpi_computers_items.itemtype' => $itemtype
]
]
]
]
];
}
$result = $DB->request($criteria)->next();
$number = (int)$result['cpt'];
echo "<tr class='tab_bg_2'><td>".$itemtype::getTypeName(Session::getPluralNumber())."</td>";
echo "<td class='numeric'>$number</td></tr>";
}
echo "<tr class='tab_bg_1'><td colspan='2' class='b'>".OperatingSystem::getTypeName(1)."</td></tr>";
// 2. Get some more number data (operating systems per computer)
$iterator = $DB->request([
'SELECT' => [
'COUNT' => '* AS count',
'glpi_operatingsystems.name AS name'
],
'FROM' => 'glpi_items_operatingsystems',
'LEFT JOIN' => [
'glpi_operatingsystems' => [
'ON' => [
'glpi_items_operatingsystems' => 'operatingsystems_id',
'glpi_operatingsystems' => 'id'
]
]
],
'WHERE' => ['is_deleted' => 0],
'GROUPBY' => 'glpi_operatingsystems.name'
]);
while ($data = $iterator->next()) {
if (empty($data['name'])) {
$data['name'] = Dropdown::EMPTY_VALUE;
}
echo "<tr class='tab_bg_2'><td>".$data['name']."</td>";
echo "<td class='numeric'>".$data['count']."</td></tr>";
}
// Get counts of types
$val = array_flip($items);
unset($val["Software"]);
$items = array_flip($val);
foreach ($items as $itemtype) {
echo "<tr class='tab_bg_1'><td colspan='2' class='b'>".$itemtype::getTypeName(Session::getPluralNumber()).
"</td></tr>";
$table_item = getTableForItemType($itemtype);
$typeclass = $itemtype."Type";
$type_table = getTableForItemType($typeclass);
$typefield = getForeignKeyFieldForTable(getTableForItemType($typeclass));
$criteria = [
'SELECT' => [
'COUNT' => '* AS count',
"$type_table.name AS name"
],
'FROM' => $table_item,
'LEFT JOIN' => [
$type_table => [
'ON' => [
$table_item => $typefield,
$type_table => 'id'
]
]
],
'WHERE' => [
"$table_item.is_deleted" => 0,
"$table_item.is_template" => 0
] + getEntitiesRestrictCriteria($table_item),
'GROUPBY' => "$type_table.name"
];
if (in_array($itemtype, $linkitems)) {
$criteria['LEFT JOIN']['glpi_computers_items'] = [
'ON' => [
'glpi_computers_items' => 'items_id',
$table_item => 'id', [
'AND' => [
'glpi_computers_items.itemtype' => $itemtype
]
]
]
];
}
$iterator = $DB->request($criteria);
while ($data = $iterator->next()) {
if (empty($data['name'])) {
$data['name'] = Dropdown:: EMPTY_VALUE;
}
echo "<tr class='tab_bg_2'><td>".$data['name']."</td>";
echo "<td class='numeric'>".$data['count']."</td></tr>";
}
}
echo "</table>";
}
/**
* Get report informations
*
* @param string $from From table
* @param array $joincrit Join criteria
* @param array $where Where clause
* @param array $select Extra select clause
* @param array $leftjoin Extra LEFT JOIN clause
* @param array $innerjoin Extra INNER JOIN clause
* @param array $order Order clause
* @param string $extra ?
*
* @return void
*
* @since 10.0.0
**/
static function reportForNetworkInformations(
$from,
array $joincrit,
array $where = [],
array $select = [],
array $leftjoin = [],
array $innerjoin = [],
array $order = [],
$extra = ''
) {
global $DB;
// This SQL request matches the NetworkPort, then its NetworkName and IPAddreses. It also
// match opposite NetworkPort, then its NetworkName and IPAddresses.
// Results are groupes by NetworkPort. Then all IPs are concatenated by comma as separator.
if (count($joincrit) === 3) {
$andcrit = array_pop($joincrit);
$andcrit['AND']['PORT_1.is_deleted'] = 0;
$joincrit[] = $andcrit;
} else {
$joincrit[]['AND']['PORT_1.is_deleted'] = 0;
}
$criteria = [
'SELECT' => array_merge([
'PORT_1.itemtype AS itemtype_1',
'PORT_1.items_id AS items_id_1',
'PORT_1.id AS id_1',
'PORT_1.name AS port_1',
'PORT_1.mac AS mac_1',
'PORT_1.logical_number AS logical_1',
new QueryExpression('GROUP_CONCAT(' . $DB->quoteName('ADDR_1.name') . ' SEPARATOR ' . $DB->quote(',') . ') AS ' . $DB->quoteName('ip_1')),
'PORT_2.itemtype AS itemtype_2',
'PORT_2.items_id AS items_id_2',
'PORT_2.id AS id_2',
'PORT_2.name AS port_2',
'PORT_2.mac AS mac_2',
new QueryExpression('GROUP_CONCAT(' . $DB->quoteName('ADDR_2.name') .' SEPARATOR ' . $DB->quote(',') . ') AS ' . $DB->quoteName('ip_2'))
], $select),
'FROM' => $from,
'INNER JOIN' => $innerjoin + [
'glpi_networkports AS PORT_1' => [
'ON' => $joincrit
]
],
'LEFT JOIN' => [
'glpi_networknames AS NAME_1' => [
'ON' => [
'PORT_1' => 'id',
'NAME_1' => 'items_id', [
'AND' => [
'NAME_1.itemtype' => 'NetworkPort',
'NAME_1.is_deleted' => 0
]
]
]
],
'glpi_ipaddresses AS ADDR_1' => [
'ON' => [
'NAME_1' => 'id',
'ADDR_1' => 'items_id', [
'AND' => [
'ADDR_1.itemtype' => 'NetworkName',
'ADDR_1.is_deleted' => 0
]
]
]
],
'glpi_networkports_networkports AS LINK' => [
'ON' =>[
'LINK' => 'networkports_id_1',
'PORT_1' => 'id', [
'OR' => [
'LINK.networkports_id_2' => new QueryExpression($DB->quoteName('PORT_1.id'))
]
]
]
],
'glpi_networkports AS PORT_2' => [
'ON' => [
'PORT_2' => 'id',
new QueryExpression(
'IF(' . $DB->quoteName('LINK.networkports_id_1') . ' = ' . $DB->quoteName('PORT_1.id') . ', ' .
$DB->quoteName('LINK.networkports_id_2') . ', ' .
$DB->quoteName('LINK.networkports_id_1') . ')'
)
]
],
'glpi_networknames AS NAME_2' => [
'ON' => [
'PORT_2' => 'id',
'NAME_2' => 'items_id', [
'AND' => [
'NAME_2.itemtype' => 'NetworkPort',
'NAME_2.is_deleted' => 0
]
]
]
],
'glpi_ipaddresses AS ADDR_2' => [
'ON' => [
'NAME_2' => 'id',
'ADDR_2' => 'items_id', [
'AND' => [
'ADDR_2.itemtype' => 'NetworkName',
'ADDR_2.is_deleted' => 0
]
]
]
]
] + $leftjoin,
'WHERE' => $where,
'GROUPBY' => ['PORT_1.id']
];
if (count($order)) {
$criteria['ORDER'] = $order;
}
$iterator = $DB->request($criteria);
if (count($iterator)) {
echo "<table class='tab_cadre_fixehov'>";
echo "<tr>";
if (!empty($extra)) {
echo "<td>&nbsp;</td>";
}
echo "<th colspan='5'>".__('Device 1')."</th>";
echo "<th colspan='5'>".__('Device 2')."</th>";
echo "</tr>\n";
echo "<tr>";
if (!empty($extra)) {
echo "<th>$extra</th>";
}
echo "<th>"._n('Device type', 'Device types', 1)."</th>";
echo "<th>".__('Device name')."</th>";
echo "<th>".__('Port Number')."</th>";
echo "<th>".NetworkPort::getTypeName(1)."</th>";
echo "<th>".__('MAC address')."</th>";
echo "<th>".IPAddress::getTypeName(0)."</th>";
echo "<th>".NetworkPort::getTypeName(1)."</th>";
echo "<th>".__('MAC address')."</th>";
echo "<th>".IPAddress::getTypeName(0)."</th>";
echo "<th>"._n('Device type', 'Device types', 1)."</th>";
echo "<th>".__('Device name')."</th>";
echo "</tr>\n";
while ($line = $iterator->next()) {
echo "<tr class='tab_bg_1'>";
// To ensure that the NetworkEquipment remain the first item, we test its type
if ($line['itemtype_2'] == 'NetworkEquipment') {
$idx = 2;
} else {
$idx = 1;
}
if (!empty($extra)) {
echo "<td>".(empty($line['extra']) ? NOT_AVAILABLE : $line['extra'])."</td>";
}
$itemtype = $line["itemtype_$idx"];
if (!empty($itemtype)) {
echo "<td>".$itemtype::getTypeName(1)."</td>";
$item_name = '';
if ($item = getItemForItemtype($itemtype)) {
if ($item->getFromDB($line["items_id_$idx"])) {
$item_name = $item->getName();
}
}
echo "<td>".(empty($item_name) ? NOT_AVAILABLE : $item_name)."</td>";
} else {
echo "<td> ".NOT_AVAILABLE." </td>";
echo "<td> ".NOT_AVAILABLE." </td>";
}
echo "<td>".(empty($line["logical_$idx"]) ? NOT_AVAILABLE : $line["logical_$idx"])."</td>";
echo "<td>".(empty($line["port_$idx"]) ? NOT_AVAILABLE : $line["port_$idx"])."</td>";
echo "<td>".(empty($line["mac_$idx"]) ? NOT_AVAILABLE : $line["mac_$idx"])."</td>";
echo "<td>".(empty($line["ip_$idx"]) ? NOT_AVAILABLE : $line["ip_$idx"])."</td>";
if ($idx == 1) {
$idx = 2;
} else {
$idx = 1;
}
echo "<td>".(empty($line["port_$idx"]) ? NOT_AVAILABLE : $line["port_$idx"])."</td>";
echo "<td>".(empty($line["mac_$idx"]) ? NOT_AVAILABLE : $line["mac_$idx"])."</td>";
echo "<td>".(empty($line["ip_$idx"]) ? NOT_AVAILABLE : $line["ip_$idx"])."</td>";
$itemtype = $line["itemtype_$idx"];
if (!empty($itemtype)) {
echo "<td>".$itemtype::getTypeName(1)."</td>";
$item_name = '';
if ($item = getItemForItemtype($itemtype)) {
if ($item->getFromDB($line["items_id_$idx"])) {
$item_name = $item->getName();
}
}
echo "<td>".(empty($item_name) ? NOT_AVAILABLE : $item_name)."</td>";
} else {
echo "<td> ".NOT_AVAILABLE." </td>";
echo "<td> ".NOT_AVAILABLE." </td>";
}
echo "</tr>\n";
}
echo "</table><br><hr><br>";
}
}
/**
* @since 0.85
*
* @see commonDBTM::getRights()
**/
function getRights($interface = 'central') {
$values = [ READ => __('Read')];
return $values;
}
static function getIcon() {
return "fas fa-file-medical-alt";
}
}