1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9package Kernel::System::SysConfig::BaseValueType; 10## nofilter(TidyAll::Plugin::OTRS::Perl::LayoutObject) 11 12use strict; 13use warnings; 14 15use Kernel::System::VariableCheck qw(:all); 16 17our @ObjectDependencies = ( 18 'Kernel::Language', 19 'Kernel::Output::HTML::Layout', 20 'Kernel::System::Log', 21); 22 23=head1 NAME 24 25Kernel::System::SysConfig::BaseValueType - Common system configuration value type backend functions. 26 27=head1 PUBLIC INTERFACE 28 29=head2 SettingEffectiveValueCheck() 30 31Check if provided EffectiveValue matches structure defined in XMLContentParsed. 32 33 my %Result = $ValueTypeObject->SettingEffectiveValueCheck( 34 EffectiveValue => 'open', 35 XMLContentParsed => { 36 Value => [ 37 { 38 'Item' => [ 39 { 40 'Content' => "Scalar value", 41 }, 42 ], 43 }, 44 ], 45 }, 46 ); 47 48Result: 49 $Result = ( 50 EffectiveValue => 'open', # Note for common ValueTypes EffectiveValue is not changed. 51 Success => 1, 52 Error => undef, 53 ); 54 55=cut 56 57sub SettingEffectiveValueCheck { 58 my ( $Self, %Param ) = @_; 59 60 for my $Needed (qw(XMLContentParsed)) { 61 if ( !$Param{$Needed} ) { 62 $Kernel::OM->Get('Kernel::System::Log')->Log( 63 Priority => 'error', 64 Message => "Need $Needed!" 65 ); 66 67 return; 68 } 69 } 70 71 my %Result = ( 72 Success => 0, 73 ); 74 75 my $Value = $Param{XMLContentParsed}->{Value}; 76 77 for my $Parameter ( sort keys %{ $Param{Parameters} } ) { 78 if ( !defined $Value->[0]->{Item}->[0]->{$Parameter} ) { 79 $Value->[0]->{Item}->[0]->{$Parameter} = $Param{Parameters}->{$Parameter}; 80 } 81 } 82 83 # Data should be scalar. 84 if ( ref $Param{EffectiveValue} ) { 85 $Result{Error} = 'EffectiveValue must be a scalar!'; 86 return %Result; 87 } 88 89 my $Regex = $Value->[0]->{Item}->[0]->{ValueRegex}; 90 91 # RegEx check - do not use any modifiers for compatibility reasons. 92 if ( $Regex && $Param{EffectiveValue} !~ m{$Regex} ) { 93 $Result{Error} = "EffectiveValue not valid - regex '$Regex'!"; 94 return %Result; 95 } 96 97 $Result{Success} = 1; 98 $Result{EffectiveValue} = $Param{EffectiveValue}; 99 100 return %Result; 101} 102 103=head2 EffectiveValueGet() 104 105Extracts the effective value from a XML parsed setting. 106 107 my $EffectiveValue = $ValueTypeObject->EffectiveValueGet( 108 Value => [ 109 { 110 ValueRegex => '', # (optional) 111 Content => 'TheEffectiveValue', 112 ValueType => 'AValueType', # (optional) 113 # ... 114 } 115 ], 116 ); 117 118Returns: 119 120 $EffectiveValue = 'TheEffectiveValue'; 121 122=cut 123 124sub EffectiveValueGet { 125 my ( $Self, %Param ) = @_; 126 127 if ( !IsArrayRefWithData( $Param{Value} ) ) { 128 $Kernel::OM->Get('Kernel::System::Log')->Log( 129 Priority => 'error', 130 Message => "Value is missing or invalid!", 131 ); 132 133 return ''; 134 } 135 136 if ( scalar @{ $Param{Value} } > 1 ) { 137 $Kernel::OM->Get('Kernel::System::Log')->Log( 138 Priority => 'error', 139 Message => "Value must be a single element!", 140 ); 141 return ''; 142 } 143 144 $Param{Translate} = 0; # common ValueTypes are never translated 145 146 my $Result = $Param{Value}->[0]->{Content} // ''; 147 148 if ( 149 $Result 150 && $Param{Translate} 151 && $Param{Value}->[0]->{Translatable} 152 ) 153 { 154 $Result = $Kernel::OM->Get('Kernel::Language')->Translate($Result); 155 } 156 157 return $Result; 158} 159 160=head2 ModifiedValueGet() 161 162Returns parsed value with updated content(according to EffectiveValue). 163 164 my $ModifiedValue = $ValueTypeObject->ModifiedValueGet( 165 'EffectiveValue' => 'Item 1', 166 'Value' => [ 167 { 168 'Item' => [ 169 { 170 'Content' => 'Default value', 171 'ValueType' => 'String', 172 }, 173 ], 174 }, 175 ], 176 ); 177 178Returns: 179 180 $ModifiedValue = [ 181 { 182 'Item' => [ 183 { 184 'Content' => 'Item 1', 185 'ValueType' => 'String', 186 }, 187 ], 188 }, 189 ]; 190 191=cut 192 193sub ModifiedValueGet { 194 my ( $Self, %Param ) = @_; 195 196 for my $Needed (qw(Value)) { 197 if ( !$Param{$Needed} ) { 198 $Kernel::OM->Get('Kernel::System::Log')->Log( 199 Priority => 'error', 200 Message => "Need $Needed!", 201 ); 202 return; 203 } 204 } 205 206 my $Result = $Param{Value}; 207 208 # Update Content 209 $Result->[0]->{Item}->[0]->{Content} = $Param{EffectiveValue} || ''; 210 211 return $Result; 212} 213 214=head2 SettingRender() 215 216Extracts the effective value from a XML parsed setting. 217 218 my $SettingHTML = $ValueTypeObject->SettingRender( 219 Name => 'SettingName', 220 EffectiveValue => 'Product 6', # (optional) 221 DefaultValue => 'Product 5', # (optional) 222 Class => 'My class' # (optional) 223 Item => [ # (optional) XML parsed item 224 { 225 'ValueType' => 'String', 226 'Content' => 'admin@example.com', 227 'ValueRegex' => '', 228 }, 229 ], 230 RW => 1, # (optional) Allow editing. Default 0. 231 IsArray => 1, # (optional) Item is part of the array 232 IsHash => 1, # (optional) Item is part of the hash 233 IDSuffix => 1, # (optional) Suffix will be added to the element ID 234 SkipEffectiveValueCheck => 1, # (optional) If enabled, system will not perform effective value check. 235 # Default: 1. 236 ); 237 238Returns: 239 240 $SettingHTML = '<div class "Field"...</div>'; 241 242=cut 243 244sub SettingRender { 245 my ( $Self, %Param ) = @_; 246 247 if ( !defined $Param{Name} ) { 248 $Kernel::OM->Get('Kernel::System::Log')->Log( 249 Priority => 'error', 250 Message => "Need Name", 251 ); 252 return; 253 } 254 255 $Param{EffectiveValue} //= ''; 256 $Param{Class} //= ''; 257 $Param{DefaultValue} //= ''; 258 my $IDSuffix = $Param{IDSuffix} || ''; 259 260 my $LanguageObject = $Kernel::OM->Get('Kernel::Language'); 261 262 my $EffectiveValue = $Param{EffectiveValue}; 263 if ( 264 !defined $EffectiveValue 265 && $Param{Item} 266 && $Param{Item}->[0]->{Content} 267 ) 268 { 269 $EffectiveValue = $Param{Item}->[0]->{Content}; 270 } 271 272 my $Regex; 273 if ( $Param{Item}->[0]->{ValueRegex} ) { 274 $Regex = $Param{Item}->[0]->{ValueRegex}; 275 $Param{Class} .= ' Validate_Regex '; 276 } 277 278 my $DefaultValueStrg = $LanguageObject->Translate('Default'); 279 280 my %EffectiveValueCheck = ( 281 Success => 1, 282 ); 283 284 if ( !$Param{SkipEffectiveValueCheck} ) { 285 %EffectiveValueCheck = $Self->SettingEffectiveValueCheck( 286 EffectiveValue => $EffectiveValue, 287 XMLContentParsed => { 288 Value => [ 289 { 290 Item => $Param{Item}, 291 }, 292 ], 293 }, 294 ); 295 } 296 297 my $HTML = '<div class="SettingContent">'; 298 $HTML .= "<input class=\"$Param{Class}\" type=\"text\" name=\"$Param{Name}\" id=\"$Param{Name}$IDSuffix\" "; 299 300 my $HTMLValue = $Kernel::OM->Get('Kernel::Output::HTML::Layout')->Ascii2Html( 301 Text => $EffectiveValue, 302 Type => 'Normal', 303 ); 304 $HTML .= "value=\"$HTMLValue\" "; 305 306 if ($Regex) { 307 $HTML .= "data-regex=\"$Regex\" "; 308 } 309 310 if ( !$Param{RW} ) { 311 $HTML .= "disabled='disabled' "; 312 } 313 314 $HTML .= " />\n"; 315 316 if ( !$EffectiveValueCheck{Success} ) { 317 my $Message = $LanguageObject->Translate("Value is not correct! Please, consider updating this field."); 318 319 $HTML .= $Param{IsValid} ? "<div class='BadEffectiveValue'>\n" : "<div>\n"; 320 $HTML .= "<p>* $Message</p>\n"; 321 $HTML .= "</div>\n"; 322 } 323 324 if ($Regex) { 325 my $Message = $LanguageObject->Translate( 326 "Value doesn't satisfy regex (%s).", $Regex, 327 ); 328 329 $HTML .= "<div class='TooltipErrorMessage' id=\"$Param{Name}$IDSuffix" . "Error\">\n"; 330 $HTML .= "<p>$Message</p>\n"; 331 $HTML .= "</div>\n"; 332 } 333 334 $HTML .= "</div>"; 335 336 if ( !$Param{IsArray} && !$Param{IsHash} ) { 337 $HTML .= <<"EOF"; 338 <div class=\"WidgetMessage Bottom\"> 339 $DefaultValueStrg: $Param{DefaultValue} 340 </div> 341EOF 342 } 343 344 return $HTML; 345} 346 347sub EffectiveValueCalculate { 348 my ( $Self, %Param ) = @_; 349 350 # Check needed stuff. 351 for my $Needed (qw(Name)) { 352 if ( !$Param{$Needed} ) { 353 $Kernel::OM->Get('Kernel::System::Log')->Log( 354 Priority => 'error', 355 Message => "Need $Needed!", 356 ); 357 return; 358 } 359 } 360 361 my $Result = ''; 362 363 if ( $Param{ $Param{Name} } ) { 364 $Result = $Param{ $Param{Name} }; 365 } 366 367 return $Result; 368} 369 370=head2 AddItem() 371 372Generate HTML for new array/hash item. 373 374 my $HTML = $ValueTypeObject->AddItem( 375 Name => 'SettingName', (required) Name 376 DefaultItem => { (optional) DefaultItem hash, if available 377 Item => { 378 Content => 'Value', 379 }, 380 }, 381 ); 382 383Returns: 384 385 $HTML = "<input type='text' id='Setting_ExampleArray' 386 value='Value' name='ExampleArray' class='Entry'/>"; 387 388=cut 389 390sub AddItem { 391 my ( $Self, %Param ) = @_; 392 393 # Check needed stuff. 394 for my $Needed (qw(Name)) { 395 if ( !$Param{$Needed} ) { 396 $Kernel::OM->Get('Kernel::System::Log')->Log( 397 Priority => 'error', 398 Message => "Need $Needed!", 399 ); 400 return; 401 } 402 } 403 404 my $IDSuffix = $Param{IDSuffix} || ''; 405 my $Class = $Param{Class} || ''; 406 407 my $Name = $Param{Name} . $IDSuffix; 408 409 my $DefaultValue = ''; 410 411 if ( $Param{DefaultItem} && $Param{DefaultItem}->{Item} ) { 412 $DefaultValue = $Param{DefaultItem} && $Param{DefaultItem}->{Item}->{Content} || ''; 413 } 414 elsif ( $Param{DefaultItem} ) { 415 $DefaultValue = $Param{DefaultItem} && $Param{DefaultItem}->{Content} || ''; 416 } 417 418 my $RemoveThisEntry = $Kernel::OM->Get('Kernel::Language')->Translate("Remove this entry"); 419 420 my $Result = "<input type='text' id='$Name' 421 value='$DefaultValue' name='$Param{Name}' class='$Class Entry'/>"; 422 423 return $Result; 424} 425 426=head2 ValueAttributeGet() 427 428Returns attribute name in the parsed XML that contains Value. 429 430 my $Result = $ValueTypeObject->ValueAttributeGet(); 431 432Result: 433 $Result = 'Content'; 434 435=cut 436 437sub ValueAttributeGet { 438 my ( $Self, %Param ) = @_; 439 440 return 'Content'; 441} 442 443=head2 DefaultItemAdd() 444 445Return structure of the DefaultItem in case it's not inside of Array or Hash. 446 447 my $DefaultItem = $ValueTypeObject->DefaultItemAdd(); 448 449Returns: 450 451 $DefaultItem = undef; 452 # or 453 $DefaultItem = { 454 Item => { 455 Content => '', 456 }, 457 ValueType => 'VacationDaysOneTime', 458 }; 459 460=cut 461 462sub DefaultItemAdd { 463 my ( $Self, %Param ) = @_; 464 465 # For most ValueTypes there is no such case, so return undef. 466 return; 467} 468 469=head2 ForbiddenValueTypes() 470 471Return array of value types that are not allowed inside this value type. 472 473 my @ForbiddenValueTypes = $ValueTypeObject->ForbiddenValueTypes(); 474 475Returns: 476 477 @ForbiddenValueTypes = ( 478 'Option', 479 ... 480 ); 481 482=cut 483 484sub ForbiddenValueTypes { 485 my ( $Self, %Param ) = @_; 486 487 return (); 488} 489 490=head2 AddSettingContent() 491 492Checks if a div with class 'SettingContent' should be added when adding new item to an array/hash in some special cases. 493 494 my $AddSettingContent = $ValueTypeObject->AddSettingContent(); 495 496Returns: 497 498 my $AddSettingContent = 1; 499 500=cut 501 502sub AddSettingContent { 503 my ( $Self, %Param ) = @_; 504 505 return 1; 506} 507 5081; 509