367 lines
12 KiB
PHP
367 lines
12 KiB
PHP
<?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");
|
|
}
|
|
|
|
class RuleDictionnaryPrinterCollection extends RuleCollection {
|
|
// From RuleCollection
|
|
|
|
public $stop_on_first_match = true;
|
|
public $can_replay_rules = true;
|
|
public $menu_type = 'dictionnary';
|
|
public $menu_option = 'printer';
|
|
|
|
static $rightname = 'rule_dictionnary_printer';
|
|
|
|
/**
|
|
* @see RuleCollection::getTitle()
|
|
**/
|
|
function getTitle() {
|
|
return __('Dictionnary of printers');
|
|
}
|
|
|
|
|
|
/**
|
|
* @see RuleCollection::cleanTestOutputCriterias()
|
|
**/
|
|
function cleanTestOutputCriterias(array $output) {
|
|
|
|
//If output array contains keys begining with _ : drop it
|
|
foreach ($output as $criteria => $value) {
|
|
if (($criteria[0] == '_') && ($criteria != '_ignore_import')) {
|
|
unset ($output[$criteria]);
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
|
|
/**
|
|
* @see RuleCollection::replayRulesOnExistingDB()
|
|
**/
|
|
function replayRulesOnExistingDB($offset = 0, $maxtime = 0, $items = [], $params = []) {
|
|
global $DB;
|
|
|
|
if (isCommandLine()) {
|
|
printf(__('Replay rules on existing database started on %s')."\n", date("r"));
|
|
}
|
|
$nb = 0;
|
|
$i = $offset;
|
|
|
|
//Select all the differents software
|
|
$criteria = [
|
|
'SELECT' => [
|
|
'glpi_printers.name',
|
|
'glpi_manufacturers.name AS manufacturer',
|
|
'glpi_printers.manufacturers_id AS manufacturers_id',
|
|
'glpi_printers.comment AS comment'
|
|
],
|
|
'DISTINCT' => true,
|
|
'FROM' => 'glpi_printers',
|
|
'LEFT JOIN' => [
|
|
'glpi_manufacturers' => [
|
|
'ON' => [
|
|
'glpi_manufacturers' => 'id',
|
|
'glpi_printers' => 'manufacturers_id'
|
|
]
|
|
]
|
|
],
|
|
'WHERE' => [
|
|
// Do not replay on trashbin and templates
|
|
'glpi_printers.is_deleted' => 0,
|
|
'glpi_printers.is_template' => 0
|
|
]
|
|
];
|
|
|
|
if ($offset) {
|
|
$criteria['START'] = (int)$offset;
|
|
$criteria['LIMIT'] = 999999999;
|
|
}
|
|
|
|
$iterator = $DB->request($criteria);
|
|
$nb = count($iterator) + $offset;
|
|
$step = (($nb > 1000) ? 50 : (($nb > 20) ? floor(count($iterator) / 20) : 1));
|
|
|
|
while ($input = $iterator->next()) {
|
|
if (!($i % $step)) {
|
|
if (isCommandLine()) {
|
|
//TRANS: %1$s is a date, %2$s is a row, %3$s is total row, %4$s is memory
|
|
printf(__('%1$s - replay rules on existing database: %2$s/%3$s (%4$s Mio)')."\n",
|
|
date("H:i:s"), $i, $nb, round(memory_get_usage() / (1024 * 1024), 2));
|
|
} else {
|
|
Html::changeProgressBarPosition($i, $nb, "$i / $nb");
|
|
}
|
|
}
|
|
|
|
//Replay printer dictionnary rules
|
|
$res_rule = $this->processAllRules($input, [], []);
|
|
|
|
foreach (['manufacturer', 'is_global', 'name'] as $attr) {
|
|
if (isset($res_rule[$attr]) && ($res_rule[$attr] == '')) {
|
|
unset($res_rule[$attr]);
|
|
}
|
|
}
|
|
|
|
//If the software's name or version has changed
|
|
if (self::somethingHasChanged($res_rule, $input)) {
|
|
|
|
$IDs = [];
|
|
//Find all the printers in the database with the same name and manufacturer
|
|
$print_iterator = $DB->request([
|
|
'SELECT' => 'id',
|
|
'FROM' => 'glpi_printers',
|
|
'WHERE' => [
|
|
'name' => $input['name'],
|
|
'manufacturers_id' => $input['manufacturers_id']
|
|
]
|
|
]);
|
|
|
|
if (count($print_iterator)) {
|
|
//Store all the printer's IDs in an array
|
|
while ($result = $print_iterator->next()) {
|
|
$IDs[] = $result["id"];
|
|
}
|
|
//Replay dictionnary on all the printers
|
|
$this->replayDictionnaryOnPrintersByID($IDs, $res_rule);
|
|
}
|
|
}
|
|
$i++;
|
|
|
|
if ($maxtime) {
|
|
$crt = explode(" ", microtime());
|
|
if ($crt[0] + $crt[1] > $maxtime) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isCommandLine()) {
|
|
printf(__('Replay rules on existing database: %1$s/%2$s')."\n", $i, $nb);
|
|
} else {
|
|
Html::changeProgressBarPosition($i, $nb, "$i / $nb");
|
|
}
|
|
|
|
if (isCommandLine()) {
|
|
printf(__('Replay rules on existing database ended on %s')."\n", date("r"));
|
|
}
|
|
|
|
return (($i == $nb) ? -1 : $i);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $res_rule array
|
|
* @param $input array
|
|
**/
|
|
static function somethingHasChanged(array $res_rule, array $input) {
|
|
|
|
if ((isset($res_rule["name"]) && ($res_rule["name"] != $input["name"]))
|
|
|| (isset($res_rule["manufacturer"]) && ($res_rule["manufacturer"] != ''))
|
|
|| (isset($res_rule['is_global']) && ($res_rule['is_global'] != ''))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Replay dictionnary on several printers
|
|
*
|
|
* @param $IDs array of printers IDs to replay
|
|
* @param $res_rule array of rule results
|
|
*
|
|
* @return Query result handler
|
|
**/
|
|
function replayDictionnaryOnPrintersByID(array $IDs, $res_rule = []) {
|
|
global $DB;
|
|
|
|
$new_printers = [];
|
|
$delete_ids = [];
|
|
|
|
$iterator = $DB->request([
|
|
'SELECT' => [
|
|
'glpi_printers.id',
|
|
'glpi_printers.name',
|
|
'glpi_printers.entities_id AS entities_id',
|
|
'glpi_printers.is_global AS is_global',
|
|
'glpi_manufacturers.name AS manufacturer'
|
|
],
|
|
'FROM' => 'glpi_printers',
|
|
'LEFT JOIN' => [
|
|
'glpi_manufacturers' => [
|
|
'FKEY' => [
|
|
'glpi_printers' => 'manufacturers_id',
|
|
'glpi_manufacturers' => 'id'
|
|
]
|
|
]
|
|
],
|
|
'WHERE' => [
|
|
'glpi_printers.is_template' => 0,
|
|
'glpi_printers.id' => $IDs
|
|
]
|
|
]);
|
|
|
|
while ($printer = $iterator->next()) {
|
|
//For each printer
|
|
$this->replayDictionnaryOnOnePrinter($new_printers, $res_rule, $printer, $delete_ids);
|
|
}
|
|
|
|
//Delete printer if needed
|
|
$this->putOldPrintersInTrash($delete_ids);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param $IDS array
|
|
*/
|
|
function putOldPrintersInTrash($IDS = []) {
|
|
|
|
$printer = new Printer();
|
|
foreach ($IDS as $id) {
|
|
$printer->delete(['id' => $id]);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Replay dictionnary on one printer
|
|
*
|
|
* @param &$new_printers array containing new printers already computed
|
|
* @param $res_rule array of rule results
|
|
* @param $params array
|
|
* @param &$printers_ids array containing replay printer need to be put in trashbin
|
|
**/
|
|
function replayDictionnaryOnOnePrinter(array &$new_printers, array $res_rule,
|
|
array $params, array &$printers_ids) {
|
|
$p['id'] = 0;
|
|
$p['name'] = '';
|
|
$p['manufacturer'] = '';
|
|
$p['is_global'] = '';
|
|
$p['entity'] = 0;
|
|
foreach ($params as $key => $value) {
|
|
$p[$key] = $value;
|
|
}
|
|
|
|
$input["name"] = $p['name'];
|
|
$input["manufacturer"] = $p['manufacturer'];
|
|
|
|
if (empty($res_rule)) {
|
|
$res_rule = $this->processAllRules($input, [], []);
|
|
}
|
|
|
|
$printer = new Printer();
|
|
|
|
//Printer's name has changed
|
|
if (isset($res_rule["name"])
|
|
&& ($res_rule["name"] != $p['name'])) {
|
|
|
|
$manufacturer = "";
|
|
|
|
if (isset($res_rule["manufacturer"])) {
|
|
$manufacturer = addslashes(Dropdown::getDropdownName("glpi_manufacturers",
|
|
$res_rule["manufacturer"]));
|
|
} else {
|
|
$manufacturer = addslashes($p['manufacturer']);
|
|
}
|
|
|
|
//New printer not already present in this entity
|
|
if (!isset($new_printers[$p['entity']][$res_rule["name"]])) {
|
|
// create new printer or restore it from trashbin
|
|
$new_printer_id = $printer->addOrRestoreFromTrash($res_rule["name"], $manufacturer,
|
|
$p['entity']);
|
|
$new_printers[$p['entity']][$res_rule["name"]] = $new_printer_id;
|
|
} else {
|
|
$new_printer_id = $new_printers[$p['entity']][$res_rule["name"]];
|
|
}
|
|
|
|
// Move direct connections
|
|
$this->moveDirectConnections($p['id'], $new_printer_id);
|
|
|
|
} else {
|
|
$new_printer_id = $p['id'];
|
|
$res_rule["id"] = $p['id'];
|
|
|
|
if (isset($res_rule["manufacturer"])) {
|
|
if ($res_rule["manufacturer"] != '') {
|
|
$res_rule["manufacturers_id"] = $res_rule["manufacturer"];
|
|
}
|
|
unset($res_rule["manufacturer"]);
|
|
}
|
|
$printer->update($res_rule);
|
|
}
|
|
|
|
// Add to printer to deleted list
|
|
if ($new_printer_id != $p['id']) {
|
|
$printers_ids[] = $p['id'];
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Move direct connections from old printer to the new one
|
|
*
|
|
* @param $ID the old printer's id
|
|
* @param $new_printers_id the new printer's id
|
|
*
|
|
* @return void
|
|
**/
|
|
function moveDirectConnections($ID, $new_printers_id) {
|
|
$computeritem = new Computer_Item();
|
|
//For each direct connection of this printer
|
|
$connections = getAllDataFromTable(
|
|
'glpi_computers_items', [
|
|
'itemtype' => 'Printer',
|
|
'items_id' => $ID
|
|
]
|
|
);
|
|
foreach ($connections as $connection) {
|
|
|
|
//Direct connection exists in the target printer ?
|
|
if (!countElementsInTable("glpi_computers_items",
|
|
['itemtype' => 'Printer',
|
|
'items_id' => $new_printers_id,
|
|
'computers_id' => $connection["computers_id"]])) {
|
|
//Direct connection doesn't exists in the target printer : move it
|
|
$computeritem->update(['id' => $connection['id'],
|
|
'items_id' => $new_printers_id]);
|
|
} else {
|
|
//Direct connection already exists in the target printer : delete it
|
|
$computeritem->delete($connection);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|