[SOLVED] Modul(e) hinzufügen (Beispiel: Artikeltyp ändern)

Hilfe zu Znuny Problemen aller Art
Locked
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

[SOLVED] Modul(e) hinzufügen (Beispiel: Artikeltyp ändern)

Post by nd0 »

Ausgegliedert aus Thread: viewtopic.php?f=34&t=30761&p=128312#p128312
nd0 wrote:Tjaaa ... also das Buch "PERL 5 FÜR DUMMIES" hat mich nicht sonderlich weitergebracht. Da wo es für mich interessant wird hört das Buch nämlich auf (muss leider auch dazu sagen ist eine Ausgabe von 1996 :shock: )


Hab mich dann weitergehend mal mit dem Developer Guide für OTRS 4 auseinandergesetzt und bin schon am Hinzufügen des HelloWorld-Moduls gescheitert ... https://otrs.github.io/doc/manual/devel ... -otrs.html

/e: Achja, und steh ich wieder auf dem Schlauch oder warum werden in deinem Script die beiden Abfragen (jeweils) zwei mal durchgeführt?
RStraub wrote:

Code: Select all

return unless ($Ticket{DynamicField_ProcessManagementProcessID} &&
                        $Ticket{DynamicField_ProcessManagementProcessID} eq 'Process-223afb371193757faff0785e76ea2e94');
    return unless ($Ticket{DynamicField_ProcessManagementActivityID} &&
                        $Ticket{DynamicField_ProcessManagementActivityID} eq 'Activity-72cff829a2da4933ca7cfe15159ed509');
RStraub wrote:Wo scheiterst du denn ?

Die Abfragen führ ich nicht zweimal durch, der Teil vor dem "&&" prüft ob die Variable überhaupt da ist (!= NULL), da sonst unschöne Fehler geworfen werden wenn ich versuche NULL mit einem String zu vergleichen.
nd0 wrote:Au - ja ich stand wieder auf dem Schlauch ;-) Jetzt wo du's sagst: Logisch!

Also, ich scheitere im Grunde schon am Anfang:
First of all we must build the directory /Hello World for the module in the developer directory. In this directory, all directories existent in OTRS can be created. Each module should at least contain the following directories:
Wo befindet sich denn das "developer directory"? :? Ich bin dann mal davon ausgegangen, dass damit der Ordner "Custom" in "/opt/otrs/" gemeint war. Dort habe ich dann die folgende Struktur angelegt:

Kernel/
Kernel/Config
Kernel/Config/Files
Kernel/Language
Kernel/Modules
Kernel/Output
Kernel/Output/HTML
Kernel/Output/HTML/Standard
Kernel/System

Innerhalb dieser Struktur habe ich dann wie im Developer Manual beschrieben alle Dateien zum HelloWorld-Modul erstellt ... danach RebuildConfig, DeleteCache und natürlich vorher die Permissions angepasst (Dateien wurden von mir in WinSCP erstellt) ... es tut sich nichts :/

/e: In "/opt/otrs/Custom/Kernel/Modules" befinden sich auch schon eine pm-Dateien die ich während diverser Anpassungen dort abgelegt habe ... DAS funktioniert ja wiederum alles :(
RStraub wrote:Könntest du dazu einen eigenen Thread aufmachen? Möchte den hier ungern hijacken.

Das mit dem Custom Ordner ist schonmal ganz richtig, nur OTRS scannt einige bestimmte Ordner nicht ab. Dazu gehört u.a. auch ~otrs/Kernel/Config/Files.

D.h. deine ganzen .xml Dateien zur Registrierung des Moduls müssen in den Original-Pfad rein. Danach sollte (bis auf ggf. die Übersetzung) das Modul sichtbar sein.

Cache Rebuild ist nicht unbedingt nötigt, es reicht meistens wenn du nach einer Anpassung der .xml in der Weboberfläche nur die SysConfig aufrufst - dann wird alles neu eingelesen (falls fehlerfrei).
#############################################################

Gesagt - Getan. (+danke für die Info bzgl. Aufruf der SysConfig!)

Also:
Die "HelloWorld.xml" habe ich jetzt in den "Originalpfad" (/opt/otrs/Kernel/Config/Files) gelegt und sofort erscheint der Button oben in Navigationsleiste... sieht wenn man drauf klickt jetzt (natürlich?) so aus:
hw.png
Wurde das Modul hiermit "erfolgreich" erstellt, oder müssen andere Dateien auch noch an anderer Stelle platziert werden?!
You do not have the required permissions to view the files attached to this post.
Last edited by nd0 on 02 Mar 2016, 14:30, edited 1 time in total.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Ich würde sagen das war erfolgreich.

Jetzt kannst du langsam anfangen mit:

Im Perl-Modul ein Ticket auslesen (z.B. erstmal mit einer fixen ID) und den Titel ausgeben.

Der nächste Schritt könnte sein eine Maske darzustellen die dann dynamisch Werte abfragt.

Aber ich denke du möchtest eh nur den internen Artikel Typ anpassen :)
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Juhu. ;-) Habe gestern noch ein bisschen rumprobiert, aber dabei ist nichts mehr rumgekommen. Heute morgen habe ich dann versucht das Ganze von Grund auf nachzuvollziehen ... im Zuge dessen habe ich das "HelloWorld"-Modul umbenannt in "HalloWelt" (inklusive aller erforderlichen Anpassungen).

Danach habe ich dann nochmal versucht Ticket Informationen auszulesen ... was nicht geklappt hat.

Lese ich die Ticket Informationen in der (...)/System/HalloWelt.pm aus oder in der (...)/Modules/HalloWelt.pm?

Wie lese ich die Informationen überhaupt aus? :? Während ich danach gegoogled habe bin ich auf folgende Seite gestoßen:
https://otrs.github.io/doc/api/otrs/4.0 ... et.pm.html

Das sieht schonmal aus als würde das in die richtige Richtung gehen .. nur verstehe ich eben den Zusammenhang zwischen (...)/System/HalloWelt.pm, (...)/Modules/HalloWelt.pm und (...)/Output/HTML/Standard/HalloWelt.tt noch nicht...

Magst mich nochmal ein bisschen in die richtige Richtung schubsen?
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Huhu,

ich würd zum loslegen das Modul aus /System rauswerfen und erstmal nur an einem Modul (~otrs/Custom/Kernel/Modules/) basteln.

Meistens reicht das schon, außer du willst modulare / wiederverwendbare Funktionen. Grundsätzlich gibt es auch keinen Unterschied in der funktionsweiße, das ist eher eine Entscheidung der Architektur --> Die "Core" Funktionen (wie TicketGet) die oft gebraucht werden liegen zentral unter System, die spezifizischen Funktionen (z.B. AddNote) liegen dann unter /Modules.

Such dir im Webfrontend mal ein Ticket raus und ließ aus der URL die TicketID. Dann schreib in dein /Modules/HalloWelt.pm folgendes:

Code: Select all

my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');

