### XML CodeInstall Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Provides Perl code to be executed during package installation. Includes examples for logging and database operations. Can be executed before ('pre') or after ('post') installation. ```perl # log example $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'notice', Message => "Some Message!", ); # database example $Kernel::OM->Get('Kernel::System::DB')->Do(SQL => "SOME SQL"); ``` -------------------------------- ### Rebuild OTOBO Configuration and Install Module Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/get-started/development-environment.md After linking a module, rebuild the OTOBO system configuration and execute any necessary SQL or Perl code from the module. This example installs the 'Calendar' module. ```bash shell> ~/src/otobo/bin/otobo.Console.pl Maint::Config::Rebuild shell> ~/src/module-tools/DatabaseInstall.pl -m Calendar.sopm -a install shell> ~/src/module-tools/CodeInstall.pl -m Calendar.sopm -a install ``` -------------------------------- ### Clone OTOBO Development Guide Repository Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/README.md Clone the repository to start working on the documentation. Navigate into the cloned directory afterwards. ```bash git clone https://github.com/RotherOSS/doc-otobo-dev.git cd doc-otobo-dev ``` -------------------------------- ### otobo Package Specification (.sopm) Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md This XML file defines the metadata, installation, and uninstallation procedures for an otobo package. It includes details like package name, version, vendor, changelog, descriptions, installation files, and database schema. ```XML Calendar 10.0.1 10.0.x Rother OSS GmbH https://otobo.com/ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Added some feature. New package. A customer package. Ein kundenspezifisches Paket. Thank you for choosing the Calendar module. Vielen Dank fuer die Auswahl des Kalender Modules. ? ? ``` -------------------------------- ### Mapping Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example configuration for the Mapping module. ```json { "mappingType": "CustomMapping", "settings": { "rules": [ { "from": "fieldA", "to": "fieldB" } ] } } ``` -------------------------------- ### Invoker Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example configuration for the Invoker module. ```json { "invokerType": "RemoteInvoker", "settings": { "endpoint": "http://example.com/api" } } ``` -------------------------------- ### Operation Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example configuration for the Operation module. ```json { "operationType": "DataProcessingOperation", "settings": { "processingMode": "batch" } } ``` -------------------------------- ### Ticket Menu Module Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example configuration for the Ticket Menu Module. ```json { "moduleName": "TicketMenuModule", "settings": { "showQuickCreate": true } } ``` -------------------------------- ### Notification Module Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example configuration for the Notification Module. ```json { "moduleName": "NotificationModule", "settings": { "defaultChannel": "email" } } ``` -------------------------------- ### Database Installation Type Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Specifies the execution time for database operations, defaulting to 'post' installation. ```XML ``` -------------------------------- ### Agent Authentication Module Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This configuration example shows how to enable and configure a custom Agent Authentication module in OTOBO. It specifies the module name and its parameters. ```yaml AuthModules: Agent: - Name: MyAuth Module: OTOBO::Auth::Agent::MyAuth Params: SomeParam: SomeValue ``` -------------------------------- ### REST WADL Extension Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/gi-operation.md Example of extending a WADL file to define a new REST resource and operation for 'Test'. This includes defining the resource path, query parameters, and the GET method with its request and response. ```APIDOC ## WADL Extension Example WADL files contain the definitions of the web services and its operations for REST interface, add a new resource to `development/webservices/GenericTickeConnectorREST.wadl`. ```xml ``` ``` -------------------------------- ### Network Transport Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example configuration for the Network Transport. ```json { "transportType": "NetworkTransport", "settings": { "host": "localhost", "port": 8080, "protocol": "http" } } ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/README.md Install all necessary Python packages, including Sphinx and themes, using the provided requirements file. ```bash pip install -r requirements.txt ``` -------------------------------- ### Notification Module Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example demonstrating the code for the Notification Module. ```javascript class NotificationModule extends BaseModule { constructor(config) { super(config); } async notify(message) { console.log('Notification:', message); // Add notification logic here } } ``` -------------------------------- ### Install and Prepare Vendor Modules Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/writing-new-otobo-frontend-component.md Install the required module without saving it to package.json, then remove modules already provided by the OTOBO framework. This helps in reducing the final package size. ```bash /ws/MyPackage $ npm install vue-full-calendar --no-save + vue-full-calendar@2.7.0 added 9 packages from 14 contributors in 1.883s /ws/MyPackage $ ls -1 node_modules/ babel-plugin-transform-runtime babel-runtime core-js fullcalendar jquery lodash.defaultsdeep moment regenerator-runtime vue-full-calendar ``` ```bash /ws/MyPackage $ rm -rf node_modules/babel-runtime node_modules/core-js node_modules/moment node_modules/regenerator-runtime /ws/MyPackage $ ls -1 node_modules/ babel-plugin-transform-runtime fullcalendar jquery lodash.defaultsdeep vue-full-calendar ``` -------------------------------- ### Ticket Menu Module Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example demonstrating the code for the Ticket Menu Module. ```javascript class TicketMenuModule extends BaseModule { constructor(config) { super(config); } getMenuItems() { return [ { label: 'New Ticket', action: 'createTicket' }, { label: 'View Tickets', action: 'viewTickets' } ]; } } ``` -------------------------------- ### Concise Content Example (RST) Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/documentation/style-guide.md An example of concise, step-by-step content writing that is recommended. This format improves readability and simplifies translation by breaking down instructions into short, manageable sentences. ```rst To change the interface language of OTOBO: 1. Click on your avatar on the top left corner. 2. Select *Personal Settings*. 3. Click the *User Profile* in the new screen. 4. Choose a language from the drop-down menu of the *Language* widget. 5. Click the *Save* button next to the widget. ``` -------------------------------- ### Mapping Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example code for a Mapping backend. ```javascript class MappingBackend extends Mapping { constructor(config) { super(config); } async map(data) { console.log('Mapping data:', data); // Mapping logic return 'mapped_data'; } } ``` -------------------------------- ### Root Application Component Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example code for the Root Application Component. ```javascript class RootApplicationComponent extends BaseComponent { constructor(config) { super(config); } render() { return '

