Az OTRS minden új hibajavító vagy fő verziójával át kell írnia a csomagjait, és meg kell győződnie arról, hogy azok továbbra is működnek az OTRS API-val.
Ez a szakasz azokat a változtatásokat sorolja fel, amelyeket meg kell vizsgálnia, amikor átírja a csomagját az OTRS 4-ről 5-re.
Az OTRS 5-ben a Kernel/Output/HTML
átszerkesztésre
került. Az összes Perl modul (kivéve a Layout.pm
fájlt)
alkönyvtárakba került áthelyezésre (minden modulréteghez egybe). A
sablonfájlok (témák) is áthelyezésre kerültek a
Kernel/Output/HTML/Standard
könyvtárból a
Kernel/Output/HTML/Templates/Standard
könyvtárba. Végezze el ezeket a költöztetéseket a saját kódjában is.
Az OTRS 5-tel többé nincs támogatás a pre
kimenetszűrőkhöz. Ezek a szűrők azelőtt változtatták meg a sablon tartalmát,
mielőtt az feldolgozásra került volna, és potenciálisan rossz
teljesítményproblémákhoz vezethettek, ugyanis a sablonokat többé nem
lehetett gyorstárazni, és minden alkalommal fel kellett dolgozni és le
kellett fordítani.
Egyszerűen váltson a pre
kimenetszűrőről a
post
kimenetszűrőre. A tartalom lefordításához
futtathatja közvetlenül a $LayoutObject->Translate()
függvényt. Ha egyéb sablonszolgáltatásokra van szüksége, akkor egyszerűen
határozzon meg egy kis sablonfájlt a kimenetszűrőhöz, és használja azt a
tartalom megjelenítéséhez, mielőtt beültetné azt a fő adatokba. Néhány
esetben hasznos lehet a jQuery DOM műveletek használata is a képernyőn lévő
tartalom sorrendjének megváltoztatásához vagy cseréjéhez a reguláris
kifejezések használata helyett. Ebben az esetben láthatatlan tartalomként
kellene beültetnie az új kódot valahova az oldalba (például a
Hidden
osztállyal), majd ezután áthelyezni a jQuery
használatával a megfelelő helyre a DOM-ban, és megjeleníteni azt.
Az utó-kimenetszűrők használatának megkönnyítéséhez létezik egy új mechanizmus is a HTML megjegyzéshorgok lekéréséhez bizonyos sablonoknál vagy blokkoknál. Hozzáadhatja a modulbeállító XML-be a következőhöz hasonlóan:
<ConfigItem Name="Frontend::Template::GenerateBlockHooks###100-OTRSBusiness-ContactWithData" Required="1" Valid="1"> <Description Translatable="1">Generate HTML comment hooks for the specified blocks so that filters can use them.</Description> <Group>OTRSBusiness</Group> <SubGroup>Core</SubGroup> <Setting> <Hash> <Item Key="AgentTicketZoom"> <Array> <Item>CustomerTable</Item> </Array> </Item> </Hash> </Setting> </ConfigItem>
Ez azt fogja okozni, hogy az AgentTicketZoom.tt
fájlban
lévő CustomerTable
blokk át lesz alakítva a HTML
megjegyzésekben minden alkalommal, amikor megjelenítésre kerül:
<!--HookStartCustomerTable--> ... blokk kimenet ... <!--HookEndCustomerTable-->
Ezzel a mechanizmussal minden csomag csak azokat a blokkhorgokat kérheti, amelyekre szüksége van, és következetesen kerülnek megjelenítésre. Ezek a HTML megjegyzések használhatók ezután a kimenetszűrőben az egyszerű reguláris kifejezés illesztéshez.
Az IE 8 és IE 9 támogatást eldobták.
Eltávolíthat minden kerülőmegoldást a kódjából, amelyet ezekhez a
platformokhoz készített, valamint az összes olyan régi
<CSS_IE7>
vagy <CSS_IE8>
betöltő címkét, amely még esetleg megbújik az XML beállítófájljaiban.
A TicketGet()
művelet másképpen ad vissza dinamikus mező
adatokat a jegyből és a bejegyzésből mint az OTRS 4-ben. Mostantól ezek
tisztán el vannak választva a többi statikus jegy- és bejegyzésmezőktől -
innentől kezdve csoportosítva vannak egy DynamicField
nevű listába. Eszerint alakítson át minden olyan alkalmazást, amely ezt a
műveletet használja.
# megváltoztatva erről: Ticket => [ { TicketNumber => '20101027000001', Title => 'valamilyen cím', ... DynamicField_X => 'x_ertek', }, ] # erre: Ticket => [ { TicketNumber => '20101027000001', Title => 'valamilyen cím', ... DynamicField => [ { Name => 'valamilyen név', Value => 'valamilyen érték', }, ], }, ]
Az új statisztikák grafikus felhasználói felülete egy előnézetet biztosít a
jelenlegi beállításhoz. Ezt meg kell valósítani a statisztikák moduljaiban,
és általában hamis vagy véletlenszerű adatokat adnak vissza sebességi
okokból. Így minden olyan dinamikus (mátrix) statisztikánál, amely a
GetStatElement()
metódust biztosítja, hozzá kell adnia egy
GetStatElementPreview()
metódust is, valamint minden olyan
dinamikus (tábla) statisztikánál, amely a GetStatTable()
metódust biztosítja, hozzá kell adnia egy GetStatTablePreview()
metódust ennek megfelelően. Egyébként az új statisztikák grafikus
felhasználói felületén lévő előnézet nem fog működni a saját
statisztikáinál. Példamegvalósításokat találhat az alapértelmezett OTRS
statisztikákban.
Az OTRS 5-ig a PDF::API2
Perl modul nem volt megtalálható
minden rendszeren. Ezért létezett egy tartalék HTML nyomtatási mód. Az OTRS
5-tel a modul mostantól mellékelve van, és a HTML nyomtatás eldobásra
került. A $LayoutObject->PrintHeader()
és a
PrintFooter()
többé nem érhető el. Távolítsa el a tartalék HTML
nyomtatást a kódjából, és változtassa meg a PDF előállításához, ha
szükséges.
Az OTRS 5-ig a lefordítható szövegeket nem lehetett kinyerni a Perl kódból
és az adatbázis XML meghatározásokból. Ez mostantól lehetséges, és elavulttá
tette az olyan üres sablonokat, mint például az AAA*.tt
sablont. A részletekért nézze meg ezt a szakaszt.
Ez a szakasz azokat a változtatásokat sorolja fel, amelyeket meg kell vizsgálnia, amikor átírja a csomagját az OTRS 3.3-ról 4-re.
Az OTRS 4-ig az objektumokat mind központilag, mind helyileg létre kellett
hozni, és ekkor az összes objektumot le kellett kezelni a konstruktornak
átadva azokat. Az OTRS 4-es és későbbi verzióinál mostantól létezik egy
ObjectManager
objektum, amely központosítja az egyke
objektum létrehozását és hozzáférését.
Ez mindenek előtt azt fogja igényelni, hogy változtassa meg az összes felső
szintű Perl parancsfájlt (csak a .pl fájlokat!) az
ObjectManager
betöltéséhez és biztosításához az összes
OTRS objektumnál. Példaként nézzük meg az
otrs.CheckDB.pl
parancsfájlt az OTRS 3.3-ból:
use strict; use warnings; use File::Basename; use FindBin qw($RealBin); use lib dirname($RealBin); use lib dirname($RealBin) . '/Kernel/cpan-lib'; use lib dirname($RealBin) . '/Custom'; use Kernel::Config; use Kernel::System::Encode; use Kernel::System::Log; use Kernel::System::Main; use Kernel::System::DB; # a szokásos objektumok létrehozása my %CommonObject = (); $CommonObject{ConfigObject} = Kernel::Config->new(); $CommonObject{EncodeObject} = Kernel::System::Encode->new(%CommonObject); $CommonObject{LogObject} = Kernel::System::Log->new( LogPrefix => 'OTRS-otrs.CheckDB.pl', ConfigObject => $CommonObject{ConfigObject}, ); $CommonObject{MainObject} = Kernel::System::Main->new(%CommonObject); $CommonObject{DBObject} = Kernel::System::DB->new(%CommonObject);
Láthatjuk, hogy rengeteg kódot használnak a csomagok betöltéséhez és a gyakori objektumok létrehozásához, amelyet a parancsfájlban át kell adni a használandó OTRS objektumoknak. Az OTRS 4-gyel ez egy kicsit máshogy néz ki:
use strict; use warnings; use File::Basename; use FindBin qw($RealBin); use lib dirname($RealBin); use lib dirname($RealBin) . '/Kernel/cpan-lib'; use lib dirname($RealBin) . '/Custom'; use Kernel::System::ObjectManager; # a szokásos objektumok létrehozása local $Kernel::OM = Kernel::System::ObjectManager->new( 'Kernel::System::Log' => { LogPrefix => 'OTRS-otrs.CheckDB.pl', }, ); # az adatbázis-objektum lekérése my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
Az új kód egy kicsivel rövidebb mint a régi. Többé nem szükséges az összes
csomag betöltése, elég csak az ObjectManager
objektumot. Azután a
$Kernel::OM->Get('Sajat::Perl::Csomag')
használható az
objektumok példányainak lekéréséhez, amelyeket csak egyszer kell
létrehozni. A LogPrefix
beállítás vezérli azokat a
naplóüzeneteket, amelyeket a Kernel::System::Log
ír ki,
így az szintén elhagyható.
Ebből a példából kikövetkeztetheti az általános átírási irányelvet is,
amikor az objektumok hozzáférése jön: többé ne tárolja azokat a
$Self
változóban (hacsak bizonyos okokból ez nem
szükséges). Egyszerűen kérje le és használja az objektumokat igény szerint,
úgymint
$Kernel::OM->Get('Kernel::System::Log')->Log(...)
. Ennek megvan
az az előnye is, hogy a Log
objektumot csak akkor kell
majd létrehozni, ha valamit naplózni kell. Néha hasznos lehet helyi
változókat is létrehozni, ha egy objektumot többször használnak egy
függvényben, mint például a fenti példában lévő $DBObject
objektumot.
Nem kell sokkal többet tudnia az olyan csomagok átírásakor, amelyeknek
betölthetőnek kell lenniük az ObjectManager
használatával. Meg kell határozniuk azokat a modulokat, amelyeket használnak
(a $Kernel::OM->Get()
függvényen keresztül) ehhez hasonlóan:
our @ObjectDependencies = ( 'Kernel::Config', 'Kernel::System::Log', 'Kernel::System::Main', );
Az @ObjectDependencies
meghatározás szükséges az
ObjectManager
objektumhoz a helyes sorrend megtartásához
az objektumok megsemmisítésekor.
Nézzük meg a Valid.pm
fájlt az OTRS 3.3-ból és a 4-ből,
hogy lássuk a különbséget. A régi:
package Kernel::System::Valid; use strict; use warnings; use Kernel::System::CacheInternal; ... sub new { my ( $Type, %Param ) = @_; # új kivonat lefoglalása az objektumhoz my $Self = {}; bless( $Self, $Type ); # a szükséges objektumok ellenőrzése for my $Object (qw(DBObject ConfigObject LogObject EncodeObject MainObject)) { $Self->{$Object} = $Param{$Object} || die "Nincs $Object!"; } $Self->{CacheInternalObject} = Kernel::System::CacheInternal->new( %{$Self}, Type => 'Valid', TTL => 60 * 60 * 24 * 20, ); return $Self; } ... sub ValidList { my ( $Self, %Param ) = @_; # gyorsítótár olvasása my $CacheKey = 'ValidList'; my $Cache = $Self->{CacheInternalObject}->Get( Key => $CacheKey ); return %{$Cache} if $Cache; # lista lekérése az adatbázisból return if !$Self->{DBObject}->Prepare( SQL => 'SELECT id, name FROM valid' ); # az eredmény lekérése my %Data; while ( my @Row = $Self->{DBObject}->FetchrowArray() ) { $Data{ $Row[0] } = $Row[1]; } # gyorsítótár beállítása $Self->{CacheInternalObject}->Set( Key => $CacheKey, Value => \%Data ); return %Data; }
Az új:
package Kernel::System::Valid; use strict; use warnings; our @ObjectDependencies = ( 'Kernel::System::Cache', 'Kernel::System::DB', 'Kernel::System::Log', ); ... sub new { my ( $Type, %Param ) = @_; # új kivonat lefoglalása az objektumhoz my $Self = {}; bless( $Self, $Type ); $Self->{CacheType} = 'Valid'; $Self->{CacheTTL} = 60 * 60 * 24 * 20; return $Self; } ... sub ValidList { my ( $Self, %Param ) = @_; # gyorsítótár olvasása my $CacheKey = 'ValidList'; my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get( Type => $Self->{CacheType}, Key => $CacheKey, ); return %{$Cache} if $Cache; # adatbázis-objektum lekérése my $DBObject = $Kernel::OM->Get('Kernel::System::DB'); # lista lekérése az adatbázisból return if !$DBObject->Prepare( SQL => 'SELECT id, name FROM valid' ); # az eredmény lekérése my %Data; while ( my @Row = $DBObject->FetchrowArray() ) { $Data{ $Row[0] } = $Row[1]; } # gyorsítótár beállítása $Kernel::OM->Get('Kernel::System::Cache')->Set( Type => $Self->{CacheType}, TTL => $Self->{CacheTTL}, Key => $CacheKey, Value => \%Data ); return %Data; }
Láthatja, hogy meg vannak határozva a függőségek, és az objektumok csak
igény szerint vannak lekérve. A következő szakaszban a
CacheInternalObject
objektumról fogunk beszélni.
Mivel a Kernel::System::Cache
mostantól képes a
memóriában is gyorstárazni, a
Kernel::System::CacheInternal
eldobásra került. Nézze meg
az előző példát, hogy a kódot hogyan kell átköltöztetni: a globális
Cache
objektumot kell használnia, és át kell adnia a
Type
beállítást a Get()
, Set()
,
Delete()
és CleanUp()
függvények minden egyes
hívásához. A TTL
paraméter mostantól elhagyható, és
alapértelmezetten 20 nap, így csak akkor kell megadnia a Get()
függvényben, ha eltérő TTL
értékre van szüksége.
Különösen fontos a Type
paraméter hozzáadása a
CleanUp()
függvényhez, mivel különben nem csak a jelenlegi
gyorsítótártípus, hanem a teljes gyorsítótár törölve lehet.
Az ütemező háttérprogram fájljai áthelyezésre kerültek a
Kernel/Scheduler
mappából a
Kernel/System/Scheduler
mappába. Ha valamilyen egyéni
feladatkezelő moduljai vannak, akkor azokat is át kell helyeznie.
Az SOPM fájlokban lévő kódcímkéket is frissíteni kell. Többé ne használja a
$Self
változót. Régebben ezt használták az olyan OTRS
objektumokhoz való hozzáféréshez, mint például a
MainObject
. Mostantól használja az
ObjectManager
objektumot. Itt egy példa a régi stílusra:
<CodeInstall Type="post"> # függvénynév meghatározása my $FunctionName = 'CodeInstall'; # a csomagnév létrehozása my $CodeModule = 'var::packagesetup::' . $Param{Structure}->{Name}->{Content}; # a modul betöltése if ( $Self->{MainObject}->Require($CodeModule) ) { # új példány létrehozása my $CodeObject = $CodeModule->new( %{$Self} ); if ($CodeObject) { # metódus elindítása if ( !$CodeObject->$FunctionName(%{$Self}) ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Nem sikerült meghívni a(z) $FunctionName() metódust ebben: $CodeModule.pm." ); } } # hibakezelés else { $Self->{LogObject}->Log( Priority => 'error', Message => "Nem sikerült meghívni a new() metódust ebben: $CodeModule.pm." ); } } </CodeInstall>
Most ezt a következővel kell helyettesíteni:
<CodeInstall Type="post"><![CDATA[ $Kernel::OM->Get('var::packagesetup::SajatCsomag')->CodeInstall(); ]]></CodeInstall>
Az OTRS 4-gyel a DTL sablonmotort a Template::Toolkit váltotta. A részletekért nézze meg a sablonozó szakaszt, hogy hogyan néz ki az új sablonszintaxis.
Ezek azok a változtatások, amelyet alkalmaznia kell, amikor a meglévő DTL sablonokat az új Template::Toolkit szintaxisra alakítja át:
4.1. táblázat - Sablonváltoztatások az OTRS 3.3-ról 4-re
DTL címke | Template::Toolkit címke |
$Data{"Name"} |
[% Data.Name %] |
$Data{"Complex-Name"} |
[% Data.item("Complex-Name") %] |
$QData{"Name"} |
[% Data.Name | html %] |
$QData{"Name", "$Length"} |
[% Data.Name | truncate($Length) | html %] |
$LQData{"Name"} |
[% Data.Name | uri %] |
$Quote{"Szöveg", "$Length"} |
nem lehet közvetlenül lecserélni, lásd a lenti példákat |
$Quote{"$Config{"Name"}"} |
[% Config("Name") | html %] |
$Quote{"$Data{"Name"}", "$Length"} |
[% Data.Name | truncate($Length) | html %] |
$Quote{"$Data{"Content"}","$QData{"MaxLength"}"} |
[% Data.Name | truncate(Data.MaxLength) | html %] |
$Quote{"$Text{"$Data{"Content"}"}","$QData{"MaxLength"}"} |
[% Data.Content | Translate | truncate(Data.MaxLength) | html
%] |
$Config{"Name"} |
[% Config("Name") %] |
$Env{"Name"} |
[% Env("Name") %] |
$QEnv{"Name"} |
[% Env("Name") | html %] |
$Text{"Szöveg %s helykitöltőkkel", "String"} |
[% Translate("Szöveg %s helykitöltőkkel", "String") | html
%] |
$Text{"Szöveg dinamikus %s helykitöltőkkel",
"$QData{Name}"} |
[% Translate("Szöveg dinamikus %s helykitöltőkkel", Data.Name) |
html %] |
'$JSText{"Szöveg dinamikus %s helykitöltőkkel",
"$QData{Name}"}' |
[% Translate("Szöveg dinamikus %s helykitöltőkkel", Data.Name) |
JSON %] |
"$JSText{"Szöveg dinamikus %s helykitöltőkkel",
"$QData{Name}"}" |
[% Translate("Szöveg dinamikus %s helykitöltőkkel", Data.Name) |
JSON %] |
$TimeLong{"$Data{"CreateTime"}"} |
[% Data.CreateTime | Localize("TimeLong") %] |
$TimeShort{"$Data{"CreateTime"}"} |
[% Data.CreateTime | Localize("TimeShort") %] |
$Date{"$Data{"CreateTime"}"} |
[% Data.CreateTime | Localize("Date") %] |
<-- dtl:block:Name -->...<-- dtl:block:Name
--> |
[% RenderBlockStart("Name") %]...[% RenderBlockEnd("Name")
%] |
<-- dtl:js_on_document_complete -->...<--
dtl:js_on_document_complete --> |
[% WRAPPER JSOnDocumentComplete %]...[% END %] |
<-- dtl:js_on_document_complete_placeholder --> |
[% PROCESS JSOnDocumentCompleteInsert %] |
$Include{"Copyright"} |
[% InsertTemplate("Copyright") %] |
Létezik egy bin/otrs.MigrateDTLtoTT.pl
segítő
parancsfájl is, amely automatikusan át fogja írni önnek a DTL-fájlokat a
Template::Toolkit szintaxisra. Sikertelen lehet, ha hibák találhatók a
DTL-jében, ezért először javítsa ki ezeket, és azután futtassa újra a
parancsfájlt.
Van még további néhány dolog, amelyet tudomásul kell vennie a kód átírásakor az új sablonmotorra:
Az összes nyelvi fájlnak mostantól rendelkeznie kell a use
utf8;
kikötéssel.
A Layout::Get()
mostantól elavult. Használja a
Layout::Translate()
függvényt helyette.
A Perl-kódban a $Text{""}
összes előfordulását mostantól
le kell cserélni a Layout::Translate()
hívásaival.
Ez azért van, mert a DTL-ben nem volt különválasztás a sablon és az adatok között. Ha DTL-címkék voltak beszúrva valamilyen adat részeként, akkor a motornak továbbra is fel kellene dolgozni azokat. Ez többé nincs a Template::Toolkit esetén, mert itt a sablon és az adatok szigorú különválasztása van.
Tipp: ha valamikor interpolálnia kell a címkéket az adatokban, akkor ehhez
használhatja az Interpolate
szűrőt ([% Data.Name
| Interpolate %]
). Ez nem ajánlott biztonsági és teljesítménybeli
okok miatt!
Hasonló okból a dtl:js_on_document_complete
által
körbezárt dinamikusan beágyazott JavaScript sem fog működni többé. Használja
a Layout::AddJSOnDocumentComplete()
függvényt ahelyett, hogy
ezt sablonadatként ágyazná be.
Erre találhat egy példát a
Kernel/System/DynamicField/Driver/BaseSelect.pm
fájlban.
Legyen óvatos a pre
kimenetszűrőkkel (a
Frontend::Output::FilterElementPre
objektumban
beállítottakkal). Ezek továbbra is működnek, de meg fogják akadályozni a
sablont, hogy gyorstárazza azokat. Ez komoly teljesítményproblémákhoz
vezethet. Határozottan ne legyen egyetlen olyan pre
kimenetszűrője sem, amely az összes sablonnal dolgozik, hanem korlátozza
azokat bizonyos sablonokra a konfigurációs beállításokon keresztül.
A post
kimenetszűrőknek
(Frontend::Output::FilterElementPost
) nincsenek ilyen
erős negatív teljesítményhatásaik. Azonban ezeket is körültekintéssel kell
használni, és nem minden sablonnál.
Az OTRS 4-gyel egy új verzióra frissítettük a FontAwesome betűkészletet
is. Ennek következtében az ikonok CSS-osztályai megváltoztak. Miközben a
korábbi ikonok egy icon-{ikonnév}
szerű sémával voltak
meghatározva, ezt mostantól a fa fa-{ikonnév}
formában
kell megadni.
Ezen változtatás miatt meg kell győződnie arról, hogy frissítette-e az
összes olyan egyéni előtétprogram-modul regisztrációit, amelyek ikonokat
használnak (például a felső navigációs sávnál) az új séma használatához. Ez
igaz az olyan sablonoknál is, ahol ikonelemeket használ, mint például
<i class="icon-{ikonnév}"></i>
.
Az OTRS 4-gyel az egységtesztekben a $Self
többé nem
szolgáltat olyan gyakori objektumokat, mint például a
MainObject
. Mindig a $Kernel::OM->Get('...')
függvényt használja ezen objektumok lekéréséhez.
Ha bármilyen egyéni jegy előzmény típusokat használ, akkor két lépést kell
elvégeznie, hogy azok helyesen legyenek megjelenítve az OTRS 4+
AgentTicketHistory
képernyőjén.
Először regisztrálnia kell az egyéni jegy előzmény típusait a rendszerbeállításokon keresztül. Ez így nézhet ki:
<ConfigItem Name="Ticket::Frontend::HistoryTypes###100-MyCustomModule" Required="1" Valid="1"> <Description Translatable="1">Controls how to display the ticket history entries as readable values.</Description> <Group>Ticket</Group> <SubGroup>Frontend::Agent::Ticket::ViewHistory</SubGroup> <Setting> <Hash> <Item Key="MyCustomType" Translatable="1">Added information (%s)</Item> </Hash> </Setting> </ConfigItem>
A második lépés az egyéni jegy előzmény típusnál biztosított angol szöveg lefordítása a nyelvi fájljaiban, ha szükséges. Ennyi!
Ha érdeklődik a részletek iránt, akkor nézze meg ezt a véglegesítést azon változtatásokkal kapcsolatos további információkról, amelyek az OTRS-ben történtek.