my %Ticket = $TicketObject->TicketGet(
        TicketID      => 123, # (Ersetzen mit deiner TicketID),
        UserID        => 1, # oder Deiner UserID
);
Wenn du nun Daten von dem .pm an das .tt übergeben willst, gibt es dafür zwei Möglichkeiten die OTRS nutzt:
- Entweder globale Attribute, die werden übergeben sobald das Template aufgerufen wird, also in diesem Teil:

Code: Select all

    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'AgentHelloWorld',
    );
- Oder dynamisch per Block (wenn etwa Listen erstellt werden), das sähe dann so aus:

Code: Select all

        $Self->{LayoutObject}->Block(
            Name => 'CustomerRow',
            Data => $Data,
        );
Diese Blöcke kannst du dir ganz grob wie Scopes oder Subfunktionen vorstellen. Pro Block wird im Template (und damit im endgültigen HTML Code) ein Fragment ausgegeben dass nur lokal die Informationen aus dem $Data Hash "kennt".

Um jetzt einzusteigen schreib mal eine Ticketinformation in diesen $Data Hash:

Code: Select all

$Data{MeinTicketTitel} = $Ticket{Title};
Und im .tt kannst du dies auslesen via:

Code: Select all

[% Data.MeinTicketTitel | html %]
der Teil "| html" ist nicht unbedingt nötigt, kodiert aber Werte auf HTML um, falls etwa Sonderzeichen oder HTML Tags in der Variable stehen würden.

Frohes basteln :)
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Hmmm :lol:

Ziemlich genau so hab ich das sogar probiert gestern/heute außer das ich die UserID weggelassen habe und nur die TicketID angegeben habe.

Also, ich habe jetzt die (...)/System/HalloWelt.pm gelöscht.

In (...)/Modules/HalloWelt.pm steht jetzt folgendes:

Code: Select all

package Kernel::Modules::HalloWelt;

use strict;
use warnings;

use Kernel::System::HalloWelt;

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless ($Self, $Type);

    # check needed objects
    for (qw(ParamObject DBObject TicketObject LayoutObject LogObject QueueObject ConfigObject EncodeObject MainObject)) {
        if ( !$Self->{$_} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $_!" );
        }
    }

    # create needed objects
    $Self->{HelloWorldObject} = Kernel::System::HalloWelt->new(%Param);

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;
    my %Data = ();
    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');

    my %Ticket = $TicketObject->TicketGet(					###
      TicketID      => 592, # (Ersetzen mit deiner TicketID),		###
      UserID        => 1, # oder Deiner UserID					###
    );												###

    $Data{HelloWorldText} = $Self->{HelloWorldObject}->GetHelloWorldText();
    
    $Data{MeinTicketTitel} = $Ticket{Title};					####

    # build output
    my $Output = $Self->{LayoutObject}->Header(Title => "HalloWelt");
    $Output   .= $Self->{LayoutObject}->NavigationBar();
    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'HalloWelt',
    );

    $Output   .= $Self->{LayoutObject}->Footer();
    return $Output;
}

1;
(Deine Snippets sind mit "###" gekennzeichnet)

In der HalloWelt.tt steht jetzt folgendes:

Code: Select all

<h1>[% Translate("Overview") | html %]: [% Translate("Hallo Welt") %]</h1>
<p>
    [% Data.HelloWorldText | Translate() | html %]
</p>
<p>
    [% Data.MeinTicketTitel | html %]						###
</p>
(Deine Snippets sind mit "###" gekennzeichnet)

Wenn ich das Modul dann anschließend aufrufe wird im zweiten "p-Tag" nichts ausgegeben außer einer Leerstelle (edit: ... ne ist mehr als nur EINE Leerstelle :-D). Ich muss aber auch zugeben, einen kleinen Teil deiner Hilfestellung habe ich nicht verstanden:
RStraub wrote: Um jetzt einzusteigen schreib mal eine Ticketinformation in diesen $Data Hash:


Wie wo was muss ich da jetzt reinschreiben? ^^ Ich dachte dadurch liest er den Title des Tickets aus?!
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Dieser Teil müsste dann auch raus:

Code: Select all

    $Data{HelloWorldText} = $Self->{HelloWorldObject}->GetHelloWorldText();
da du ja dann das andere Modul gelöscht hast.

ah, und dieser Block im new auch:

Code: Select all

    # create needed objects
    $Self->{HelloWorldObject} = Kernel::System::HalloWelt->new(%Param);
Anonsten sieht's so aus als ob es funktionieren sollte. Probier's mal hardcodiert mit:

Code: Select all

$Data{Test} = "Erdbeerkuchen";
und im .tt mit:

Code: Select all

<p>
    Mein Lieblingskuchen ist: [% Data.Test %]
</p>
Häng dich auch mal während einem Aufruf des Moduls an den Apache Log, der spuckt immer ziemlich viel aus falls es Fehler gibt:

Code: Select all

(als root, oder per sudo)
tail -f /var	/log/apache2/error.log
Deine letzte Frage verstehe ich nicht ganz. Die Informationen werden so gesammelt:
1) Im .pm holst du dir das TicketObject
2) Dann holst du die Ticketinformationen über TicketGet in die Variable %Ticket
3) Dann schreibst du einen Wert aus %Ticket in %Data
4) %Data wird dem Template übergeben
5) TemplateToolkit parst den String "[% Data.MeinTicketTitel %] und ersetzt ihn mit dem Wert der in $Data{MeinTicketTitel} steht.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

OMG! Kommando zurück - es klappt...

WinSCP hat irgendwie die Verbindung verloren (ich öffne die pm-Datei aus WinSCP mit Rechtsklick -> Öffnen mit PSPad) wodurch dann trotz "STRG + S" in PSPad die Datei auf dem Server sich nicht aktualisiert hat.

Also. KLAPPT! xD

Auch mit etlichen anderen Attributen ... cool - danke - dann lag das scheinbar echt daran, das ich bei meinem Versuch die UserID nicht mit angegeben habe. Die Auflistung ganz unten in deinem Post ist trotzdem super. Vielen Dank, dann hab ich doch alles richtig verstanden. Apache Log läuft in KiTTY die ganze Zeit mit ;-) Danke!

Super, so weit so gut... um jetzt letztenendes aber meinen Wunsch (aus dem anderen Thread) umzusetzen muss ich ja in die Article reinschauen ...
Wie bastel ich denn jetzt zum Beispiel eine Abfrage ob der neueste/letzte hinzugefügte Article "email-external" oder "note-external" ist?

/e: Die von dir genannten Zeilen hab ich jetzt noch schnell entfernt - hat aber auch vorher geklappt ;-)
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Gratz :)

Um alle Artikel-IDs eines Tickets zu bekommen:

Code: Select all

my @ArticleIDs = $TicketObject->ArticleIndex(
        TicketID => 123,
);
Um den letzten davon auszulesen:

Code: Select all

my $LastArticleID = $ArticleIDs[$#ArticleIDs];
Und dann könntest du mit ArticleGet und ArticleUpdate versuchen den Typ zu ändern:
https://otrs.github.io/doc/api/otrs/sta ... le.pm.html
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Hehe 8)

Hinzugefügt in HalloWelt.pm:

