You are not logged in.

Announcement

 Téléchargez la dernière version stable de GLPI      -     Et vous, que pouvez vous faire pour le projet GLPI ? :  Contribuer
 Download last stable version of GLPI                      -     What can you do for GLPI ? :  Contribute

#26 2016-08-19 16:11:07

kevinG
Guest
Registered: 2014-02-26
Posts: 298

Re: Erreur suite remontée inventaire

Je pense avoir trouvé, dans le fichier "inventorycomputerlib.class.php" dans la fonction "updateComputer" dans la partie "monitor" le début  à la ligne  1307.
Dans la requête qui commence à la ligne 1328, on vérifie uniquement les monitors déjà connecté sur l'ordinateur qui fait une remontée. Puis on supprime les liens existant.
Mais on n'a pas de requête pour vérifier que le moniteur est déjà attaché à un autre PC. Donc les liens ne sont jamais supprimés.
Et quand on passe dans la classe "Computer_item", vu que l'on vérifie s'il y a déjà un lien et si on est en gestion global sur le matériel alors on ne fait rien.

Il faudrait donc, je pense, ajouter du code pour supprimer tous les liens des moniteurs s'il n'est pas en gestion global.

Je n'ai pas pu me pencher sur le code à mettre mais lundi je pourrai proposer quelque chose wink
Il suffit peut être de remplacer la condition

AND `computers_id`='".$computers_id."'

par

