Heute werden wir darüber sprechen, wie ich das GLPI-Plugin geschrieben habe, um mit neuen Bestellungen zu arbeiten, die auf der Grundlage bereits abgeschlossener Bestellungen erstellt wurden, oder vielmehr geschlossene Bestellungen wieder zu öffnen, wenn zusätzliche Anfragen vom Benutzer für sie eingehen.
HintergrundDie Eingabeparameter sind wie folgt.
Seit fast einem Monat beschäftige ich mich mit dem Quellcode des GLPI-Helpdesk-Systems. Und während ich diese Open-Source-Lösung studierte, machte ich auf die vernachlässigbare Menge an Informationen für Entwickler aufmerksam. Die überwiegende Mehrheit des Materials bezieht sich auf die GLPI-Konfiguration innerhalb der Schnittstelle. Ein bisschen weniger, aber Sie können immer noch Informationen zum Einrichten des Servers finden. Und nur ein Artikel (und der auf Englisch) erzählt von der Entwicklung von Plugins für dieses Wundersystem.
Aus den offiziellen Handbüchern - ein paar Ressourcen zu readthedocs sowie ein aus phpdoc generiertes Handbuch.
Aus der Community - ein Chat im Telegramm und ein ausländisches Forum.
Es gibt ein GLPI-Helpdesk-System. Anwendungen von Benutzern werden an eine dedizierte Mailbox gesendet, die mit dem System verbunden ist. Die Antwort des Support-Service kommt auch per Post an. Im Allgemeinen werden alle Benachrichtigungen über den Fortschritt des Antrags vom ersten Anruf bis zur Entscheidung und zum Abschluss per E-Mail gesendet.
Wenn der Benutzer jedoch der Ansicht ist, dass sein Problem nicht ordnungsgemäß behoben wurde, und beschließt, auf den Brief zum Schließen der Anwendung zu antworten, wird anstelle des erneuten Öffnens ein neues Ticket erstellt und das alte Ticket einfach daran gebunden. Eigentlich musste dieses Problem gelöst werden.
So lass uns gehen.
Der erste Schritt ist die Installation des Plugin-Generators- Es vereinfacht das Leben erheblich, indem es das Grundgerüst unseres zukünftigen Plugins erstellt. Dies kann mit dem folgenden Algorithmus erfolgen:
Und das war's, der Rahmen ist fertig.
Wenn Sie in das Verzeichnis des von Ihnen erstellten Plugins gehen, sehen Sie eine Reihe von Dateien, von denen nur setup.php und hook.php wirklich benötigt werden. Wenn Sie zusätzliche Bibliotheken verwenden möchten, können Sie composer.json verlassen. Ich brauchte diese nicht, also habe ich nur 2 notwendige Dateien hinterlassen.
In der Datei setup.php sind zwei Funktionen erforderlich: plugin_init_yourpluginname und plugin_version_yourpluginname . Der erste initialisiert das Plugin, der zweite gibt Informationen darüber zurück - Name, Autor, Version usw.
Mit dem zweiten ist alles mehr oder weniger klar. Daher konzentrieren wir uns kurz auf die erste Funktion. Es funktioniert mit der globalen Variablen $ PLUGIN_HOOKS... Sicher weiß jeder, was Haken sind, aber wenn jemand nicht Bescheid weiß, dann ist dies der sogenannte. System-Hooks, die das Plugin zieht. Weitere Informationen zu Haken finden Sie im offiziellen Handbuch .
Jedes Plugin muss den csrf_compliant- Hook registrieren . Andernfalls können Sie ihn einfach nicht aktivieren. Es tritt ein Fehler wie der folgende auf:
Ich weiß nicht, was dieser Parameter ist, bis ich das System bis zum Ende herausgefunden habe. Wenn sich unter den Lesern GLPI-Experten befinden, schreiben Sie in die Kommentare.
Neben dem obligatorischen Hook können Sie viele andere registrieren, z. B. einen Link zur Einstellungsseite setzen:
$PLUGIN_HOOKS['config_page']['yourpluginname'] = 'config.php';
Plugin-Klassen sind ebenfalls in dieser Funktion registriert:
Plugin::registerClass(PluginYourpluginnameConfig::class);
, , , GLPI , . : Plugin + + . , , .Kehren wir zu unseren Haken zurück. Ich muss die Erstellung eines neuen Stornierungs- Tickets verfolgen, damit ich einen Hook-Handler pre_item_add registrieren kann . Sie können Parameter an den Handler übergeben. Dies erfolgt über ein assoziatives Array, wobei der Schlüssel das Objekt der gewünschten Entität (in meinem Fall Ticket) und der Wert der Name der Handlerfunktion ist.
: PluginYourpluginnameConfig, config.class.php. inc ( , , , , — — , - ).
.
In meinem Fall sehen die beiden erforderlichen Funktionen der Datei setup.php daher folgendermaßen aus:
/**
* Init hooks of the plugin.
* REQUIRED
*
* @return void
*/
function plugin_init_advtickets() {
global $PLUGIN_HOOKS;
Plugin::registerClass(PluginAdvticketsEvent::class);
$PLUGIN_HOOKS['csrf_compliant']['advtickets'] = true;
$PLUGIN_HOOKS['pre_item_add']['advtickets'] = [
Ticket::class => 'plugin_advtickets_pre_item_add'
];
}
/**
* Get the name and the version of the plugin
* REQUIRED
*
* @return array
*/
function plugin_version_advtickets() {
return [
'name' => 'Adv Tickets',
'version' => PLUGIN_ADVTICKETS_VERSION,
'author' => 'Roman Gonyukov',
'license' => '',
'homepage' => 'https://github.com/stayfuneral/advtickets',
'requirements' => [
'glpi' => [
'min' => '9.2',
]
]
];
}
Die Dokumentation besagt, dass es möglich ist, statische Methoden von Klassen als Handler zu registrieren. In diesem Fall sollten sie so aussehen (es ist übrigens überhaupt nicht erforderlich, Parameter an den Handler zu übergeben):
/* */
//call a function
$PLUGIN_HOOKS['hook_name']['plugin_name'] = 'function_name';
//call a static method from an object
$PLUGIN_HOOKS['other_hook']['plugin_name'] = ['ObjectName', 'methodName'];
Die Handlerfunktionen selbst werden in der Datei hook.php gespeichert. Dort sind auch die Funktionen zum Installieren und Deinstallieren des Plugins gespeichert. Die Funktionsnamen haben die gleichen Anforderungen - plugin_yourpluginname_function_name.
Übrigens habe ich versucht, eine statische Methode zu registrieren, um den Hook zu behandeln und das Ticket-Objekt an die Parameter zu übergeben, aber aus irgendeinem Grund hat nichts für mich funktioniert. Aber mit der üblichen Funktion hat alles geklappt. Um hook.php nicht mit unnötigem Code zu verunreinigen, habe ich eine Klasse registriert, die eine Hook-Handler-Methode enthält, und in der erforderlichen Funktion habe ich einfach diese Methode aufgerufen:
// hook.php
/**
* @param Ticket $ticket
*
* @return bool
*/
function plugin_advtickets_pre_item_add(Ticket $ticket)
{
return PluginAdvticketsEvent::pre_item_add_ticket($ticket);
}
Wenn Sie Tabellen in einer Datenbank installieren müssen, enthält die offizielle Dokumentation einen separaten Absatz zu diesem Thema. Ich brauchte die Tische nicht, also überspringe ich diesen Moment.
Nun, wir haben die Installation / Entfernung des Plugins herausgefunden, Hook-Handler registriert und aufgerufen. Jetzt ist es Zeit herauszufinden, wie wir die neue Anfrage verarbeiten werden.
Zu diesem Zweck habe ich, wie oben erwähnt, die PluginAdvticketsEvent- Klasse (Datei inc / event.php) registriert, die eine einzelne pre_item_add_ticket- Methode enthält .
class PluginAdvticketsEvent extends CommonDBTM
{
static function pre_item_add_ticket(Ticket $ticket)
{
global $DB;
// .. , input
$fields = $ticket->input;
// , ( )
if($fields['_link']['tickets_id_2']) {
$relatedTicketId = $fields['_link']['tickets_id_2'];
$relatedTicketParamsForUpdate = [
'itemtype' => \Ticket::class, // ,
'items_id' => $relatedTicketId, // id
'users_id' => $fields['_users_id_requester'], // id
'users_id_editor' => 0,
'content' => $fields['content'],
'date' => date('c'),
'date_mod' => date('c'),
'date_creation' => date('c'),
'is_private' => 0,
'requesttypes_id' => $fields['requesttypes_id'], // (helpdesk, email ..)
'timeline_position' => 4,
'sourceitems_id' => 0,
'sourceof_items_id' => 0
];
// ( , ), . , glpi_itilfollowups
$DB->insert('glpi_itilfollowups', $relatedTicketParamsForUpdate);
// , "". glpi_tickets
$DB->update('glpi_tickets', [
'status' => 1
], [
'id' => $relatedTicketId
]);
// .. , input false. .
$ticket->input = false;
return $ticket->input;
}
}
}
Das ist alles. Vielen Dank für Ihre Aufmerksamkeit. Quellcode, wie immer auf Github .
Nützliche Links: Offizielle
GLPI-Website
Offizielle Foren
Telegramm-Chat
Beispiel-Plugin
Dokumentation für
APIDoc- Entwickler
Dokumentation zum Erstellen von Plugins
Artikel zum Erstellen von GLPI-Plugins