Code: Select all

    my @ArticleIDs = $TicketObject->ArticleIndex(
      TicketID => 592,
    );
    
    my $LastArticleID = $ArticleIDs[$#ArticleIDs];
    
    $Data{MeineArtikelListe} = $LastArticleID;
    
    my %Article = $TicketObject->ArticleGet(
      ArticleID     => $LastArticleID,
      UserID        => 1,
    );
    
    $Data{MeinArtikelTyp} = $Article{ArticleType};
 
HalloWelt.tt:

Code: Select all

<h1>[% Translate("Overview") | html %]: [% Translate("Hallo Welt") %]</h1>
<br>
<p>
Betreff des Tickets: [% Data.MeinTicketTitel | html %]
</p>
<br>
<p>
ID des letzten Artikels: [% Data.MeineArtikelListe | html %]
</p>
<p>
Typ des Artikels: [% Data.MeinArtikelTyp | html %]
</p>
Resultat:
hw2.png
######

Jetzt sagst du "versuchen den Typ zu ändern" ... DAS wiederrum möchte ich ja nur per "Knopf-Druck" realisieren. Wie baue ich jetzt in die HalloWelt.tt einen Button/Link ein, der die Daten wieder an das Modul übergibt?

(Nochmal zur Erinnerung: Später soll es ja so sein, dass dieser Button/Link nur DANN auftaucht (im TicketZoom -> Artikel Optionen) wenn es sich wirklich um einen entsprechenden (externen) Artikel handelt, denn nur dann soll ja schließlich möglich sein den Typ zu ändern auf INTERN ... aber alles zu seiner Zeit ;-))
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Okay, das ist dann der nächste Schritt, du möchtest also vom Template (.tt) das Modul (.pm) ansprechen und dort eine andere Ausgabe erzeugen.

Dazu brauchst du im Template eine "Form", die dann an das Modul übergeben wird, etwa:

Code: Select all

<form action="[% Env("CGIHandle") %]" method="post" enctype="multipart/form-data" name="compose" id="Compose" class="Validate PreventMultipleSubmits">
    <input type="hidden" name="Action" value="HalloWelt"/>
    <input type="hidden" name="Subaction" value="Update" id="UpdateArticleType"/>
    
</form>
<div class="Center SpacingTop">
    <button class="Primaray CallForAction" type="submit" id="" action=""  name="" value="[% Translate("Submit") | html %]"><span><i class="icon-check"></i> [% Translate("Submit") | html %]</span></button>
Bei Klick auf den Button wird dann Action "HalloWelt" aufgerufen mit der Subaction "UpdateArticleType". Diese kannst du im Modul auslesen. Es werden übrigens alle Felder übergeben, aber nur diese zwei direkt in Parameter geparst. Dazu später mehr (du willst ja etwa die Artikel ID übergeben).

Im Perl Modul kannst du diese Parameter auslesen und entscheiden was zu tun ist. Bei mir sieht die sub Run meist so aus:

Code: Select all

sub Run {
    my ($Self, %Param) = @_;
    if ($Self->{Subaction} eq 'UpdateArticleType') {
        _UpdateArticleType($Self);
    } else {
        _MainRoutine($Self);
    }
}
OTRS dagegen schreibt meist alles in die Run und entscheidet spaltet sich dann in riesige if-else Blöcke auf. Welchen Weg auch immer du gehen magst, anhand dieser unterschiedlichen Subroutinen kannst du dann den Output ändern oder eben den Artikeltyp ändern.

Zum starten würde ich dir empfehlen wieder einfach anzufangen. Erstell dir ein sichtbares Inputfenster innerhalb der Form:

Code: Select all

    <input name="MyTextField" value="Erdbeerkuchen"/>
Im Modul kannst du diesen dann auslesen (da wie gesagt nur Action und Subaction automatisch in $Self gepackt werden):

Code: Select all

my $Text = $Self->{ParamObject}->GetParam( Param => 'MyTextField');
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Hui .. also:

In der Template-Datei habe ich jetzt (unterhalb meiner vorherigen Tests) folgendes eingefügt:

Code: Select all

<form action="[% Env("CGIHandle") %]" method="post" enctype="multipart/form-data" name="compose" id="Compose" class="Validate PreventMultipleSubmits">
# <input type="hidden" name="Action" value="HalloWelt"/>
# <input type="hidden" name="Subaction" value="Update" id="UpdateArticleType"/>
<input name="MyTextField" value="Kaesekuchen"/>
</form>
<button class="Primary CallForAction" type="submit" id="" action=""  name="" value="[% Translate("Submit") | html %]"><span><i class="icon-check"></i> [% Translate("Submit") | html %]</span></button>
<p>Test: [% Data.Test %]</p>
Info: Die Button Klasse hieß bei dir "Primaray CallForAction" ... das hab ich mal korrigiert :-D


Die sub Run (im Perl-Modul) sieht jetzt so aus:

Code: Select all

sub Run {
    my ( $Self, %Param ) = @_;
    
    #if ($Self->{Subaction} eq 'UpdateArticleType') {
    #    _UpdateArticleType($Self);
    #} else {
    #    _MainRoutine($Self);
    #}    
    
    my $Text = $Self->{ParamObject}->GetParam( Param => 'MyTextField');
    
    
    
    my %Data = ();
    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');

    my %Ticket = $TicketObject->TicketGet(
      TicketID      => 592, # (Ersetzen mit deiner TicketID),
      UserID        => 1, # oder Deiner UserID
    );
        
    $Data{MeinTicketTitel} = $Ticket{Title};
    $Data{MeineTicketNr} = $Ticket{TicketNumber};
    
    my @ArticleIDs = $TicketObject->ArticleIndex(
      TicketID => 592,
    );
    
    my $LastArticleID = $ArticleIDs[$#ArticleIDs];
    
    $Data{MeineArtikelListe} = $LastArticleID;
    
    my %Article = $TicketObject->ArticleGet(
      ArticleID     => $LastArticleID,
      UserID        => 1,
    );
    
    $Data{MeinArtikelTyp} = $Article{ArticleType};
    
    $Data{MeinArtikelBetreff} = $Article{Subject};
    
    $Data{MeinArtikelInhalt} = $Article{Body};

    $Data{Test} = $Text;
    
    # build output
    my $Output = $Self->{LayoutObject}->Header(Title => "HalloWelt");
    $Output   .= $Self->{LayoutObject}->NavigationBar();
    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'HalloWelt',
    );

    $Output   .= $Self->{LayoutObject}->Footer();
    return $Output;
}
... sieht dann jetzt so aus:
hw3.png
... leider passiert beim Klick auf den Button nichts :?

Was habe ich übersehen bzw. nicht verstanden?
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Diese Zeilen sind wichtig:
# <input type="hidden" name="Action" value="HalloWelt"/>
# <input type="hidden" name="Subaction" value="Update" id="UpdateArticleType"/>
Insbesondere die Action, sonst passiert einfach gar nix. Probier's nochmal wenn sie nicht kommentiert sind.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Puh ... also als erstes hab ich (wie du sagtest) die folgenden Zeilen (im Template) wieder "entkommentiert":

Code: Select all

<input type="hidden" name="Action" value="HalloWelt"/>
<input type="hidden" name="Subaction" value="Update" id="UpdateArticleType"/>
Beim Klick auf den Button tat sich danach allerdings immernoch nichts.

