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::ValueType::Entity; 10## nofilter(TidyAll::Plugin::OTRS::Perl::LayoutObject) 11 12use strict; 13use warnings; 14 15use Kernel::System::VariableCheck qw(:all); 16 17use parent qw(Kernel::System::SysConfig::BaseValueType); 18 19our @ObjectDependencies = ( 20 'Kernel::Language', 21 'Kernel::Output::HTML::Layout', 22 'Kernel::System::Log', 23 'Kernel::System::Main', 24 'Kernel::System::SysConfig::EntityType', 25); 26 27=head1 NAME 28 29Kernel::System::SysConfig::ValueType::Entity - System configuration entity value type backed. 30 31=head1 PUBLIC INTERFACE 32 33=head2 new() 34 35Create an object. Do not use it directly, instead use: 36 37 use Kernel::System::ObjectManager; 38 local $Kernel::OM = Kernel::System::ObjectManager->new(); 39 my $ValueTypeObject = $Kernel::OM->Get('Kernel::System::SysConfig::ValueType::Entity'); 40 41=cut 42 43sub new { 44 my ( $Type, %Param ) = @_; 45 46 # Allocate new hash for object. 47 my $Self = {}; 48 bless( $Self, $Type ); 49 50 return $Self; 51} 52 53=head2 SettingEffectiveValueCheck() 54 55Check if provided EffectiveValue matches structure defined in XMLContentParsed. 56 57 my %Result = $ValueTypeObject->SettingEffectiveValueCheck( 58 XMLContentParsed => { 59 Value => [ 60 { 61 'Item' => [ 62 { 63 'Content' => '3 - normal', 64 'ValueEntityType' => 'Priority', 65 'ValueEntitySubType' => 'SomeSubType', 66 'ValueType' => 'Entity', 67 }, 68 ], 69 }, 70 ], 71 }, 72 EffectiveValue => '2 - low', 73 ); 74 75Result: 76 $Result = ( 77 EffectiveValue => '2 - low', # Note for Entity ValueTypes EffectiveValue is not changed. 78 Success => 1, 79 Error => undef, 80 ); 81 82=cut 83 84sub SettingEffectiveValueCheck { 85 my ( $Self, %Param ) = @_; 86 87 for (qw(XMLContentParsed)) { 88 if ( !$Param{$_} ) { 89 $Kernel::OM->Get('Kernel::System::Log')->Log( 90 Priority => 'error', 91 Message => "Need $_!" 92 ); 93 return; 94 } 95 } 96 97 my %Result = ( 98 Success => 0, 99 ); 100 101 # Data should be scalar. 102 if ( ref $Param{EffectiveValue} ) { 103 $Result{Error} = 'EffectiveValue for Entity must be scalar!'; 104 return %Result; 105 } 106 107 my $Value = $Param{XMLContentParsed}->{Value}; 108 109 for my $Parameter ( sort keys %{ $Param{Parameters} } ) { 110 if ( !defined $Value->[0]->{Item}->[0]->{$Parameter} ) { 111 $Value->[0]->{Item}->[0]->{$Parameter} = $Param{Parameters}->{$Parameter}; 112 } 113 } 114 115 my $EntityType = $Value->[0]->{Item}->[0]->{ValueEntityType}; 116 117 if ( !$EntityType ) { 118 $Result{Error} = 'ValueEntityType not provided!'; 119 return %Result; 120 } 121 122 my $EntitySubType = $Value->[0]->{Item}->[0]->{ValueEntitySubType} || ''; 123 124 my @ValidValues = $Self->EntityValueList( 125 EntityType => $EntityType, 126 EntitySubType => $EntitySubType, 127 ); 128 129 if ( !grep { $_ eq $Param{EffectiveValue} } @ValidValues ) { 130 $Result{Error} = "Entity value is invalid($Param{EffectiveValue})!"; 131 return %Result; 132 } 133 134 $Result{Success} = 1; 135 $Result{EffectiveValue} = $Param{EffectiveValue}; 136 137 return %Result; 138} 139 140=head2 EntityValueList() 141 142Returns a list of valid values for provided EntityType. 143 144 my $Result = $ValueTypeObject->EntityValueList( 145 EntityType => 'Priority', 146 EntitySubType => 'SomeSubtype', # optional e.g. the ObjectType for DynamicField entities 147 ); 148 149Returns: 150 151 $Result = [ 152 '1 very low', 153 '2 low', 154 '3 medium', 155 '4 high', 156 '5 very high', 157 ]; 158 159=cut 160 161sub EntityValueList { 162 my ( $Self, %Param ) = @_; 163 164 for my $Needed (qw(EntityType)) { 165 if ( !$Param{$Needed} ) { 166 $Kernel::OM->Get('Kernel::System::Log')->Log( 167 Priority => 'error', 168 Message => "Need $Needed!", 169 ); 170 return; 171 } 172 } 173 174 my $Loaded = $Kernel::OM->Get('Kernel::System::Main')->Require( 175 "Kernel::System::SysConfig::ValueType::Entity::$Param{EntityType}", 176 ); 177 178 return [] if !$Loaded; 179 180 my $BackendObject = $Kernel::OM->Get( 181 "Kernel::System::SysConfig::ValueType::Entity::$Param{EntityType}", 182 ); 183 184 return $BackendObject->EntityValueList(%Param); 185} 186 187=head2 SettingRender() 188 189Extracts the effective value from a XML parsed setting. 190 191 my $SettingHTML = $ValueTypeObject->SettingRender( 192 Name => 'SettingName', 193 EffectiveValue => '3 medium', # (optional) 194 DefaultValue => '3 medium', # (optional) 195 Class => 'My class' # (optional) 196 RW => 1, # (optional) Allow editing. Default 0. 197 Item => [ # (optional) XML parsed item 198 { 199 'ValueType' => 'Entity', 200 'ValueEntityType' => 'Priority', 201 'ValueEntitySubType' => 'SomeSubType', 202 'Content' => '2 low', 203 }, 204 ], 205 IsArray => 1, # (optional) Item is part of the array 206 IsHash => 1, # (optional) Item is part of the hash 207 SkipEffectiveValueCheck => 1, # (optional) If enabled, system will not perform effective value check. 208 # Default: 1. 209 ); 210 211Returns: 212 213 $SettingHTML = '<div class "Field"...</div>'; 214 215=cut 216 217sub SettingRender { 218 my ( $Self, %Param ) = @_; 219 220 if ( !defined $Param{Name} ) { 221 $Kernel::OM->Get('Kernel::System::Log')->Log( 222 Priority => 'error', 223 Message => "Need Name", 224 ); 225 return; 226 } 227 228 $Param{Class} //= ''; 229 $Param{DefaultValue} //= ''; 230 $Param{IDSuffix} //= ''; 231 232 my $LanguageObject = $Kernel::OM->Get('Kernel::Language'); 233 234 my $Value = $Param{Value}; 235 236 my $EntityType; 237 my $EntitySubType; 238 239 my $EffectiveValue = $Param{EffectiveValue}; 240 if ( 241 !defined $EffectiveValue 242 && $Param{Item}->[0]->{Content} 243 ) 244 { 245 $EffectiveValue = $Param{Item}->[0]->{Content}; 246 } 247 248 if ( 249 $Param{Item} 250 && $Param{Item}->[0]->{ValueEntityType} 251 ) 252 { 253 $EntityType = $Param{Item}->[0]->{ValueEntityType}; 254 $EntitySubType = $Param{Item}->[0]->{ValueEntitySubType} || ''; 255 } 256 elsif ( 257 $Value->[0]->{Item} 258 && $Value->[0]->{Item}->[0]->{ValueEntityType} 259 ) 260 { 261 $EntityType = $Value->[0]->{Item}->[0]->{ValueEntityType}; 262 $EntitySubType = $Value->[0]->{Item}->[0]->{ValueEntitySubType} || ''; 263 } 264 elsif ( $Value->[0]->{Array} ) { 265 $EntityType = $Value->[0]->{Array}->[0]->{DefaultItem}->[0]->{ValueEntityType}; 266 $EntitySubType = $Value->[0]->{Array}->[0]->{DefaultItem}->[0]->{ValueEntitySubType} || ''; 267 } 268 elsif ( $Value->[0]->{Hash} ) { 269 if ( 270 $Value->[0]->{Hash}->[0]->{DefaultItem} 271 && $Value->[0]->{Hash}->[0]->{DefaultItem}->[0]->{ValueEntityType} 272 ) 273 { 274 275 # take ValueEntityType from DefaultItem 276 $EntityType = $Value->[0]->{Hash}->[0]->{DefaultItem}->[0]->{ValueEntityType}; 277 $EntitySubType = $Value->[0]->{Hash}->[0]->{DefaultItem}->[0]->{ValueEntitySubType} || ''; 278 } 279 else { 280 # check if there is definition for certain key 281 ITEM: 282 for my $Item ( @{ $Value->[0]->{Hash}->[0]->{Item} } ) { 283 if ( $Item->{Key} eq $Param{Key} ) { 284 $EntityType = $Item->{ValueEntityType} || ''; 285 $EntitySubType = $Item->{ValueEntitySubType} || ''; 286 last ITEM; 287 } 288 } 289 } 290 } 291 292 my @EntityValues = $Self->EntityValueList( 293 EntityType => $EntityType, 294 EntitySubType => $EntitySubType, 295 ); 296 297 # When displaying diff between current and old value, it can happen that value is missing 298 # since it was renamed, or removed. In this case, we need to add this "old" value also. 299 if ( 300 $EffectiveValue 301 && !grep { $_ eq $EffectiveValue } @EntityValues 302 ) 303 { 304 push @EntityValues, $EffectiveValue; 305 } 306 307 my %EffectiveValueCheck = ( 308 Success => 1, 309 ); 310 311 if ( !$Param{SkipEffectiveValueCheck} ) { 312 %EffectiveValueCheck = $Self->SettingEffectiveValueCheck( 313 EffectiveValue => $EffectiveValue, 314 XMLContentParsed => { 315 Value => [ 316 { 317 Item => $Param{Item}, 318 }, 319 ], 320 }, 321 ); 322 } 323 324 my $HTML = "<div class='SettingContent'>\n"; 325 $HTML .= $Kernel::OM->Get('Kernel::Output::HTML::Layout')->BuildSelection( 326 Data => \@EntityValues, 327 Name => $Param{Name}, 328 ID => $Param{Name} . $Param{IDSuffix}, 329 Disabled => $Param{RW} ? 0 : 1, 330 SelectedValue => $EffectiveValue, 331 Title => $Param{Name}, 332 OptionTitle => 1, 333 Class => "$Param{Class} Modernize", 334 ); 335 336 if ( !$EffectiveValueCheck{Success} ) { 337 my $Message = $LanguageObject->Translate("Value is not correct! Please, consider updating this field."); 338 339 $HTML .= $Param{IsValid} ? "<div class='BadEffectiveValue'>\n" : "<div>\n"; 340 $HTML .= "<p>* $Message</p>\n"; 341 $HTML .= "</div>\n"; 342 } 343 344 $HTML .= "</div>\n"; 345 346 if ( !$Param{IsArray} && !$Param{IsHash} ) { 347 my $DefaultText = $LanguageObject->Translate('Default'); 348 349 $HTML .= <<"EOF"; 350 <div class=\"WidgetMessage Bottom\"> 351 $DefaultText: $Param{DefaultValue} 352 </div> 353EOF 354 } 355 356 return $HTML; 357} 358 359=head2 AddItem() 360 361Generate HTML for new array/hash item. 362 363 my $HTML = $ValueTypeObject->AddItem( 364 Name => 'SettingName', (required) Name 365 DefaultItem => { (required) DefaultItem hash 366 'Content' => '3 normal', 367 'ValueType' => 'Entity', 368 'ValueEntityType' => 'Priority', 369 'ValueEntitySubType' => 'SomeSubType', 370 }, 371 IDSuffix => '_Array1', (optional) IDSuffix is needed for arrays and hashes. 372 ); 373 374Returns: 375 376 $HTML = '<select class="Modernize" id="SettingName" name="SettingName" title="SettingName"> 377 ... 378 </select>'; 379 380=cut 381 382sub AddItem { 383 my ( $Self, %Param ) = @_; 384 385 # Check needed stuff. 386 for my $Needed (qw(Name DefaultItem)) { 387 if ( !$Param{$Needed} ) { 388 $Kernel::OM->Get('Kernel::System::Log')->Log( 389 Priority => 'error', 390 Message => "Need $Needed!", 391 ); 392 return; 393 } 394 } 395 396 $Param{Class} //= ''; 397 $Param{IDSuffix} //= ''; 398 399 my @EntityValues = $Self->EntityValueList( 400 EntityType => $Param{DefaultItem}->{ValueEntityType}, 401 EntitySubType => $Param{DefaultItem}->{ValueEntitySubType} || '', 402 ); 403 404 my $Result = $Kernel::OM->Get('Kernel::Output::HTML::Layout')->BuildSelection( 405 Data => \@EntityValues, 406 Name => $Param{Name}, 407 ID => $Param{Name} . $Param{IDSuffix}, 408 SelectedValue => $Param{DefaultItem}->{Content}, 409 Title => $Param{Name}, 410 OptionTitle => 1, 411 Class => "$Param{Class} Modernize Entry", 412 ); 413 414 return $Result; 415} 416 417=head2 EntityLookupFromWebRequest() 418 419Gets the entity name from the web request 420 421Called URL: index.pl?Action=AdminQueue;Subaction=Change;QueueID=1 422 423 my $EntityName = $ValueTypeObject->EntityLookupFromWebRequest( 424 EntityType => 'Queue', 425 ); 426 427Returns: 428 429 $EntityName = 'Postmaster'; 430 431=cut 432 433sub EntityLookupFromWebRequest { 434 my ( $Self, %Param ) = @_; 435 436 for my $Needed (qw(EntityType)) { 437 if ( !$Param{$Needed} ) { 438 $Kernel::OM->Get('Kernel::System::Log')->Log( 439 Priority => 'error', 440 Message => "Need $Needed!", 441 ); 442 return; 443 } 444 } 445 446 my $Loaded = $Kernel::OM->Get('Kernel::System::Main')->Require( 447 "Kernel::System::SysConfig::ValueType::Entity::$Param{EntityType}", 448 ); 449 450 return if !$Loaded; 451 452 my $BackendObject = $Kernel::OM->Get( 453 "Kernel::System::SysConfig::ValueType::Entity::$Param{EntityType}", 454 ); 455 456 return if !$BackendObject->can('EntityLookupFromWebRequest'); 457 458 return $BackendObject->EntityLookupFromWebRequest(); 459} 460 4611; 462 463=head1 TERMS AND CONDITIONS 464 465This software is part of the OTRS project (L<https://otrs.org/>). 466 467This software comes with ABSOLUTELY NO WARRANTY. For details, see 468the enclosed file COPYING for license information (GPL). If you 469did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>. 470 471=cut 472