Welcome to oTOBO

'; } } ``` -------------------------------- ### Customer User Preferences Module Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This Perl example shows how OTOBO might interact with the Customer User Preferences module to fetch or update a customer's settings. It demonstrates calls to GetPreferences and SetPreferences. ```perl my $prefs_module = OTOBO::CustomerUserPreferences::MyPreferences->new($config->{CustomerUserPreferencesModules}->[0]); my $customer_user_id = 456; my $prefs = $prefs_module->GetPreferences($customer_user_id); print "Retrieved preferences: ", Dumper($prefs), "\n"; $prefs->{Language} = 'de'; $prefs_module->SetPreferences($customer_user_id, $prefs); ``` -------------------------------- ### Start and Log Connection Events Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-it-works/log-mechanism.md Initiate a 'Connection' object log and record connection-related messages with a specified priority, key, and value. Ensure the object log is started before logging events. ```Perl $CommunicationLogObject->ObjectLogStart( ObjectLogType => 'Connection', ); $CommunicationLogObject->ObjectLog( ObjectLogType => 'Connection', Priority => 'Debug', # Trace, Debug, Info, Notice, Warning or Error Key => 'Kernel::System::MailAccount::POP3', Value => "Open connection to 'host.example.com' (user-1).", ); ``` -------------------------------- ### Ticket Event Module Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/events.md Shows the naming convention for configuring ticket event modules in XML configuration files. ```xml Ticket::EventModulePost### ``` -------------------------------- ### Customer Authentication Module Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This Perl example demonstrates how OTOBO might use the Customer Authentication module to verify customer login credentials. It shows the call to the Authenticate method. ```perl my $cust_auth_module = OTOBO::Auth::Customer::MyCustomerAuth->new($config->{AuthModules}->{Customer}->[0]); my $customer_id = $cust_auth_module->Authenticate('customer@example.com', 'custpass'); if (defined $customer_id) { print "Customer authentication successful for ID: $customer_id\n"; } else { print "Customer authentication failed.\n"; } ``` -------------------------------- ### Queue Preferences Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This Perl example shows how OTOBO might use the Queue Preferences module to retrieve or update settings for a specific queue. It demonstrates calls to GetPreferences and SetPreferences. ```perl my $queue_prefs_module = OTOBO::QueuePreferences::MyQueuePrefs->new($config->{QueuePreferencesModules}->[0]); my $queue_id = 5; my $prefs = $queue_prefs_module->GetPreferences($queue_id); print "Retrieved queue preferences: ", Dumper($prefs), "\n"; $prefs->{AutoCloseTime} = 7200; $queue_prefs_module->SetPreferences($queue_id, $prefs); ``` -------------------------------- ### Agent Authentication Module Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This example illustrates how OTOBO might use the Agent Authentication module to verify agent credentials during login. It shows the call to the Authenticate method. ```perl my $auth_module = OTOBO::Auth::Agent::MyAuth->new($config->{AuthModules}->{Agent}->[0]); my $user_id = $auth_module->Authenticate('testuser', 'password'); if (defined $user_id) { print "Authentication successful for user ID: $user_id\n"; } else { print "Authentication failed.\n"; } ``` -------------------------------- ### List All OPM Packages via Console Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-management.md Command to list all installed OPM packages using the OTOBO console. ```shell bin/otobo.Console.pl Admin::Package::List ``` -------------------------------- ### Ticket Menu Module Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of using the Ticket Menu Module in a use case. ```javascript const ticketMenuModule = new TicketMenuModule(); const menuItems = ticketMenuModule.getMenuItems(); console.log('Ticket Menu Items:', menuItems); ``` -------------------------------- ### Conditional Database Install with IfPackage Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Applies a DatabaseInstall section only if a specified package is present in the local repository. This allows for conditional package installations. ```XML # ... ``` -------------------------------- ### Install OPM Package via Console Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-management.md Command to install an OPM package using the OTOBO console. Ensure the package file has a .opm extension. ```shell bin/otobo.Console.pl Admin::Package::Install /path/to/package.opm ``` -------------------------------- ### Module SYNOPSIS Section Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/contributing/code-style.md The SYNOPSIS section provides a short usage example of commonly used module functions. Usage is optional. ```Perl =head1 SYNOPSIS my $Object = $Kernel::OM->Get('Kernel::System::MyModule'); Read data my $FileContent = $Object->Read( File => '/tmp/testfile', ); Write data $Object->Write( Content => 'my file content', File => '/tmp/testfile', ); ``` -------------------------------- ### Perl Ticket Menu Module Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/ticket-menu.md Implement a custom ticket menu module by defining 'new()' and 'Run()' functions. This example demonstrates basic logic for checking permissions and returning menu item details. ```Perl # -- # Copyright (C) 2019-2021 Rother OSS GmbH, https://otobo.de/ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. # -- package Kernel::Output::HTML::TicketMenuCustom; use strict; use warnings; sub new { my ( $Type, %Param ) = @__; # allocate new hash for object my $Self = {}; bless( $Self, $Type ); # get needed objects for my $Object (qw(ConfigObject LogObject DBObject LayoutObject UserID TicketObject)) { $Self->{$Object} = $Param{$Object} || die "Got no $Object!"; } return $Self; } sub Run { my ( $Self, %Param ) = @__; # check needed stuff if ( !$Param{Ticket} ) { $Self->{LogObject}->Log( Priority => 'error', Message => 'Need Ticket!' ); return; } # check if frontend module registered, if not, do not show action if ( $Param{Config}->{Action} ) { my $Module = $Self->{ConfigObject}->Get('Frontend::Module')->{ $Param{Config}->{Action} }; return if !$Module; } # check permission my $AccessOk = $Self->{TicketObject}->Permission( Type => 'rw', TicketID => $Param{Ticket}->{TicketID}, UserID => $Self->{UserID}, LogNo => 1, ); return if !$AccessOk; # check permission if ( $Self->{TicketObject}->CustomIsTicketCustom( TicketID => $Param{Ticket}->{TicketID} ) ) { my $AccessOk = $Self->{TicketObject}->OwnerCheck( TicketID => $Param{Ticket}->{TicketID}, OwnerID => $Self->{UserID}, ); return if !$AccessOk; } # check acl return if defined $Param{ACL}->{ $Param{Config}->{Action} } && !$Param{ACL}->{ $Param{Config}->{Action} }; # if ticket is customized if ( $Param{Ticket}->{Custom} eq 'lock' ) { # if it is locked for somebody else return if $Param{Ticket}->{OwnerID} ne $Self->{UserID}; # show custom action return { %{ $Param{Config} }, %{ $Param{Ticket} }, %Param, Name => 'Custom', Description => 'Custom to give it back to the queue!', Link => 'Action=AgentTicketCustom;Subaction=Custom;TicketID=$QData{"TicketID"}', }; } # if ticket is customized return { %{ $Param{Config} }, %{ $Param{Ticket} }, %Param, Name => 'Custom', Description => 'Custom it to work on it!', Link => 'Action=AgentTicketCustom;Subaction=Custom;TicketID=$QData{"TicketID"}', }; } 1; ``` -------------------------------- ### Authentication Synchronization Module Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This Perl example shows how OTOBO might trigger the user synchronization process using the configured Authentication Synchronization module. It calls the SyncUser method. ```perl my $sync_module = OTOBO::Auth::Sync::MySync->new($config->{AuthModules}->{Sync}->[0]); my $user_data = { UserID => 123, Username => 'testuser', Email => 'test@example.com' }; $sync_module->SyncUser($user_data); ``` -------------------------------- ### OTOBO Module Header Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/dynamic-fields/dynamic-fields-new-field.md This is the standard header for OTOBO modules, including copyright, licensing, package declaration, and dependencies. ```Perl # -- # Copyright (C) 2019-2021 Rother OSS GmbH, https://otobo.de/ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. # -- package Kernel::System::DynamicField::Driver::Password; use strict; use warnings; use parent qw(Kernel::System::DynamicField::Driver::BaseText); use Kernel::System::VariableCheck qw(:all); our @ObjectDependencies = ( 'Kernel::Config', 'Kernel::System::DynamicField::Value', 'Kernel::System::Main', ); ``` -------------------------------- ### Component Folder Structure Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/writing-new-otobo-frontend-component.md Organize your component files within a dedicated folder. The main component file should be named `index.vue`. ```default HelloWorld/ HelloWorld/index.vue ``` ```default HelloWorld/ HelloWorld/index.vue HelloWorld/Styles/_mystyles.scss HelloWorld/Images/foobar.png HelloWorld/Fonts/awesome-font.woff HelloWorld/Fonts/awesome-font.woff2 HelloWorld/ChildComponent1.vue HelloWorld/ChildComponent2/index.vue HelloWorld/ChildComponent2/Styles/_childstyles2.scss ``` -------------------------------- ### Module DESCRIPTION Section Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/contributing/code-style.md The DESCRIPTION section offers more in-depth information about the module if necessary. Usage is optional. ```Perl =head1 DESCRIPTION This module does not only handle files. It is also able to: - brew coffee - turn lead into gold - bring world peace ``` -------------------------------- ### XML IntroInstall Tag Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Defines introductory text to be displayed in the installation dialog. Supports HTML formatting by default and can be set to plain text. 'Lang' and 'Title' attributes are optional. ```xml ``` -------------------------------- ### XML IntroReinstall Tag Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Defines introductory text for the re-installation dialog. Supports HTML or plain text formatting and optional language and title attributes. ```xml ``` -------------------------------- ### Change to OTOBO Home Directory (Non-Docker) Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/get-started/development-environment.md Navigate to the OTOBO installation directory when not using Docker, typically '/opt/otobo', to execute commands. ```bash shell> cd /opt/otobo ``` -------------------------------- ### Example OTOBO Configuration Setting Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-it-works/config-mechanism.md Demonstrates the structure of a single configuration setting within an OTOBO XML file, including its name, description, navigation path, and value. ```XML The identifier for a ticket, e.g. Ticket#, Call#, MyTicket#. The default is Ticket#. Core::Ticket Ticket# ``` -------------------------------- ### Perl SLA Preferences Module Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/sla-preferences.md This Perl module implements custom SLA preferences for OTOBO. It includes functions for setting and getting SLA preferences, interacting with the database, and logging. Ensure the module is saved under Kernel/System/SLA/PreferencesCustom.pm. ```Perl # -- # Copyright (C) 2019-2021 Rother OSS GmbH, https://otobo.de/ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. # -- package Kernel::System::SLA::PreferencesCustom; use strict; use warnings; use vars qw(@ISA); sub new { my ( $Type, %Param ) = @_; # allocate new hash for object my $Self = {}; bless( $Self, $Type ); # check needed objects for (qw(DBObject ConfigObject LogObject)) { $Self->{$_} = $Param{$_} || die "Got no $_!"; } # preferences table data $Self->{PreferencesTable} = 'sla_preferences'; $Self->{PreferencesTableKey} = 'preferences_key'; $Self->{PreferencesTableValue} = 'preferences_value'; $Self->{PreferencesTableSLAID} = 'sla_id'; return $Self; } sub SLAPreferencesSet { my ( $Self, %Param ) = @_; # check needed stuff for (qw(SLAID Key Value)) { if ( !defined( $Param{$_} ) ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" ); return; } } # delete old data return if !$Self->{DBObject}->Do( SQL => "DELETE FROM $Self->{PreferencesTable} WHERE " . "$Self->{PreferencesTableSLAID} = ? AND $Self->{PreferencesTableKey} = ?", Bind => [ \$Param{SLAID}, \$Param{Key} ], ); $Self->{PreferencesTableValue} .= 'PreferencesCustom'; # insert new data return $Self->{DBObject}->Do( SQL => "INSERT INTO $Self->{PreferencesTable} ($Self->{PreferencesTableSLAID}, " . " $Self->{PreferencesTableKey}, $Self->{PreferencesTableValue}) " . " VALUES (?, ?, ?)", Bind => [ \$Param{SLAID}, \$Param{Key}, \$Param{Value} ], ); } sub SLAPreferencesGet { my ( $Self, %Param ) = @_; # check needed stuff for (qw(SLAID)) { if ( !$Param{$_} ) { $Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" ); return; } } # check if SLA preferences are available if ( !$Self->{ConfigObject}->Get('SLAPreferences') ) { return; } # get preferences return if !$Self->{DBObject}->Prepare( SQL => "SELECT $Self->{PreferencesTableKey}, $Self->{PreferencesTableValue} " . " FROM $Self->{PreferencesTable} WHERE $Self->{PreferencesTableSLAID} = ?", Bind => [ \$Param{SLAID} ], ); my %Data; while ( my @Row = $Self->{DBObject}->FetchrowArray() ) { $Data{ $Row[0] } = $Row[1]; } # return data return %Data; } 1; ``` -------------------------------- ### WADL Extension Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of a WADL extension for an Operation. ```xml ``` -------------------------------- ### Create and Configure Webservice Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/gi-operation.md This snippet demonstrates the process of creating a new webservice, configuring its debugger and provider settings, and updating it with detailed configuration including transport and operation specifics. It also includes setting up the remote system endpoint. ```perl use vars (qw($Self)); use Kernel::GenericInterface::Debugger; use Kernel::GenericInterface::Operation::Test::Test; use Kernel::System::VariableCheck qw(:all); # Skip SSL certificate verification (RestoreDatabase must not be used in this test). $Kernel::OM->ObjectParamAdd( 'Kernel::System::UnitTest::Helper' => { SkipSSLVerify => 1, }, ); my $Helper = $Kernel::OM->Get('Kernel::System::UnitTest::Helper'); # get a random number my $RandomID = $Helper->GetRandomNumber(); # create a new user for current test my $UserLogin = $Helper->TestUserCreate( Groups => ['users'], ); my $Password = $UserLogin; my $UserID = $Kernel::OM->Get('Kernel::System::User')->UserLookup( UserLogin => $UserLogin, ); # set web-service name my $WebserviceName = '-Test-' . $RandomID; # create web-service object my $WebserviceObject = $Kernel::OM->Get('Kernel::System::GenericInterface::Webservice'); $Self->Is( 'Kernel::System::GenericInterface::Webservice', ref $WebserviceObject, "Create web service object", ); my $WebserviceID = $WebserviceObject->WebserviceAdd( Name => $WebserviceName, Config => { Debugger => { DebugThreshold => 'debug', }, Provider => { Transport => { Type => '', }, }, }, ValidID => 1, UserID => 1, ); $Self->True( $WebserviceID, "Added Web Service", ); # get remote host with some precautions for certain unit test systems my $Host = $Helper->GetTestHTTPHostname(); my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); # prepare web-service config my $RemoteSystem = $ConfigObject->Get('HttpType') . '://' . $Host . '/' . $ConfigObject->Get('ScriptAlias') . '/nph-genericinterface.pl/WebserviceID/' . $WebserviceID; my $WebserviceConfig = { Description => 'Test for Ticket Connector using SOAP transport backend.', Debugger => { DebugThreshold => 'debug', TestMode => 1, }, Provider => { Transport => { Type => 'HTTP::SOAP', Config => { MaxLength => 10000000, NameSpace => 'http://otobo.org/SoapTestInterface/', Endpoint => $RemoteSystem, }, }, Operation => { Test => { Type => 'Test::Test', }, }, }, Requester => { Transport => { Type => 'HTTP::SOAP', Config => { NameSpace => 'http://otobo.org/SoapTestInterface/', Encoding => 'UTF-8', Endpoint => $RemoteSystem, }, }, Invoker => { Test => { Type => 'Test::TestSimple' , # requester needs to be Test::TestSimple in order to simulate a request to a remote system }, }, }, }; # update web-service with real config # the update is needed because we are using # the WebserviceID for the Endpoint in config my $WebserviceUpdate = $WebserviceObject->WebserviceUpdate( ID => $WebserviceID, Name => $WebserviceName, Config => $WebserviceConfig, ValidID => 1, UserID => $UserID, ); $Self->True( $WebserviceUpdate, "Updated Web Service $WebserviceID - $WebserviceName", ); ``` -------------------------------- ### WSDL Extension Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of a WSDL extension for an Operation. ```xml ``` -------------------------------- ### Open Local HTML Documentation Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/README.md After building the HTML documentation, open the main index file in your web browser to view the generated output. This command is an example for Linux/macOS. ```bash open _build/html/content/index.html ``` -------------------------------- ### Operation Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example code for an Operation backend. ```javascript class OperationBackend extends Operation { constructor(config) { super(config); } async execute(input) { console.log('Executing operation with input:', input); // Operation execution logic return 'operation_result'; } } ``` -------------------------------- ### Invoker Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example code for an Invoker backend. ```javascript class InvokerBackend extends Invoker { constructor(config) { super(config); } async invoke(operation, params) { console.log(`Invoking operation: ${operation} with params:`, params); // Invocation logic return 'invocation_result'; } } ``` -------------------------------- ### Kernel::System::HelloWorld Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/writing-otobo-application.md This snippet shows the implementation of a basic OTOBO module 'HelloWorld' and its public method 'GetHelloWorldText'. It also includes an internal helper method '_FormatHelloWorldText'. ```APIDOC ## Kernel::System::HelloWorld ### Description A basic OTOBO module that provides a 'Hello World' text. ### Methods #### new() Creates a new instance of the HelloWorld object. ##### Usage ```perl my $HelloWorldObject = $Kernel::OM->Get('Kernel::System::HelloWorld'); ``` #### GetHelloWorldText() Returns the formatted 'Hello World' text. ##### Usage ```perl my $HelloWorldText = $HelloWorldObject->GetHelloWorldText(); ``` #### _FormatHelloWorldText() Internal method to format the 'Hello World' string to uppercase. ##### Usage ```perl my $HelloWorld = $Self->_FormatHelloWorldText( String => 'Hello World', ); ``` ### Dependencies - Kernel::System::DB (commented out in example) ``` -------------------------------- ### XML IntroUninstall Tag Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Defines introductory text for the uninstallation dialog. Similar to IntroInstall, it supports HTML or plain text formatting and optional language and title attributes. ```xml ``` -------------------------------- ### Operation Unit Test Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of a unit test for an Operation. ```javascript describe('OperationBackend', () => { it('should execute correctly', async () => { const operation = new OperationBackend({}); const result = await operation.execute('test_input'); expect(result).toBe('operation_result'); }); }); ``` -------------------------------- ### Network Transport Code Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example code for a Network Transport backend. ```javascript class NetworkTransportBackend extends TransportBackend { constructor(config) { super(config); } async send(data) { console.log('Sending data over network:', data); // Network transport logic } async receive() { console.log('Receiving data over network'); // Network receive logic return 'network_data'; } } ``` -------------------------------- ### Generate HTML Documentation Locally Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/README.md Build the HTML version of the documentation using the Makefile. This command is used for local preview before submitting changes. ```bash make html ``` -------------------------------- ### Web Service REST Extension Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of a Web Service REST extension for an Operation. ```json { "operation": "PerformAction", "parameters": { "param1": "value1", "param2": 123 } } ``` -------------------------------- ### Web Service SOAP Extension Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of a Web Service SOAP extension for an Operation. ```xml Sample Input ``` -------------------------------- ### Authentication Synchronization Module Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This YAML configuration enables and sets up a custom Authentication Synchronization module. It specifies the module's name, class, and any necessary parameters. ```yaml AuthModules: Sync: - Name: MySync Module: OTOBO::Auth::Sync::MySync Params: SyncInterval: 3600 ``` -------------------------------- ### Notification Module Use Case Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers.md Example of using the Notification Module in a use case. ```javascript const notificationModule = new NotificationModule({ defaultChannel: 'sms' }); notificationModule.notify('System alert: High CPU usage!'); ``` -------------------------------- ### Verify Vendor Module Structure Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/writing-new-otobo-frontend-component.md After moving and optimizing, list the contents of the `Frontend/Vendor` directory to confirm that the modules are correctly placed and ready for packaging. ```bash /ws/MyPackage $ ls -la Frontend/Vendor Frontend/Vendor Frontend/Vendor/vue-full-calendar Frontend/Vendor/vue-full-calendar/.babelrc Frontend/Vendor/vue-full-calendar/LICENSE Frontend/Vendor/vue-full-calendar/tests Frontend/Vendor/vue-full-calendar/tests/fullcalendar.spec.js Frontend/Vendor/vue-full-calendar/index.js ... ``` -------------------------------- ### Matching String Start and End with '\A' and '\z' Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/contributing/code-style.md Use '\A' and '\z' anchors to match the absolute start and end of a string, respectively. Use '^' and '$' only when matching the start or end of lines within a multi-line string. ```Perl $Text =~ m{ \A # beginning of the string Content # some string \z # end of the string }xms; ``` ```Perl $MultilineText =~ m{ \A # beginning of the string .* (?: \n Content $ )+ # one or more lines containing the same string .* \z # end of the string }xms; ``` -------------------------------- ### Instantiate StaticStatsTemplate Object Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/stats.md Demonstrates how to create an instance of the StaticStatsTemplate module by providing necessary configuration and system objects. Ensure all required objects like ConfigObject, LogObject, etc., are initialized before instantiation. ```Perl # -- # Copyright (C) 2019-2021 Rother OSS GmbH, https://otobo.de/ # -- # This software comes with ABSOLUTELY NO WARRANTY. For details, see # the enclosed file COPYING for license information (GPL). If you # did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. # -- package Kernel::System::Stats::Static::StaticStatsTemplate; use strict; use warnings; use Kernel::System::Type; use Kernel::System::Ticket; use Kernel::System::Queue; =head1 NAME StaticStatsTemplate.pm - the module that creates the stats about tickets in a queue =head1 SYNOPSIS All functions =head1 PUBLIC INTERFACE =over 4 =\n =item new() create an object use Kernel::Config; use Kernel::System::Encode; use Kernel::System::Log; use Kernel::System::Main; use Kernel::System::Time; use Kernel::System::DB; use Kernel::System::Stats::Static::StaticStatsTemplate; my $ConfigObject = Kernel::Config->new(); my $EncodeObject = Kernel::System::Encode->new( ConfigObject => $ConfigObject, ); my $LogObject = Kernel::System::Log->new( ConfigObject => $ConfigObject, ); my $MainObject = Kernel::System::Main->new( ConfigObject => $ConfigObject, LogObject => $LogObject, ); my $TimeObject = Kernel::System::Time->new( ConfigObject => $ConfigObject, LogObject => $LogObject, ); my $DBObject = Kernel::System::DB->new( ConfigObject => $ConfigObject, LogObject => $LogObject, MainObject => $MainObject, ); my $StatsObject = Kernel::System::Stats::Static::StaticStatsTemplate->new( ConfigObject => $ConfigObject, LogObject => $LogObject, MainObject => $MainObject, TimeObject => $TimeObject, DBObject => $DBObject, EncodeObject => $EncodeObject, ); =cut sub new { my ( $Type, %Param ) = @_; # allocate new hash for object my $Self = {%Param}; bless( $Self, $Type ); # check all needed objects for my $Needed (qw(DBObject ConfigObject LogObject TimeObject MainObject EncodeObject)) { $Self->{$Needed} = $Param{$Needed} || die "Got no $Needed"; } # create needed objects $Self->{TypeObject} = Kernel::System::Type->new( %{$Self} ); $Self->{TicketObject} = Kernel::System::Ticket->new( %{$Self} ); $Self->{QueueObject} = Kernel::System::Queue->new( %{$Self} ); return $Self; } ``` -------------------------------- ### Customer Authentication Module Configuration Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo.md This YAML configuration enables a custom Customer Authentication module for OTOBO. It specifies the module's name, class, and any required parameters. ```yaml AuthModules: Customer: - Name: MyCustomerAuth Module: OTOBO::Auth::Customer::MyCustomerAuth Params: SSLEnabled: true ``` -------------------------------- ### Required Perl Module Dependencies Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Lists Perl modules that must be installed prior to installing this package, with version constraints. ```XML Encode MIME::Tools ``` -------------------------------- ### Subroutine Documentation Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/contributing/code-style.md Documents a subroutine, including its purpose, a sample call, and its return value. The return value can be a Data::Dumper output. ```Perl =head2 LastTimeObjectChanged() Calculates the last time the object was changed. It returns a hash reference with information about the object and the time. my $Info = $Object->LastTimeObjectChanged( Param => 'Value', ); This returns something like: my $Info = { ConfigItemID => 1234, HistoryType => 'foo', LastTimeChanged => '08.10.2009', }; =cut ``` -------------------------------- ### Provide and Configure Test Database Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/contributing/unit-tests.md This function sets up a temporary database for testing, optionally loading a specific XML schema or a list of XML files. It overrides global database configurations for the test duration. The database is automatically dropped when the Helper object is destroyed. ```Perl $Helper->ProvideTestDatabase( DatabaseXMLString => $XML, # (optional) OTOBO database XML schema to execute # or DatabaseXMLFiles => [ # (optional) List of XML files to load and execute '/opt/otobo/scripts/database/otobo-schema.xml', '/opt/otobo/scripts/database/otobo-initial_insert.xml', ], ); ``` -------------------------------- ### Verbose Content Example (RST) Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/documentation/style-guide.md An example of verbose content writing that is not recommended. This format is less suitable for translation due to long, monolithic text blocks. ```rst The agents are able to change the interface language of OTOBO. To change the interface language, click on your avatar on the top left corner, then select Personal Settings menu item. A new screen will be displayed. On this screen click on the User Profile, and then find a widget named Language. Select the desired language in the drop-down menu. Please make sure to click on the Save button next to the language widget. ``` -------------------------------- ### SOAP WSDL Extension Example Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-extend-otobo/otobo-module-layers/gi-operation.md Example of extending a WSDL file to define a new SOAP operation named 'Test'. This includes definitions for the port type, binding, types, and messages. ```APIDOC ## WSDL Extension Example WSDL files contain the definitions of the web services and its operations for SOAP messages, in case we will extend `development/webservices/GenericTickeConnectorSOAP.wsdl` in some places: Port Type: ```xml ``` Binding: ```xml ``` Type: ```xml ``` Message: ```xml ``` ``` -------------------------------- ### Build OTOBO Extension Package Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Use the OTOBO console to build an .opm package from a .sopm specification file. Specify the input .sopm file and the desired output directory. ```shell shell> bin/otobo.Console.pl Dev::Package::Build /path/to/example.sopm /tmp Building package... Done. shell> ``` -------------------------------- ### XML IntroUpgrade Tag Source: https://github.com/rotheross/doc-otobo-dev/blob/rel-11_0/content/how-to-publish-otobo-extensions/package-building.md Defines introductory text for the upgrade dialog. Supports HTML or plain text formatting and optional language and title attributes. ```xml ```