Dann habe ich die folgenden Zeilen (im Perl-Modul) auch wieder "entkommentiert":

Code: Select all

if ($Self->{Subaction} eq 'UpdateArticleType') {
    _UpdateArticleType($Self);
} else {
    _MainRoutine($Self);
}  
Das verursachte folgende Fehlermeldung im Apache Log:
HalloWelt.pm: Subroutine new redefined at /opt/otrs/Custom/Kernel/Modules/HalloWelt.pm line 17.
HalloWelt.pm: Subroutine Run redefined at /opt/otrs/Custom/Kernel/Modules/HalloWelt.pm line 34.
[error] Undefined subroutine &Kernel::Modules::HalloWelt::_MainRoutine called at /opt/otrs/Custom/Kernel/Modules/HalloWelt.pm line 40.\n
#####

Ich bin ratlos :?

Mir ist allerdings aufgefallen, dass der Button im Template keine Action aufruft/ausführt?! Ist das korrekt?
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
reneeb
Znuny guru
Posts: 5018
Joined: 13 Mar 2011, 09:54
Znuny Version: 6.0.x
Real Name: Renée Bäcker
Company: Perl-Services.de
Contact:

Re: Erweiterung: Modul(e) hinzufügen

Post by reneeb »

Hast Du die Angabe bei "package" auch auf HalloWelt geändert?
Perl / Znuny development: http://perl-services.de
Free Znuny add ons from the community: http://opar.perl-services.de
Commercial add ons: http://feature-addons.de
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

In der (...)/Kernel/Modules? Jop:

Code: Select all

package Kernel::Modules::HalloWelt;

use strict;
use warnings;

#use Kernel::System::HalloWelt;
so sehen die ersten vier Zeilen vor der "sub new" aus ...
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
reneeb
Znuny guru
Posts: 5018
Joined: 13 Mar 2011, 09:54
Znuny Version: 6.0.x
Real Name: Renée Bäcker
Company: Perl-Services.de
Contact:

Re: Erweiterung: Modul(e) hinzufügen

Post by reneeb »

Hast Du denn eine sub mit dem Namen _MainRoutine?
Perl / Znuny development: http://perl-services.de
Free Znuny add ons from the community: http://opar.perl-services.de
Commercial add ons: http://feature-addons.de
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Taaataaam ... das könnt es doch schon sein :?

Code: Select all

# --
# Kernel/Modules/AgentHelloWorld.pm - frontend module
# Copyright (C) (year) (name of author) (email of author)
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::Modules::HalloWelt;

use strict;
use warnings;

#use Kernel::System::HalloWelt;

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless ($Self, $Type);

    # check needed objects
    for (qw(ParamObject DBObject TicketObject LayoutObject LogObject QueueObject ConfigObject EncodeObject MainObject)) {
        if ( !$Self->{$_} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $_!" );
        }
    }

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;
    
    my $Text = $Self->{ParamObject}->GetParam( Param => 'MyTextField');
    
    if ($Self->{Subaction} eq 'UpdateArticleType') {
        _UpdateArticleType($Self);
    } else {
        _MainRoutine($Self);
    }    
    
    
    
    
    
    my %Data = ();
    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');

    my %Ticket = $TicketObject->TicketGet(
      TicketID      => 592, # (Ersetzen mit deiner TicketID),
      UserID        => 1, # oder Deiner UserID
    );
        
    $Data{MeinTicketTitel} = $Ticket{Title};
    $Data{MeineTicketNr} = $Ticket{TicketNumber};
    
    my @ArticleIDs = $TicketObject->ArticleIndex(
      TicketID => 592,
    );
    
    my $LastArticleID = $ArticleIDs[$#ArticleIDs];
    
    $Data{MeineArtikelListe} = $LastArticleID;
    
    my %Article = $TicketObject->ArticleGet(
      ArticleID     => $LastArticleID,
      UserID        => 1,
    );
    
    $Data{MeinArtikelTyp} = $Article{ArticleType};
    
    $Data{MeinArtikelBetreff} = $Article{Subject};
    
    $Data{MeinArtikelInhalt} = $Article{Body};

    $Data{Test} = $Text;
    
    # build output
    my $Output = $Self->{LayoutObject}->Header(Title => "HalloWelt");
    $Output   .= $Self->{LayoutObject}->NavigationBar();
    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'HalloWelt',
    );

    $Output   .= $Self->{LayoutObject}->Footer();
    return $Output;
}

1;
Das ist meine (...)/Modules/HalloWelt.pm in komplett...
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
reneeb
Znuny guru
Posts: 5018
Joined: 13 Mar 2011, 09:54
Znuny Version: 6.0.x
Real Name: Renée Bäcker
Company: Perl-Services.de
Contact:

Re: Erweiterung: Modul(e) hinzufügen

Post by reneeb »

Jepp, Du musst noch die entsprechenden Subroutinen schreiben.

Übrigens schreibt man nicht

Code: Select all

_MainRoutine( $Self )
sondern [/code]$Self->_MainRoutine()[/code].
Perl / Znuny development: http://perl-services.de
Free Znuny add ons from the community: http://opar.perl-services.de
Commercial add ons: http://feature-addons.de
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

/e: Alter Beitrag gelöscht.

Dank der Hilfe eines Kollegen klappt es jetzt nämlich endlich :-D

HalloWelt.pm:

Code: Select all

package Kernel::Modules::HalloWelt;

use strict;
use warnings;

#use Kernel::System::HalloWelt;

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless ($Self, $Type);

    # check needed objects
    for (qw(ParamObject DBObject TicketObject LayoutObject LogObject QueueObject ConfigObject EncodeObject MainObject)) {
        if ( !$Self->{$_} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $_!" );
        }
    }

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;
      
    my %Data = ();
    
    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');

    my %Ticket = $TicketObject->TicketGet(
      TicketID      => 592, # (Ersetzen mit deiner TicketID),
      UserID        => 1, # oder Deiner UserID
    );
            
    $Data{MeinTicketTitel} = $Ticket{Title};
    $Data{MeineTicketNr} = $Ticket{TicketNumber};
    
    my @ArticleIDs = $TicketObject->ArticleIndex(
      TicketID => 592,
    );
    
    my $LastArticleID = $ArticleIDs[$#ArticleIDs];
    
    $Data{MeineArtikelListe} = $LastArticleID;
    
    my %Article = $TicketObject->ArticleGet(
      ArticleID     => $LastArticleID,
      UserID        => 1,
    );
    
    $Data{MeinArtikelTyp} = $Article{ArticleType};
    
    $Data{MeinArtikelBetreff} = $Article{Subject};
    
    $Data{MeinArtikelInhalt} = $Article{Body};
    $Data{Test} = $Self->{ParamObject}->GetParam( Param => 'MyTextField');
    
    # build output
    my $Output = $Self->{LayoutObject}->Header(Title => "HalloWelt");
    $Output   .= $Self->{LayoutObject}->NavigationBar();
    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'HalloWelt',
    );

    $Output   .= $Self->{LayoutObject}->Footer();
    return $Output;
}

1;
HalloWelt.tt:

Code: Select all