AND ((`computers_id`='".$computers_id."') OR (`items_id`='".$data['found_equipment'][0]."))'

Un truc du genre vu que $data['found_equipment'][0] c'est pas top, mais j'ai pas bien vu comment était alimenté $a_monitors smile

Et j'espère que je suis assez clair hmm

Edit : vu que c'est une nouvelle page voir mon message précédent pour l'issue wink

Last edited by kevinG (2016-08-19 16:19:39)


Version en production GLPI 9.1.4 (En cours de test 9.1.5)
Version en production Fusion Inventory 9.1+1.0
Version PHP 5.6.30
Zend Engine v2.6.0 - Zend OPcache v7.0.6-dev - Xdebug v2.5.0

Offline

#28 2016-08-22 11:42:43

kevinG
Guest
Registered: 2014-02-26
Posts: 298

Re: Erreur suite remontée inventaire

Mon code proposé avant ne sert à rien. Par contre toujours dans la même fonction j'ai fait d'autre modifications qui à l'air de fonctionné test fait sur des doubles écrans.
A confirmer et valider, mais voici le code de la fonction "updateComputer" dans la partie monitor qui commence à la ligne 1307 sur la page "inventorycomputerlib.class.php"

     // * Monitors

      $rule = new PluginFusioninventoryInventoryRuleImportCollection();
      $a_monitors = array();
        $a_monitors_for_condition = 0;
      foreach ($a_computerinventory['monitor'] as $key => $arrays) {
         $input = array();
         $input['itemtype'] = "Monitor";
         $input['name']     = $arrays['name'];
         $input['serial']   = $arrays['serial'];
         $data = $rule->processAllRules($input, array(), array('class'=>$this, 'return' => TRUE));
         if (isset($data['found_equipment'])) {
            if ($data['found_equipment'][0] == 0) {
               // add monitor
               $arrays['entities_id'] = $entities_id;
               $a_monitors[] = $monitor->add($arrays);
            } else {
               $a_monitors[] = $data['found_equipment'][0];
                    if($a_monitors_for_condition != 0){
                        $a_monitors_for_condition .= ',';
                    }
                    $a_monitors_for_condition .= $data['found_equipment'][0];
            }
         }
      }
      $db_monitors = array();

      $query = "SELECT `glpi_monitors`.`id`,
                       `glpi_computers_items`.`id` as link_id
            FROM `glpi_computers_items`
         LEFT JOIN `glpi_monitors` ON `items_id`=`glpi_monitors`.`id`
         WHERE `itemtype`='Monitor'
            AND `computers_id`='".$computers_id."'
            AND `entities_id`='".$entities_id."'
            AND `glpi_computers_items`.`is_dynamic`='1'
            AND `glpi_monitors`.`is_global`='0'";
      $result = $DB->query($query);
      while ($data = $DB->fetch_assoc($result)) {
         $idtmp = $data['link_id'];
         unset($data['link_id']);
         $db_monitors[$idtmp] = $data['id'];
      }
        
        $query_condition = "SELECT `glpi_monitors`.`id`,
                      `glpi_computers_items`.`id` as link_id
        FROM `glpi_computers_items`
        LEFT JOIN `glpi_monitors` ON `items_id`=`glpi_monitors`.`id`
        WHERE `itemtype`='Monitor'
        AND `computers_id`!='".$computers_id."'
        AND `items_id` in (".$a_monitors_for_condition.")
        AND `entities_id`='".$entities_id."'
        AND `glpi_computers_items`.`is_dynamic`='1'
        AND `glpi_monitors`.`is_global`='0'";
        
        $result_condition = $DB->query($query_condition);
        while ($data = $DB->fetch_assoc($result_condition)) {
         $idtmp = $data['link_id'];
         unset($data['link_id']);
         $db_monitors_condition[$idtmp] = $data['id'];
      }
      if ((count($db_monitors) == 0) && (count($db_monitors_condition) == 0)) {
         foreach ($a_monitors as $monitors_id) {
            $input = array();
            $input['computers_id']   = $computers_id;
            $input['itemtype']       = 'Monitor';
            $input['items_id']       = $monitors_id;
            $input['is_dynamic']     = 1;
            $input['_no_history']    = $no_history;
            $computer_Item->add($input, array(), !$no_history);
         }
      } else {
         // Check all fields from source:
         foreach ($a_monitors as $key => $monitors_id) {
            foreach ($db_monitors as $keydb => $monits_id) {
               if ($monitors_id == $monits_id) {
                  unset($a_monitors[$key]);
                  unset($db_monitors[$keydb]);
                  break;
               }
            }
         }
         if (count($a_monitors) == 0
            AND count($db_monitors) == 0) {
            // Nothing to do
         } else {
            if (count($db_monitors) != 0) {
               // Delete monitors links in DB
               foreach ($db_monitors as $idtmp => $monits_id) {
                  $computer_Item->delete(array('id'=>$idtmp), 1);
               }
            }
            if (count($db_monitors_condition) != 0) {
               // Delete monitors links in DB other computer
               foreach ($db_monitors_condition as $idtmp => $monits_id) {
                  $computer_Item->delete(array('id'=>$idtmp), 1);
               }
            }
            if (count($a_monitors) != 0) {
               foreach($a_monitors as $key => $monitors_id) {
                  $input = array();
                  $input['computers_id']   = $computers_id;
                  $input['itemtype']       = 'Monitor';
                  $input['items_id']       = $monitors_id;
                  $input['is_dynamic']     = 1;
                  $input['_no_history']    = $no_history;
                  $computer_Item->add($input, array(), !$no_history);
               }
            }
         }
      }

Explication du code ajouté :
A la ligne 1311, je déclare une variable qui permettra de faire une requete sur les écrans connectés sur d'autre ordinateur plus tard :

        $a_monitors_for_condition = 0;

A la ligne 1325, j'alimente la variable à ce moment pour éviter de faire une boucle sur après sur le tableau "$a_monitor":

                    if($a_monitors_for_condition != 0){
                        $a_monitors_for_condition .= ',';
                    }
                    $a_monitors_for_condition .= $data['found_equipment'][0];

A la ligne 1350, je créé la requête pour voir si les écrans sont connectés sur d'autre ordinateur que celui en cours et en mode global , puis j'exécute la requête :

        $query_condition = "SELECT `glpi_monitors`.`id`,
                      `glpi_computers_items`.`id` as link_id
        FROM `glpi_computers_items`
        LEFT JOIN `glpi_monitors` ON `items_id`=`glpi_monitors`.`id`
        WHERE `itemtype`='Monitor'
        AND `computers_id`!='".$computers_id."'
        AND `items_id` in (".$a_monitors_for_condition.")
        AND `entities_id`='".$entities_id."'
        AND `glpi_computers_items`.`is_dynamic`='1'
        AND `glpi_monitors`.`is_global`='0'";
        
        $result_condition = $DB->query($query_condition);

A la ligne 1362, je mémorise les liens :

        while ($data = $DB->fetch_assoc($result_condition)) {
         $idtmp = $data['link_id'];
         unset($data['link_id']);
         $db_monitors_condition[$idtmp] = $data['id'];
      }

A la ligne 1367, j'ajoute le critère  dans la condition qui vérifie si le "$db_monitors_condition" est vide :

     if ((count($db_monitors) == 0) && (count($db_monitors_condition) == 0))

Enfin à la ligne 1398, je supprime les liens avec les autres ordinateurs afin de pouvoir faire la lisaison avec l'ordinateur actuel :

            if (count($db_monitors_condition) != 0) {
               // Delete monitors links in DB other computer
               foreach ($db_monitors_condition as $idtmp => $monits_id) {
                  $computer_Item->delete(array('id'=>$idtmp), 1);
               }
            }

Last edited by kevinG (2017-08-10 09:50:47)


Version en production GLPI 9.1.4 (En cours de test 9.1.5)
Version en production Fusion Inventory 9.1+1.0
Version PHP 5.6.30
Zend Engine v2.6.0 - Zend OPcache v7.0.6-dev - Xdebug v2.5.0

Offline

#29 2017-08-10 10:00:55

kevinG
Guest
Registered: 2014-02-26
Posts: 298

Re: Erreur suite remontée inventaire

Mon code produisait une erreur car je ne tenais pas compte des ordinateurs qui n'avait pas d'écran (serveur, portable, ...).
Cela remplissait le fichier sql_error.log
J'ai remis les modifications pour corriger ses erreurs.

Le code avant les modifications :

A la ligne 1311, je déclare une variable qui permettra de faire une requete sur les écrans connectés sur d'autre ordinateur plus tard :

        $a_monitors_for_condition = '';

A la ligne 1325, j'alimente la variable à ce moment pour éviter de faire une boucle sur après sur le tableau "$a_monitor":

                    if($a_monitors_for_condition != ''){
                        $a_monitors_for_condition .= ',';
                    }
                    $a_monitors_for_condition .= $data['found_equipment'][0];

En rouge ce qu'il faut modifier:
$a_monitors_for_condition = '';
if($a_monitors_for_condition != ''){

Le code après modification :
A la ligne 1311, je déclare une variable qui permettra de faire une requete sur les écrans connectés sur d'autre ordinateur plus tard :

        $a_monitors_for_condition = 0;

A la ligne 1325, j'alimente la variable à ce moment pour éviter de faire une boucle sur après sur le tableau "$a_monitor":

                    if($a_monitors_for_condition != 0){
                        $a_monitors_for_condition .= ',';
                    }
                    $a_monitors_for_condition .= $data['found_equipment'][0];

En bleu les modifications apportés
$a_monitors_for_condition = 0;
if($a_monitors_for_condition != 0){


Version en production GLPI 9.1.4 (En cours de test 9.1.5)
Version en production Fusion Inventory 9.1+1.0
Version PHP 5.6.30
Zend Engine v2.6.0 - Zend OPcache v7.0.6-dev - Xdebug v2.5.0

Offline

Board footer

Powered by FluxBB