dolibarr.netdiag/class/netdiagdevice.class.php
Eduard Wisch d079431cdf Phase 5 abgeschlossen: Klarnamen, Parameter, Listen-Ampel, N+1, Standort
- Werkzeug-Klarnamen statt interner IDs: "IP-Scanner — 46 Geräte im Netz …"
  statt "[netzwerk] ipscan — …". Bewusst eine kurze Zuordnung in
  netdiagToolName() statt eines zweiten Satzes Sprachschlüssel — die
  kanonischen Namen stehen in der App, doppelte Pflege wäre eine Fehlerquelle.
  Enthält auch dhcpcheck/wifiscan: in der App gibt es sie nicht mehr, in der
  PRODUKTIONSDATENBANK stehen dazu aber noch Messungen (4 bzw. 2). Die
  Gegenprüfung hielt den Punkt für gegenstandslos, hatte dabei aber nur die
  Testdatenbank angesehen.

- Messparameter anzeigen (Prod-Messung #126): unter jeder Messung steht jetzt
  "Ziel: 192.168.1.1 · Dauer (s): 300" in Karte und PDF. Vorher stand das
  Ergebnis ohne Bezugspunkt da — man sah nicht, wogegen gemessen wurde.

- Listenseite: Ampel je Protokoll (schlechteste Einzelmessung) plus Anzahl,
  dazu ein Filter "nur mit Befund". Status 3 "nicht messbar" geht bewusst
  NICHT ins Maximum ein — er ist keine Aussage über das Kundennetz — sondern
  wird separat als "n.m." ausgewiesen. Im Browser geprüft: der Filter liefert
  ausschließlich Protokolle mit Warnung oder Fehler.

- N+1-Queries behoben: fetchAllByProtocol() las nur die rowids und setzte je
  Zeile ein eigenes fetch() ab. Jetzt eine Abfrage mit setVarsFromFetchObj(),
  zusätzlich mit Entity-Filter (fehlte bisher ganz). Nachgemessen über
  SHOW SESSION STATUS: 46 Geräte + 7 Messungen brauchen statt 55 Abfragen
  noch eine.

- Standort aus der Kundenadresse vorbelegen, wenn der Techniker nichts
  eingetragen hat; eine vorhandene Angabe wird nie überschrieben. Über die
  echte API geprüft.

Offen bleibt aus Phase 5 nur der Vergleich zweier Protokolle (Geräte-Diff
nach MAC) — eigenes Feature mit eigener Ansicht.
2026-08-16 11:09:28 +02:00

183 lines
6.8 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/custom/netdiag/class/netdiagdevice.class.php
* \ingroup netdiag
* \brief Klasse für ein im Diagnose-Protokoll gefundenes Gerät
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
/**
* Klasse NetDiagDevice — ein im Netzwerk gefundenes Gerät.
*/
class NetDiagDevice extends CommonObject
{
/** @var string Modul-Name */
public $module = 'netdiag';
/** @var string Element-Typ */
public $element = 'netdiagdevice';
/** @var string Datenbanktabelle (ohne Präfix) */
public $table_element = 'netdiag_device';
/** @var string Icon */
public $picto = 'fa-desktop';
/** @var int 1 = Tabelle hat ein 'entity'-Feld */
public $ismultientitymanaged = 1;
/**
* @var array<string,array<string,mixed>> Felddefinitionen
*/
public $fields = array(
'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'index' => 1, 'position' => 1),
'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'default' => 1, 'index' => 1, 'position' => 5),
'fk_protocol' => array('type' => 'integer', 'label' => 'Protocol', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'index' => 1, 'position' => 10),
'ip' => array('type' => 'varchar(45)', 'label' => 'IpAddress', 'enabled' => 1, 'visible' => 1, 'position' => 20),
'mac' => array('type' => 'varchar(17)', 'label' => 'MacAddress', 'enabled' => 1, 'visible' => 1, 'position' => 25),
'hostname' => array('type' => 'varchar(255)', 'label' => 'Hostname', 'enabled' => 1, 'visible' => 1, 'position' => 30),
'netbios_name' => array('type' => 'varchar(64)', 'label' => 'NetDiagNetbiosName', 'enabled' => 1, 'visible' => 1, 'position' => 31),
'mdns_name' => array('type' => 'varchar(255)', 'label' => 'NetDiagMdnsName', 'enabled' => 1, 'visible' => 1, 'position' => 32),
'mdns_services' => array('type' => 'varchar(512)', 'label' => 'NetDiagMdnsServices', 'enabled' => 1, 'visible' => 3, 'position' => 33),
'custom_name' => array('type' => 'varchar(255)', 'label' => 'NetDiagCustomName', 'enabled' => 1, 'visible' => 1, 'position' => 34),
'vendor' => array('type' => 'varchar(128)', 'label' => 'Vendor', 'enabled' => 1, 'visible' => 1, 'position' => 35),
'devicetype' => array('type' => 'varchar(64)', 'label' => 'DeviceType', 'enabled' => 1, 'visible' => 1, 'position' => 40),
'open_ports' => array('type' => 'varchar(255)', 'label' => 'NetDiagOpenPorts', 'enabled' => 1, 'visible' => 1, 'position' => 41),
'found_via' => array('type' => 'varchar(16)', 'label' => 'NetDiagFoundVia', 'enabled' => 1, 'visible' => 1, 'position' => 42),
'last_seen' => array('type' => 'datetime', 'label' => 'NetDiagLastSeen', 'enabled' => 1, 'visible' => 1, 'position' => 43),
'note' => array('type' => 'text', 'label' => 'Note', 'enabled' => 1, 'visible' => 3, 'position' => 50),
'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'position' => 500),
'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => 0, 'notnull' => 0, 'position' => 501),
);
public $rowid;
public $entity;
public $fk_protocol;
public $ip;
public $mac;
public $hostname;
/** @var string NetBIOS-Name (UDP-137-Abfrage) */
public $netbios_name;
/** @var string mDNS-/Bonjour-Anzeigename */
public $mdns_name;
/** @var string angebotene mDNS-Dienste, kommagetrennt */
public $mdns_services;
/** @var string vom Techniker vergebener Name */
public $custom_name;
public $vendor;
public $devicetype;
/** @var string offene Ports, kommagetrennt (z.B. "80,443,9100") */
public $open_ports;
/** @var string Fundweg: ping | port | arp | mdns */
public $found_via;
/** @var int|string Unix-Zeit/Datum der letzten Sichtung */
public $last_seen;
public $note;
public $date_creation;
public $tms;
/**
* Konstruktor
*
* @param DoliDB $db Datenbank-Handler
*/
public function __construct(DoliDB $db)
{
$this->db = $db;
}
/**
* Datensatz anlegen
*
* @param User $user Benutzer
* @param int $notrigger 1 = Trigger unterdrücken
* @return int >0 wenn OK, <=0 bei Fehler
*/
public function create(User $user, $notrigger = 0)
{
return $this->createCommon($user, $notrigger);
}
/**
* Datensatz laden
*
* @param int $id Rowid
* @param string $ref Referenz
* @return int >0 wenn OK, 0 wenn nicht gefunden, <0 bei Fehler
*/
public function fetch($id, $ref = null)
{
return $this->fetchCommon($id, $ref);
}
/**
* Alle Geräte eines Protokolls laden
*
* @param int $fk_protocol Protokoll-Rowid
* @return NetDiagDevice[] Liste der Geräte
*/
public function fetchAllByProtocol($fk_protocol)
{
// Alle Spalten in EINER Abfrage holen. Vorher wurden nur die rowids
// gelesen und je Zeile ein eigenes fetch() abgesetzt — bei 46 Geräten
// also 47 Abfragen statt einer. Die Kartenansicht und der
// PDF-Generator laden diese Liste jeweils komplett.
$result = array();
$sql = "SELECT * FROM ".$this->db->prefix().$this->table_element;
$sql .= " WHERE fk_protocol = ".((int) $fk_protocol);
$sql .= " AND entity IN (".getEntity($this->element).")";
$sql .= " ORDER BY INET_ATON(ip), rowid";
$resql = $this->db->query($sql);
if ($resql) {
while ($obj = $this->db->fetch_object($resql)) {
$dev = new self($this->db);
$dev->setVarsFromFetchObj($obj);
$dev->id = (int) $obj->rowid;
$result[] = $dev;
}
$this->db->free($resql);
}
return $result;
}
/**
* Datensatz aktualisieren
*
* @param User $user Benutzer
* @param int $notrigger 1 = Trigger unterdrücken
* @return int >0 wenn OK, <=0 bei Fehler
*/
public function update(User $user, $notrigger = 0)
{
return $this->updateCommon($user, $notrigger);
}
/**
* Datensatz löschen
*
* @param User $user Benutzer
* @param int $notrigger 1 = Trigger unterdrücken
* @return int >0 wenn OK, <=0 bei Fehler
*/
public function delete(User $user, $notrigger = 0)
{
return $this->deleteCommon($user, $notrigger);
}
}