<div class="MainBox">
<h1>[% Translate("Overview") | html %]: [% Translate("Hallo Welt") %]</h1>
<br>
<p>
Betreff des Tickets: [% Data.MeinTicketTitel | html %]
</p>
<p>
Ticketnummer: [% Data.MeineTicketNr | html %]
</p>
<br>
<p>
ID des letzten Artikels: [% Data.MeineArtikelListe | html %]
</p>
<p>
Typ des Artikels: [% Data.MeinArtikelTyp | html %]
</p>
<p>
Titel des Artikels: [% Data.MeinArtikelBetreff | html %]
</p>
<p>
Inhalt des Artikels: [% Data.MeinArtikelInhalt | html %]
</p>
<form action="[% Env("CGIHandle") %]" method="post" enctype="multipart/form-data" name="compose" id="Compose" class="Validate PreventMultipleSubmits">
  <input type="hidden" name="Action" value="HalloWelt"/>
  <input type="hidden" name="Subaction" value="Update" id="MainRoutine"/>
  <input name="MyTextField" value="Kaesekuchen"/>
<button class="Primary CallForAction" type="submit" id="" action=""  name="" value="[% Translate("Submit") | html %]"><span><i class="icon-check"></i> [% Translate("Submit") | html %]</span></button>
</form>
<p>Test: [% Data.Test | html %]</p>
</div>
Nach einem Klick auf den Button wird in der letzten Zeile (hinter "Test: ") der String "Kaesekuchen" ausgegeben.

Wie ihr aber bemerken dürftet haben wir den Block mit der IF-Abfrage und die sub "_MainRoutine" gekillt ... :?
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Aaaaaaalso, ich bin jetzt schon ein ganzes Stück weiter gekommen:
hw4.png
Mittlerweile ändert sich der Artikeltyp des (hinterlegten) Tickets wenn ich auf "HalloWelt" klicke 8)

HalloWelt.pm:

Code: Select all

package Kernel::Modules::HalloWelt;

use strict;
use warnings;

use DBI;

#use Kernel::System::HalloWelt;
    
sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless ($Self, $Type);

    # check needed objects
    for (qw(ParamObject DBObject TicketObject LayoutObject LogObject QueueObject ConfigObject EncodeObject MainObject)) {
        if ( !$Self->{$_} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $_!" );
        }
    }

    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;
      
    my %Data = ();
    
    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
    
    my $MeineTicketID = 592;
    
    my %Ticket = $TicketObject->TicketGet(
      TicketID      => $MeineTicketID,
      UserID        => 1,
    );
            
    $Data{MeinTicketTitel} = $Ticket{Title};
    $Data{MeineTicketNr} = $Ticket{TicketNumber};
    
    my @ArticleIDs = $TicketObject->ArticleIndex(
      TicketID => $MeineTicketID,
    );  
    
    $Data{ArtikelAnzahl} = @ArticleIDs;  
    
    my $LastArticleID = $ArticleIDs[$#ArticleIDs];
    
    $Data{LetzterArtikel} = $LastArticleID;
    
    my %Article = $TicketObject->ArticleGet(
      ArticleID     => $LastArticleID,
      UserID        => 1,
    );
    
    $Data{LetzterArtikelTyp} = $Article{ArticleType};
    
    if ($Article{ArticleType} eq 'note-external'){
        $Data{Vorher} = "externe Notiz";
        $Data{Nachher} = "interne Notiz";
    } elsif ($Article{ArticleType} eq 'note-internal'){
        $Data{Vorher} = "interne Notiz";
        $Data{Nachher} = "externe Notiz";
    } elsif ($Article{ArticleType} eq 'email-external'){
        $Data{Vorher} = "externe E-Mail";  
        $Data{Nachher} = "interne E-Mail";
    } elsif ($Article{ArticleType} eq 'email-internal'){
        $Data{Vorher} = "interne E-Mail";
        $Data{Nachher} = "externe E-Mail";
    } else {
        $Data{Vorher} = "";
        $Data{Nachher} = "";
    }
    
    $Data{MeinArtikelBetreff} = $Article{Subject};
    
    $Data{MeinArtikelInhalt} = $Article{Body};
    $Data{Uebergabe} = $Self->{ParamObject}->GetParam( Param => 'MyTextField');
    
    my $dbh;
    my $sth;
    
    $dbh = DBI->connect('DBI:mysql:otrsdb', 'otrsuser', 'WV9#Hy/8d9rqHWM=')
            || die "Could not connect to database: $DBI::errstr";
    
    if ($Article{ArticleType} eq 'note-external') {      # note-external?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=9 WHERE id=?");
    } elsif ($Article{ArticleType} eq 'note-internal') {  # note-internal?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=10 WHERE id=?");    
    } elsif ($Article{ArticleType} eq 'email-external') {  # email-external?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=2 WHERE id=?");  
    } elsif ($Article{ArticleType} eq 'email-internal') {  # email-internal?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=1 WHERE id=?");
    } else {
      $sth = "";
    }
    
    if ($sth eq ""){
      ######            
    } else {
      $sth->execute($LastArticleID);
    }
    
    $dbh->disconnect();
    
    # build output
    my $Output = $Self->{LayoutObject}->Header(Title => "HalloWelt");
    $Output   .= $Self->{LayoutObject}->NavigationBar();
    $Output   .= $Self->{LayoutObject}->Output(
        Data => \%Data,
        TemplateFile => 'HalloWelt',
    );

    $Output   .= $Self->{LayoutObject}->Footer();
    return $Output;
}

1;

HalloWelt.tt:

Code: Select all

<div class="MainBox">
<h1>[% Translate("Modul") | html %]: [% Translate("Hallo Welt") %]</h1>
<br>
<p>
[STC#[% Data.MeineTicketNr | html %]] - [% Data.MeinTicketTitel | html %] 
</p>
<br>
<p>
Anzahl Artikel: [% Data.ArtikelAnzahl | html %]
</p>
<p>
ID neuester Artikel: [% Data.LetzterArtikel | html %]
</p>
<p>
Typ neuester Artikel: [% Data.LetzterArtikelTyp | html %]
</p>
<br>
<p>Die ist eine <strong>[%Data.Vorher | html %]</strong>.</p>
<br>
<p>
Betreff: [% Data.MeinArtikelBetreff | html %]
</p>
<p>
Inhalt: [% Data.MeinArtikelInhalt | html %]
</p>
<br>
<br>
<p>
**********************************************************************<br>
Artikeltyp erfolgreich geändert von [% Data.Vorher | html %] zu [% Data.Nachher | html %]
</p>
<br>
<br>
<br>
<br>
<br>
<form action="[% Env("CGIHandle") %]" method="post" enctype="multipart/form-data" name="compose" id="Compose" class="Validate PreventMultipleSubmits">
  <input type="hidden" name="Action" value="HalloWelt"/>
  <input type="hidden" name="Subaction" value="Update" id="MainRoutine"/>
  <input name="MyTextField" value=""/>
<button class="Primary CallForAction" type="submit" id="" action=""  name="" value="[% Translate("Submit") | html %]"><span><i class="icon-check"></i> [% Translate("Submit") | html %]</span></button>
</form>
<br>
<p>Übermittelt: [% Data.Uebergabe | html %]</p>
</div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Das Ganze mit dem Button und der Übergabe von "Action" und "Subaction" halte ich irgendwie alles für ein bisschen unnötig mittlerweile, aber warten wir mal ab was ihr dazu sagt. :lol:

Auf dem folgenden Bild seht ihr mein TEST-Ticket ... der Artikel NR. 9 wurde von "Notiz extern" auf "Notiz intern" geändert (siehe Screenshot oben).
hw5.png
Jetzt möchte ich den Link aber nicht mehr in der "Hauptnavigationsleiste" haben, sondern in der div mit der Klasse "LightRow Bottom" in der div mit der ID "ArticleItems":
hw6.png
Wie gehe ich das am schlausten an? Verstehe ich das richtig, dass ich dort dann im Grunde nur einen Link auf "(...)/index.pl?Action=HalloWelt" hinterlegen muss? Außerdem muss ich ja noch irgendwie anpassen, dass das Modul dann auf das Ticket und den Artikel zugreift wo ich mich gerade befinde ... bisher gebe ich ja die TicketID (592) und frage davon den LETZTEN Article ab ... Ab jetzt wäre ein bisschen Hilfestellung wieder super :-) Ich danke euch für eure Geduld und Mühe!
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Huhu :)

