EVOLUTION-MANAGER
Edit File: ruledictionnaryprintercollection.class.php
<?php /** * --------------------------------------------------------------------- * GLPI - Gestionnaire Libre de Parc Informatique * Copyright (C) 2015-2018 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 $sql = "SELECT DISTINCT `glpi_printers`.`name`, `glpi_manufacturers`.`name` AS manufacturer, `glpi_printers`.`manufacturers_id` AS manufacturers_id, `glpi_printers`.`comment` AS comment FROM `glpi_printers` LEFT JOIN `glpi_manufacturers` ON (`glpi_manufacturers`.`id` = `glpi_printers`.`manufacturers_id`) "; // Do not replay on trashbin and templates $sql .= "WHERE `glpi_printers`.`is_deleted` = 0 AND `glpi_printers`.`is_template` = 0 "; if ($offset) { $sql .= " LIMIT " . intval($offset) . ",999999999"; } $res = $DB->query($sql); $nb = $DB->numrows($res) + $offset; $step = (($nb > 1000) ? 50 : (($nb > 20) ? floor($DB->numrows($res) / 20) : 1)); while ($input = $DB->fetch_assoc($res)) { 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($iterator)) { //Store all the printer's IDs in an array while ($result = $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) { global $DB; $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 nothing **/ function moveDirectConnections($ID, $new_printers_id) { global $DB; $computeritem = new Computer_Item(); //For each direct connection of this printer foreach (getAllDatasFromTable( 'glpi_computers_items', [ 'itemtype' => 'Printer', 'items_id' => $ID] ) 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); } } } }