Ich hab mal ein Minimalbeispiel (ohne die Funktion des Artikel-Änderns, aber die hast du ja schon) erstellt. Die Dateien dabei sind:
~otrs/Kernel/Config/Files/Z_Otterhub.xml (Name ist egal) mit dem Inhalt:

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<otrs_config version="1.0" init="Framework">
    <ConfigItem Name="Ticket::Frontend::MenuModule###237-ChangeArticleType" Required="0" Valid="1">
        <Description Translatable="1">Shows a link in the menu to change the article type of the last article.</Description>
        <Group>Ticket</Group>
        <SubGroup>Frontend::Agent::Ticket::MenuModule</SubGroup>
        <Setting>
            <Hash>
                <Item Key="Module">Kernel::Output::HTML::TicketMenuGeneric</Item>
                <Item Key="Name">intern - extern</Item>
                <Item Key="Description" Translatable="1">Change last article type</Item>
                <Item Key="Action">ChangeArticleType</Item>
                <Item Key="Link">Action=ChangeArticleType;TicketID=[% Data.TicketID | html %]</Item>
                <Item Key="Target"></Item>
                <Item Key="PopupType">TicketAction</Item>
            </Hash>
        </Setting>
    </ConfigItem>
    <ConfigItem Name="Frontend::Module###ChangeArticleType" Required="0" Valid="1">
        <Description Translatable="1">Frontend module registration for the agent interface.</Description>
        <Group>Otterhub-Dev</Group>
        <SubGroup>Frontend::Agent::ModuleRegistration</SubGroup>
        <Setting>
            <Hash>
                <Item Key="Module">Kernel::Modules::ChangeArticleType</Item>
            </Hash>
        </Setting>
    </ConfigItem>
</otrs_config>
Diese XML registriert ein Modul mit dem Namen "ChangeArticleType" und den Knopf "intern - extern" im Ticket Zoom. Wenn du dein bestehndes Modul nehmen willst, ändere die Pfade entsprechend an.

Die Datei ~otrs/Custom/Kernel/Modules/ChangeArticleType.pm sieht so aus:

Code: Select all

package Kernel::Modules::ChangeArticleType;

use strict;
use warnings;

our $ObjectManagerDisabled = 1;
use Kernel::System::VariableCheck qw(:all);

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {%Param};
    bless( $Self, $Type );

    # check needed objects
    NEEDED:
    for my $Needed (qw(ParamObject DBObject LayoutObject LogObject ConfigObject)) {
        if ( !$Self->{$Needed} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $Needed!" );
        }
    }
    return $Self;
}

sub Run {
    my ( $Self, %Param ) = @_;

    my $Success = 1;
    
    my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
    my $Output = $LayoutObject->Header(Title => "Changing Article Type...");
    if ($Success != 1){
        $Output .= $LayoutObject->Notify(
            Priority => 'Error',
            Info => 'Irgendwas is schiefgegangen.',
        );
        return $Output;
    }

    $Output .= $Self->{LayoutObject}->Notify(
        Priority => 'Warning',
        Info => "Alles okay",
    );
    return $Output;
}

1;
Statt dem Notify kannst du natürlich auch wie gehabt ein Template ausgeben. Aber wie ich dich verstanden habe, genügt es ja den Typ zu ändern.
Die Success Variable kannst du in Abhängigkeit deiner SQL-Query befüllen und dann ändert sich die Ausgabe des Popup.

Hoffe dann hast du bald deine Änderung wie du sie dir vorstellst ;)
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Eine XML mit dem Namen "Z_ChangeArticleType" habe ich jetzt unter "Kernel/Config/Files" abgelegt und ein Modul namens "ChangeArticleType" befindet sich unter "/Custom/Kernel/Modules". Inhalte sind derzeit exakt so wie du sie mir angegeben hast.
RStraub wrote:Diese XML registriert ein Modul mit dem Namen "ChangeArticleType" und den Knopf "intern - extern" im Ticket Zoom. Wenn du dein bestehndes Modul nehmen willst, ändere die Pfade entsprechend an.
Das hört sich so an als sollte JETZT SCHON ein Knopf "intern - extern" im Ticket Zoom erscheinen?! :?

/edit: Habe mir jetzt eine Kopie von "AgentTicketZoom.tt" unter "/Custom/Kernel/Output/HTML/Standard" abgelegt und dort an der entsprechenden Stelle einfach mal ein "<a href="">TEST</a> hinterlegt und es wird nicht angezeigt (DeleteCache bringt auch nix -_-)
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Ja, der sollte da sein. Hast du die SysConfig neu aufgebaut (d.h. in der Admin-Oberfläche auf SysConfig geklickt)?

Evtl. mal die Scripte RebuildConfig und DeleteCache durchlaufen lassen.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Leider nein. :(

SetPermissions, Rebuild Config und DeleteCache hab ich laufen lassen ... sogar den Webserver neugestartet ... hab sogar versucht das "<a href="">TEST</a>" in der Original "AgentTicketZoom.tt" hinzuzufügen ... alles ohne Erfolg.

/e: In der SysConfig wirds auf jeden Fall eingetragen:
sc.png
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Hmmm, kannst du mal in der SysConfig unter
Ticket -> Frontend::Agent::Ticket::MenuModule

sicherstellen dass das ConfigItem "ChangeArticleType" registriert und aktiviert ist?

Edit: oh, hast du im edit gerade...
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Und im Log is nix ?
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Im Apache Logs nichts ungewöhnliches (nur die gewohnte Fehlermeldung, dass eine Grafik "logo_bg.png" fehlt - die habe ich einfach aus dem Ordner gelöscht um sie nicht länger zu sehen im Frontend ;-D).

Was mir jetzt aber noch bewusst geworden ist. Befinden wir uns nicht in der falschen "Ebene"? Unter "Frontend::Agent::Ticket::MenuModule" sehe ich nur die ganzen "Actions" die OBERHALB der Artikelliste (ArticleTree) im Ticket Zoom zu sehen sind... eigentlich wünsche ich mir den Link zum Ändern des Artikeltyps ja im "Article Zoom" - wenn man das so nennen kann ^^

Siehe: viewtopic.php?f=35&t=31494#p128680
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Jop, da hast du Recht, aber für Artikel hab ich noch keine "Knöpfe" hinzugefügt, da fehlt mir also schlichtweg die Erfahrung wo das einzutragen ist.

Letzter Versuch - dann bin ich nämlich ratlos - hast du ACLs die Actions verbieten? Falls nämlich so eine whitelist-ACL besteht, könnte auch der neue Knopf verschwinden.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Gut - im Notfall würde es "mir" auch reichen wenn der "Knopf" oben erscheint. Habe mal ein wenig recherchiert ob ich was dazu finde wie man Sachen am Artikel selbst anpasst - aber da scheint generell sehr wenig bekannt zu sein.

Der Straub ratlos? Oha... ACL ist auch nur eine aktiv ... und diese bezieht sich nur auf die Action "CustomerTicketMessage" und verbietet die Auswahl der beiden höchsten Prioritäten bei einer Webanfrage vom Kunden.

Tjoa - ich werd jetzt nochmal ein bisschen forschen - aber dann kann man ja fast nur noch hoffen, dass Jojo oder reneeb sich mal zu Wort melden? :lol:

ALLERBESTEN Dank auf jeden Fall wieder - du/ihr hast/habt maßgeblich dazu beigetragen, dass ich das ganze System überhaupt (ansatzweise) verstehe!
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Einen Ansatz hätte ich noch ... warum steht in der XML im unteren Teil "<Group>Otterhub-Dev</Group>"?

Dies führt nämlich dazu, dass es in der SysConfig eine neue Gruppe "Otterhub-Dev" gibt die ich durchsuchen kann. Diese hat genau einen Eintrag:
sc1.png
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Damit ich's leichter wiederfinde ;)

Unsere ganzen Anpassungen die in der SysConfig stehen habe ich auch in eine Gruppe gefasst - war angenehmer 30 Einstellungen durchzusuchen als die standardmäßigen 2000 oder was es sind.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Verstehe :-) Macht Sinn!

Also ich habe jetzt alle erdenklichen Möglichkeiten durch - habe mir sogar mal das Paket von Cape IT zusätzlich installiert um nachzusehen wie die das mit dem "Article Edit/Delete" gelöst haben ... Typ kann man auch mit deren Paket leider nicht ändern ... aber die haben es geschafft den Button unten bei den Article Items einzutragen ... habs leider nicht reproduziert bekommen...

Jojo? :lol:
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Hm, grad nochmal rumgespielt. Anscheinend liegt's am Wert innerhalb der <Action> Tags.

Hab das rausgenommen und auch die Modulregistrierung umgeschrieben (kopiert von einem funktionierenden Modul). Angehängt ist mal ein minimal-Paket mit dem es auf 4.0.7 definitiv funktioniert.
Siehe auch hier:
http://vz704.demo.znuny.com/otrs/index.pl

Login + pw = jsmith
You do not have the required permissions to view the files attached to this post.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Werd ich morgen im Büro ausprobieren. Tausend Dank.

Allerdings klappt das auf deiner Beispielseite nicht - oder? :lol:
actest.png
Wenn ich auf "Change Articel Type" klicke kommt immer die Meldung "Alles okay" - egal welcher Artikeltyp gerade ausgewählt ist.
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Jup, aber das is im Code festgelegt. Hatte wie gesagt die ganze Logik rausgelassen und nur eine minimale Ausgabe gemacht. Schau dir mal die $Success Variable an, auf die wird getestet aber sie ist fest mit 1 belegt.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Okay hab ich erst jetzt verstanden, du hast die opm eingebunden dort als Agent/Admin ^^

Habe mir diese opm dann auch mal installiert und dann darin rumgebastelt. Klappt jetzt auch soweit:
cat.png
ChangeArticleType.pm:

Code: Select all

package Kernel::Modules::ChangeArticleType;
 
use strict;
use warnings;
 
use DBI;
 
our $ObjectManagerDisabled = 1;
use Kernel::System::VariableCheck qw(:all);
 
sub new {
    my ( $Type, %Param ) = @_;
 
    # allocate new hash for object
    my $Self = {%Param};
    bless( $Self, $Type );

    # check needed objects
    NEEDED:
    for my $Needed (qw(ParamObject DBObject LayoutObject LogObject ConfigObject)) {
        if ( !$Self->{$Needed} ) {
            $Self->{LayoutObject}->FatalError( Message => "Got no $Needed!" );
        }
    }
    return $Self;
}
 
sub Run {
    my ( $Self, %Param ) = @_;
    
    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
    my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
    my $Output = $LayoutObject->Header(Title => "Changing Article Type...");
    my $Success = 0;
    
    
    my %Ticket = $Self->{TicketObject}->TicketGet(
      TicketID      => $Self->{TicketID},
    );
    
    my $MeineTicketID = $Ticket{TicketID};
    
    $Output .= "TicketID: $MeineTicketID";
    
    
    my %Ticket = $TicketObject->TicketGet(
      TicketID      => $MeineTicketID,
      UserID        => 1,
    );
    
    my @ArticleIDs = $TicketObject->ArticleIndex(
      TicketID => $MeineTicketID,
    );  
    
    my $LastArticleID = $ArticleIDs[$#ArticleIDs];
    
    $Output .= "<br>";
    $Output .= "Letzte ArticleID: $LastArticleID";
    
    my %Article = $TicketObject->ArticleGet(
      ArticleID     => $LastArticleID,
      UserID        => 1,
    );
    
    my $MeinArticleType = $Article{ArticleType};
    
    $Output .= "<br>";
    $Output .= "Type(vorher): $MeinArticleType";
   
    ############
    # DBI START
    
    my $dbh;
    my $sth;
    
    $dbh = DBI->connect('DBI:mysql:otrsdb', 'otrsuser', '----------------')
            || die "Could not connect to database: $DBI::errstr";
    
    if ($Article{ArticleType} eq 'note-external') {      # note-external?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=9 WHERE id=?");
    } elsif ($Article{ArticleType} eq 'note-internal') {  # note-internal?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=10 WHERE id=?");    
    } elsif ($Article{ArticleType} eq 'email-external') {  # email-external?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=2 WHERE id=?");  
    } elsif ($Article{ArticleType} eq 'email-internal') {  # email-internal?
      $sth = $dbh->prepare("UPDATE otrsdb.article SET article_type_id=1 WHERE id=?");
    } else {
      $sth = "";
    }
    
    if ($sth eq ""){
      ######            
    } else {
      $sth->execute($LastArticleID);
      $Success = 1;
    }
    
    $dbh->disconnect();
    
    # DBI ENDE
    ###########      

    if ($Success != 1){
        $Output .= $LayoutObject->Notify(
            Priority => 'Error',
            Info => 'Fehler: Falscher ArticleType?',
        );

        return $Output;
    }

    $Output .= $Self->{LayoutObject}->Notify(
        Priority => 'Warning',
        Info => "ArticleType wurde geaendert. Fenster schliessen und Ticket Zoom aktualisieren.",
    );
    
    return $Output;
}
 
1;
~ ~ ~ ~ ~

So weit so gut - bedanke mich nochmals für die super Hilfe!!

Um das ganze jetzt aber perefekt abzurunden fehlen im Grunde noch zwei Dinge:
- Derzeit wird der ArticleType der $LastArticleID geändert ... kann man nicht den ArticleType des gerade ausgewählten Artikels ändern? Finde nichts.
- Das "Popup" muss derzeit von Hand geschlossen werden und das "parent" Fenster aktualisiert werden, damit man die Änderung sieht. Kann ich an der Stelle so ohne weiteres ein Javascript einbauen das mir das aktuelle Fenster schließt und das Fenster aus dem das Popup geöffnet wurde aktualisiert? Was muss ich DA beachten?

Helft mir noch den letzten Feinschliff umzusetzen, werd das Ganze in einer ruhigen Minute auch mal in einem HowTo zusammenfassen - mich wunderte es ja eh das es zum Ändern des ArticleType nicht viel mehr Informationen hier im Forum (und im gesamten www) gibt :-D Ich wette über das HowTo werden sich künftige OTRS-Nutzer-Generationen freuen
You do not have the required permissions to view the files attached to this post.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Och nd0 :)

Also dann doch nochmal basteln. Um dir den Knopf im Artikel-Menu zu binden (wie du es ja auch wollteste) UND die ArtikelID zu übergeben, ersetze mal in der .xml den oberen Block durch diesen:

Code: Select all

    <ConfigItem Name="Frontend::Output::FilterElementPre###OutputFilterChangeArticleType" Required="0" Valid="1">
        <Description Translatable="1">This configuration registers an output filter that adds a 'Change Article Type' link to the article menu.</Description>
        <Group>TTO Framework</Group>
        <SubGroup>OutputFilter</SubGroup>
            <Setting>
                <Hash>
                    <Item Key="Module">Kernel::Output::HTML::OutputFilterChangeArticleType</Item>
                    <Item Key="Templates">
                    <Hash>
                        <Item Key="ArticleActionMenu">1</Item>
                    </Hash>
                    </Item>
                </Hash>
            </Setting>
    </ConfigItem>
Und zusätzlich erstell dir diese Datei:
~otrs/Custom/Kernel/Output/HTML/OutputFilterChangeArticleType.pm

Code: Select all

package Kernel::Output::HTML::OutputFilterChangeArticleType;

use strict;
use warnings;

our @ObjectDependencies = (
);

sub new {
    my ( $Type, %Param ) = @_;

    # allocate new hash for object
    my $Self = {};
    bless( $Self, $Type );

    return $Self;
}
sub Run {
    my ( $Self, %Param ) = @_;

    my $Link = <<'EOF';
                <li>
                    <a href="[% Env("Baselink") %]Action=ChangeArticleType;TicketID=[% Data.TicketID | html %];ArticleID=[% Data.ArticleID | html %]" title="[% Translate("Change Article Type") | html %]" class="AsPopup Popup_Type_TicketAction">[% Translate("Change Article Type") | html %]</a>
                </li>
EOF

    ${ $Param{Data} } =~ s{( <ul \s class="Actions"> )}{$1$Link}xms;

    return 1;
}

1;

Das sollte deinen Anforderungen genügen :)

Und wegen dem automatischen Refresh - das habe ich selbst auch noch nciht gemacht. Aber du kannst dir mal das Popup vom "Ticket-Verknüpfen" anschauen. Wenn man dort auf den Link Fenster schließen klickt, wird das Hauptfenster neu geladen.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Oh man ich trau mich fast nicht es zu schreiben - aber hast du das getestet?

Bei mir bewirkt die von dir angemerkte Änderung genau garnichts :-/

~~~

Der Hinweis auf "AgentLinkObject" und dort die SubAction "close" zum "Schließen und Aktualiseren" war schonmal sehr gut :-)
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Huhu,

die Änderung war tatsächlich getestet. Ist nun auch auf dem Server (s.o) als Paket installiert.
Das .opm ist angehängt.
You do not have the required permissions to view the files attached to this post.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Du bist der Beste! ;-)

Der Fehler lag in der XML-Datei. Du hast geschrieben "ersetze mal in der .xml den oberen Block" ... allerdings gabs auch im unteren Teil eine Änderung. Dieser Teil:

Code: Select all

<Hash>
<Item Key="Module">Kernel::Modules::ChangeArticleType</Item>
</Hash>
... wurde ersetz durch folgenden Teil:

Code: Select all

<FrontendModuleReg>
<Description>Change Article Type</Description>
<Title>Change Article Type</Title>
<NavBarName>Ticket</NavBarName>
</FrontendModuleReg>
Den Code zur Änderung an der DB habe ich wieder in "ChangeArticleType.pm" eingebaut. Jetzt funktioniert alles wunderbarst und ich kann weiter am Schliessen und automatischen Aktualisieren des ParentWindows basteln. Sobald ich rausgefunden habe wie ich einen anklickbaren Link im $Output des Moduls platziere werd ichs hier noch posten und dann dürfte das Thema für's Erste erledigt sein.

TAUSEND DANK! Dafür hast du dir nicht nur n Bierchen, sondern ein ganzes Fass verdient ;-)
Last edited by nd0 on 29 Feb 2016, 17:16, edited 1 time in total.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Hmja, ich tracke auch nicht alles mit :)

Freut mich das es klappt, frohes basteln noch - und das Bier behalt ich im Hinterkopf!
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
reneeb
Znuny guru
Posts: 5018
Joined: 13 Mar 2011, 09:54
Znuny Version: 6.0.x
Real Name: Renée Bäcker
Company: Perl-Services.de
Contact:

Re: Erweiterung: Modul(e) hinzufügen

Post by reneeb »

Ich habe mal ein komplettes Modul daraus gemacht: http://opar.perl-services.de/dist/ChangeArticleType
Perl / Znuny development: http://perl-services.de
Free Znuny add ons from the community: http://opar.perl-services.de
Commercial add ons: http://feature-addons.de
RStraub
Znuny guru
Posts: 2210
Joined: 13 Mar 2014, 09:16
Znuny Version: 6.0.14
Real Name: Rolf Straub

Re: Erweiterung: Modul(e) hinzufügen

Post by RStraub »

Hui sehr chic!

Und wie schön du diese 4-5 Seiten Thread in einer Zeile zusammengefasst hast - grandios :)
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
nd0
Znuny expert
Posts: 232
Joined: 24 Mar 2015, 16:53
Znuny Version: 5.0.14
Location: Colonia

Re: Erweiterung: Modul(e) hinzufügen

Post by nd0 »

Okay - gefällt mir viel besser als meine gefrickelte Lösung :-) Auch hinsichtlich Updates um einiges pflegeleichter - top - vielen Dank reneeb.
LIVE: OTRS 5.0.14 || Debian || MySQL/LDAP
TEST: OTRS 5.0.14 || Debian || MySQL/LDAP
Locked