mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge branch 'develop' into feature/b3217-2dev
This commit is contained in:
646
.editorconfig
646
.editorconfig
@@ -1,3 +1,5 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
@@ -11,7 +13,7 @@ ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
ij_smart_tabs = false
|
||||
ij_visual_guides = 80, 120, 140
|
||||
ij_visual_guides = 140
|
||||
ij_wrap_on_typing = true
|
||||
|
||||
[*.css]
|
||||
@@ -33,53 +35,9 @@ ij_css_space_after_colon = true
|
||||
ij_css_space_before_opening_brace = true
|
||||
ij_css_value_alignment = 0
|
||||
|
||||
[*.csv]
|
||||
max_line_length = 2147483647
|
||||
ij_wrap_on_typing = false
|
||||
ij_csv_wrap_long_lines = false
|
||||
|
||||
[*.feature]
|
||||
indent_size = 2
|
||||
ij_gherkin_keep_indents_on_empty_lines = false
|
||||
|
||||
[*.less]
|
||||
indent_size = 2
|
||||
ij_less_align_closing_brace_with_properties = false
|
||||
ij_less_blank_lines_around_nested_selector = 1
|
||||
ij_less_blank_lines_between_blocks = 1
|
||||
ij_less_brace_placement = 0
|
||||
ij_less_hex_color_long_format = false
|
||||
ij_less_hex_color_lower_case = false
|
||||
ij_less_hex_color_short_format = false
|
||||
ij_less_hex_color_upper_case = false
|
||||
ij_less_keep_blank_lines_in_code = 2
|
||||
ij_less_keep_indents_on_empty_lines = false
|
||||
ij_less_keep_single_line_blocks = false
|
||||
ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||
ij_less_space_after_colon = true
|
||||
ij_less_space_before_opening_brace = true
|
||||
ij_less_value_alignment = 0
|
||||
|
||||
[*.sass]
|
||||
indent_size = 2
|
||||
ij_sass_align_closing_brace_with_properties = false
|
||||
ij_sass_blank_lines_around_nested_selector = 1
|
||||
ij_sass_blank_lines_between_blocks = 1
|
||||
ij_sass_brace_placement = 0
|
||||
ij_sass_hex_color_long_format = false
|
||||
ij_sass_hex_color_lower_case = false
|
||||
ij_sass_hex_color_short_format = false
|
||||
ij_sass_hex_color_upper_case = false
|
||||
ij_sass_keep_blank_lines_in_code = 2
|
||||
ij_sass_keep_indents_on_empty_lines = false
|
||||
ij_sass_keep_single_line_blocks = false
|
||||
ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||
ij_sass_space_after_colon = true
|
||||
ij_sass_space_before_opening_brace = true
|
||||
ij_sass_value_alignment = 0
|
||||
|
||||
[*.scss]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_scss_align_closing_brace_with_properties = false
|
||||
ij_scss_blank_lines_around_nested_selector = 1
|
||||
ij_scss_blank_lines_between_blocks = 1
|
||||
@@ -99,7 +57,6 @@ ij_scss_value_alignment = 0
|
||||
[*.twig]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_wrap_on_typing = false
|
||||
ij_twig_keep_indents_on_empty_lines = false
|
||||
ij_twig_spaces_inside_delimiters = true
|
||||
ij_twig_spaces_inside_variable_delimiters = true
|
||||
@@ -112,7 +69,212 @@ ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.cjs,*.js}]
|
||||
[{*.ctp,*.phtml,*.module,*.php,*.php5,*.php4,*.hphp,*.inc}]
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 4
|
||||
ij_smart_tabs = true
|
||||
ij_wrap_on_typing = false
|
||||
ij_php_align_assignments = false
|
||||
ij_php_align_class_constants = false
|
||||
ij_php_align_group_field_declarations = false
|
||||
ij_php_align_inline_comments = false
|
||||
ij_php_align_key_value_pairs = false
|
||||
ij_php_align_multiline_array_initializer_expression = false
|
||||
ij_php_align_multiline_binary_operation = false
|
||||
ij_php_align_multiline_chained_methods = false
|
||||
ij_php_align_multiline_extends_list = false
|
||||
ij_php_align_multiline_for = true
|
||||
ij_php_align_multiline_parameters = false
|
||||
ij_php_align_multiline_parameters_in_calls = false
|
||||
ij_php_align_multiline_ternary_operation = false
|
||||
ij_php_align_phpdoc_comments = false
|
||||
ij_php_align_phpdoc_param_names = false
|
||||
ij_php_api_weight = 1
|
||||
ij_php_array_initializer_new_line_after_left_brace = true
|
||||
ij_php_array_initializer_right_brace_on_new_line = true
|
||||
ij_php_array_initializer_wrap = on_every_item
|
||||
ij_php_assignment_wrap = off
|
||||
ij_php_author_weight = 7
|
||||
ij_php_binary_operation_sign_on_next_line = false
|
||||
ij_php_binary_operation_wrap = off
|
||||
ij_php_blank_lines_after_class_header = 0
|
||||
ij_php_blank_lines_after_function = 1
|
||||
ij_php_blank_lines_after_imports = 1
|
||||
ij_php_blank_lines_after_opening_tag = 0
|
||||
ij_php_blank_lines_after_package = 1
|
||||
ij_php_blank_lines_around_class = 1
|
||||
ij_php_blank_lines_around_constants = 0
|
||||
ij_php_blank_lines_around_field = 0
|
||||
ij_php_blank_lines_around_method = 1
|
||||
ij_php_blank_lines_before_class_end = 0
|
||||
ij_php_blank_lines_before_imports = 1
|
||||
ij_php_blank_lines_before_method_body = 0
|
||||
ij_php_blank_lines_before_package = 1
|
||||
ij_php_blank_lines_before_return_statement = 1
|
||||
ij_php_block_brace_style = end_of_line
|
||||
ij_php_call_parameters_new_line_after_left_paren = false
|
||||
ij_php_call_parameters_right_paren_on_new_line = false
|
||||
ij_php_call_parameters_wrap = normal
|
||||
ij_php_catch_on_new_line = false
|
||||
ij_php_category_weight = 28
|
||||
ij_php_class_brace_style = end_of_line
|
||||
ij_php_comma_after_last_array_element = true
|
||||
ij_php_concat_spaces = false
|
||||
ij_php_copyright_weight = 28
|
||||
ij_php_deprecated_weight = 28
|
||||
ij_php_do_while_brace_force = always
|
||||
ij_php_else_if_style = as_is
|
||||
ij_php_else_on_new_line = true
|
||||
ij_php_example_weight = 3
|
||||
ij_php_extends_keyword_wrap = off
|
||||
ij_php_extends_list_wrap = off
|
||||
ij_php_fields_default_visibility = private
|
||||
ij_php_filesource_weight = 28
|
||||
ij_php_finally_on_new_line = false
|
||||
ij_php_for_brace_force = always
|
||||
ij_php_for_statement_new_line_after_left_paren = false
|
||||
ij_php_for_statement_right_paren_on_new_line = false
|
||||
ij_php_for_statement_wrap = off
|
||||
ij_php_force_short_declaration_array_style = false
|
||||
ij_php_global_weight = 28
|
||||
ij_php_group_use_wrap = on_every_item
|
||||
ij_php_if_brace_force = always
|
||||
ij_php_if_lparen_on_next_line = false
|
||||
ij_php_if_rparen_on_next_line = false
|
||||
ij_php_ignore_weight = 28
|
||||
ij_php_import_sorting = alphabetic
|
||||
ij_php_indent_break_from_case = true
|
||||
ij_php_indent_case_from_switch = true
|
||||
ij_php_indent_code_in_php_tags = false
|
||||
ij_php_internal_weight = 0
|
||||
ij_php_keep_blank_lines_after_lbrace = 2
|
||||
ij_php_keep_blank_lines_before_right_brace = 2
|
||||
ij_php_keep_blank_lines_in_code = 2
|
||||
ij_php_keep_blank_lines_in_declarations = 2
|
||||
ij_php_keep_control_statement_in_one_line = true
|
||||
ij_php_keep_first_column_comment = true
|
||||
ij_php_keep_indents_on_empty_lines = false
|
||||
ij_php_keep_line_breaks = true
|
||||
ij_php_keep_rparen_and_lbrace_on_one_line = true
|
||||
ij_php_keep_simple_methods_in_one_line = false
|
||||
ij_php_lambda_brace_style = end_of_line
|
||||
ij_php_license_weight = 28
|
||||
ij_php_line_comment_add_space = false
|
||||
ij_php_line_comment_at_first_column = true
|
||||
ij_php_link_weight = 28
|
||||
ij_php_lower_case_boolean_const = true
|
||||
ij_php_lower_case_null_const = true
|
||||
ij_php_method_brace_style = end_of_line
|
||||
ij_php_method_call_chain_wrap = off
|
||||
ij_php_method_parameters_new_line_after_left_paren = true
|
||||
ij_php_method_parameters_right_paren_on_new_line = true
|
||||
ij_php_method_parameters_wrap = normal
|
||||
ij_php_method_weight = 28
|
||||
ij_php_modifier_list_wrap = false
|
||||
ij_php_multiline_chained_calls_semicolon_on_new_line = false
|
||||
ij_php_namespace_brace_style = 1
|
||||
ij_php_null_type_position = in_the_end
|
||||
ij_php_package_weight = 28
|
||||
ij_php_param_weight = 4
|
||||
ij_php_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_php_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_php_phpdoc_blank_line_before_tags = true
|
||||
ij_php_phpdoc_blank_lines_around_parameters = true
|
||||
ij_php_phpdoc_keep_blank_lines = true
|
||||
ij_php_phpdoc_param_spaces_between_name_and_description = 1
|
||||
ij_php_phpdoc_param_spaces_between_tag_and_type = 1
|
||||
ij_php_phpdoc_param_spaces_between_type_and_name = 1
|
||||
ij_php_phpdoc_use_fqcn = true
|
||||
ij_php_phpdoc_wrap_long_lines = true
|
||||
ij_php_place_assignment_sign_on_next_line = false
|
||||
ij_php_place_parens_for_constructor = 0
|
||||
ij_php_property_read_weight = 28
|
||||
ij_php_property_weight = 28
|
||||
ij_php_property_write_weight = 28
|
||||
ij_php_return_type_on_new_line = false
|
||||
ij_php_return_weight = 5
|
||||
ij_php_see_weight = 2
|
||||
ij_php_since_weight = 28
|
||||
ij_php_sort_phpdoc_elements = true
|
||||
ij_php_space_after_colon = true
|
||||
ij_php_space_after_colon_in_return_type = true
|
||||
ij_php_space_after_comma = true
|
||||
ij_php_space_after_for_semicolon = true
|
||||
ij_php_space_after_quest = true
|
||||
ij_php_space_after_type_cast = false
|
||||
ij_php_space_after_unary_not = false
|
||||
ij_php_space_before_array_initializer_left_brace = false
|
||||
ij_php_space_before_catch_keyword = true
|
||||
ij_php_space_before_catch_left_brace = true
|
||||
ij_php_space_before_catch_parentheses = true
|
||||
ij_php_space_before_class_left_brace = true
|
||||
ij_php_space_before_closure_left_parenthesis = true
|
||||
ij_php_space_before_colon = true
|
||||
ij_php_space_before_colon_in_return_type = false
|
||||
ij_php_space_before_comma = false
|
||||
ij_php_space_before_do_left_brace = true
|
||||
ij_php_space_before_else_keyword = true
|
||||
ij_php_space_before_else_left_brace = true
|
||||
ij_php_space_before_finally_keyword = true
|
||||
ij_php_space_before_finally_left_brace = true
|
||||
ij_php_space_before_for_left_brace = true
|
||||
ij_php_space_before_for_parentheses = true
|
||||
ij_php_space_before_for_semicolon = false
|
||||
ij_php_space_before_if_left_brace = true
|
||||
ij_php_space_before_if_parentheses = true
|
||||
ij_php_space_before_method_call_parentheses = false
|
||||
ij_php_space_before_method_left_brace = true
|
||||
ij_php_space_before_method_parentheses = false
|
||||
ij_php_space_before_quest = true
|
||||
ij_php_space_before_switch_left_brace = true
|
||||
ij_php_space_before_switch_parentheses = true
|
||||
ij_php_space_before_try_left_brace = true
|
||||
ij_php_space_before_unary_not = false
|
||||
ij_php_space_before_while_keyword = true
|
||||
ij_php_space_before_while_left_brace = true
|
||||
ij_php_space_before_while_parentheses = true
|
||||
ij_php_space_between_ternary_quest_and_colon = false
|
||||
ij_php_spaces_around_additive_operators = true
|
||||
ij_php_spaces_around_arrow = false
|
||||
ij_php_spaces_around_assignment_in_declare = false
|
||||
ij_php_spaces_around_assignment_operators = true
|
||||
ij_php_spaces_around_bitwise_operators = true
|
||||
ij_php_spaces_around_equality_operators = true
|
||||
ij_php_spaces_around_logical_operators = true
|
||||
ij_php_spaces_around_multiplicative_operators = true
|
||||
ij_php_spaces_around_null_coalesce_operator = true
|
||||
ij_php_spaces_around_relational_operators = true
|
||||
ij_php_spaces_around_shift_operators = true
|
||||
ij_php_spaces_around_unary_operator = false
|
||||
ij_php_spaces_around_var_within_brackets = false
|
||||
ij_php_spaces_within_array_initializer_braces = false
|
||||
ij_php_spaces_within_brackets = false
|
||||
ij_php_spaces_within_catch_parentheses = false
|
||||
ij_php_spaces_within_for_parentheses = false
|
||||
ij_php_spaces_within_if_parentheses = false
|
||||
ij_php_spaces_within_method_call_parentheses = false
|
||||
ij_php_spaces_within_method_parentheses = false
|
||||
ij_php_spaces_within_parentheses = false
|
||||
ij_php_spaces_within_short_echo_tags = true
|
||||
ij_php_spaces_within_switch_parentheses = false
|
||||
ij_php_spaces_within_while_parentheses = false
|
||||
ij_php_special_else_if_treatment = false
|
||||
ij_php_subpackage_weight = 28
|
||||
ij_php_ternary_operation_signs_on_next_line = false
|
||||
ij_php_ternary_operation_wrap = off
|
||||
ij_php_throws_weight = 6
|
||||
ij_php_todo_weight = 28
|
||||
ij_php_unknown_tag_weight = 28
|
||||
ij_php_upper_case_boolean_const = false
|
||||
ij_php_upper_case_null_const = false
|
||||
ij_php_uses_weight = 28
|
||||
ij_php_var_weight = 28
|
||||
ij_php_variable_naming_style = mixed
|
||||
ij_php_version_weight = 28
|
||||
ij_php_while_brace_force = always
|
||||
ij_php_while_on_new_line = false
|
||||
|
||||
[{*.js,*.cjs}]
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 4
|
||||
ij_smart_tabs = true
|
||||
@@ -134,13 +296,13 @@ ij_javascript_array_initializer_wrap = off
|
||||
ij_javascript_assignment_wrap = off
|
||||
ij_javascript_binary_operation_sign_on_next_line = false
|
||||
ij_javascript_binary_operation_wrap = off
|
||||
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**/*
|
||||
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**/*,@angular/material,@angular/material/typings/**
|
||||
ij_javascript_blank_lines_after_imports = 1
|
||||
ij_javascript_blank_lines_around_class = 1
|
||||
ij_javascript_blank_lines_around_field = 0
|
||||
ij_javascript_blank_lines_around_function = 1
|
||||
ij_javascript_blank_lines_around_method = 1
|
||||
ij_javascript_block_brace_style = next_line
|
||||
ij_javascript_block_brace_style = end_of_line
|
||||
ij_javascript_call_parameters_new_line_after_left_paren = false
|
||||
ij_javascript_call_parameters_right_paren_on_new_line = false
|
||||
ij_javascript_call_parameters_wrap = off
|
||||
@@ -148,7 +310,7 @@ ij_javascript_catch_on_new_line = false
|
||||
ij_javascript_chained_call_dot_on_new_line = true
|
||||
ij_javascript_class_brace_style = end_of_line
|
||||
ij_javascript_comma_on_new_line = false
|
||||
ij_javascript_do_while_brace_force = never
|
||||
ij_javascript_do_while_brace_force = always
|
||||
ij_javascript_else_on_new_line = true
|
||||
ij_javascript_enforce_trailing_comma = keep
|
||||
ij_javascript_extends_keyword_wrap = off
|
||||
@@ -156,7 +318,7 @@ ij_javascript_extends_list_wrap = off
|
||||
ij_javascript_field_prefix = _
|
||||
ij_javascript_file_name_style = relaxed
|
||||
ij_javascript_finally_on_new_line = false
|
||||
ij_javascript_for_brace_force = never
|
||||
ij_javascript_for_brace_force = always
|
||||
ij_javascript_for_statement_new_line_after_left_paren = false
|
||||
ij_javascript_for_statement_right_paren_on_new_line = false
|
||||
ij_javascript_for_statement_wrap = off
|
||||
@@ -272,216 +434,11 @@ ij_javascript_use_path_mapping = always
|
||||
ij_javascript_use_public_modifier = false
|
||||
ij_javascript_use_semicolon_after_statement = true
|
||||
ij_javascript_var_declaration_wrap = normal
|
||||
ij_javascript_while_brace_force = never
|
||||
ij_javascript_while_brace_force = always
|
||||
ij_javascript_while_on_new_line = false
|
||||
ij_javascript_wrap_comments = false
|
||||
|
||||
[{*.module,*.hphp,*.phtml,*.php5,*.php4,*.php,*.ctp,*.inc}]
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 4
|
||||
ij_smart_tabs = true
|
||||
ij_wrap_on_typing = false
|
||||
ij_php_align_assignments = false
|
||||
ij_php_align_class_constants = false
|
||||
ij_php_align_group_field_declarations = false
|
||||
ij_php_align_inline_comments = false
|
||||
ij_php_align_key_value_pairs = false
|
||||
ij_php_align_multiline_array_initializer_expression = false
|
||||
ij_php_align_multiline_binary_operation = false
|
||||
ij_php_align_multiline_chained_methods = false
|
||||
ij_php_align_multiline_extends_list = false
|
||||
ij_php_align_multiline_for = true
|
||||
ij_php_align_multiline_parameters = false
|
||||
ij_php_align_multiline_parameters_in_calls = false
|
||||
ij_php_align_multiline_ternary_operation = false
|
||||
ij_php_align_phpdoc_comments = false
|
||||
ij_php_align_phpdoc_param_names = false
|
||||
ij_php_api_weight = 1
|
||||
ij_php_array_initializer_new_line_after_left_brace = true
|
||||
ij_php_array_initializer_right_brace_on_new_line = true
|
||||
ij_php_array_initializer_wrap = on_every_item
|
||||
ij_php_assignment_wrap = off
|
||||
ij_php_author_weight = 7
|
||||
ij_php_binary_operation_sign_on_next_line = false
|
||||
ij_php_binary_operation_wrap = off
|
||||
ij_php_blank_lines_after_class_header = 0
|
||||
ij_php_blank_lines_after_function = 1
|
||||
ij_php_blank_lines_after_imports = 1
|
||||
ij_php_blank_lines_after_opening_tag = 0
|
||||
ij_php_blank_lines_after_package = 1
|
||||
ij_php_blank_lines_around_class = 1
|
||||
ij_php_blank_lines_around_constants = 0
|
||||
ij_php_blank_lines_around_field = 0
|
||||
ij_php_blank_lines_around_method = 1
|
||||
ij_php_blank_lines_before_class_end = 0
|
||||
ij_php_blank_lines_before_imports = 1
|
||||
ij_php_blank_lines_before_method_body = 0
|
||||
ij_php_blank_lines_before_package = 1
|
||||
ij_php_blank_lines_before_return_statement = 1
|
||||
ij_php_block_brace_style = next_line
|
||||
ij_php_call_parameters_new_line_after_left_paren = false
|
||||
ij_php_call_parameters_right_paren_on_new_line = false
|
||||
ij_php_call_parameters_wrap = normal
|
||||
ij_php_catch_on_new_line = true
|
||||
ij_php_category_weight = 28
|
||||
ij_php_class_brace_style = next_line
|
||||
ij_php_comma_after_last_array_element = true
|
||||
ij_php_concat_spaces = false
|
||||
ij_php_copyright_weight = 28
|
||||
ij_php_deprecated_weight = 28
|
||||
ij_php_do_while_brace_force = always
|
||||
ij_php_else_if_style = as_is
|
||||
ij_php_else_on_new_line = true
|
||||
ij_php_example_weight = 3
|
||||
ij_php_extends_keyword_wrap = off
|
||||
ij_php_extends_list_wrap = off
|
||||
ij_php_fields_default_visibility = private
|
||||
ij_php_filesource_weight = 28
|
||||
ij_php_finally_on_new_line = true
|
||||
ij_php_for_brace_force = always
|
||||
ij_php_for_statement_new_line_after_left_paren = false
|
||||
ij_php_for_statement_right_paren_on_new_line = false
|
||||
ij_php_for_statement_wrap = off
|
||||
ij_php_force_short_declaration_array_style = false
|
||||
ij_php_global_weight = 28
|
||||
ij_php_group_use_wrap = on_every_item
|
||||
ij_php_if_brace_force = always
|
||||
ij_php_if_lparen_on_next_line = false
|
||||
ij_php_if_rparen_on_next_line = false
|
||||
ij_php_ignore_weight = 28
|
||||
ij_php_import_sorting = alphabetic
|
||||
ij_php_indent_break_from_case = true
|
||||
ij_php_indent_case_from_switch = true
|
||||
ij_php_indent_code_in_php_tags = false
|
||||
ij_php_internal_weight = 0
|
||||
ij_php_keep_blank_lines_after_lbrace = 2
|
||||
ij_php_keep_blank_lines_before_right_brace = 2
|
||||
ij_php_keep_blank_lines_in_code = 2
|
||||
ij_php_keep_blank_lines_in_declarations = 2
|
||||
ij_php_keep_control_statement_in_one_line = true
|
||||
ij_php_keep_first_column_comment = true
|
||||
ij_php_keep_indents_on_empty_lines = false
|
||||
ij_php_keep_line_breaks = true
|
||||
ij_php_keep_rparen_and_lbrace_on_one_line = true
|
||||
ij_php_keep_simple_methods_in_one_line = false
|
||||
ij_php_lambda_brace_style = end_of_line
|
||||
ij_php_license_weight = 28
|
||||
ij_php_line_comment_add_space = false
|
||||
ij_php_line_comment_at_first_column = true
|
||||
ij_php_link_weight = 28
|
||||
ij_php_lower_case_boolean_const = true
|
||||
ij_php_lower_case_null_const = true
|
||||
ij_php_method_brace_style = next_line
|
||||
ij_php_method_call_chain_wrap = off
|
||||
ij_php_method_parameters_new_line_after_left_paren = true
|
||||
ij_php_method_parameters_right_paren_on_new_line = true
|
||||
ij_php_method_parameters_wrap = normal
|
||||
ij_php_method_weight = 28
|
||||
ij_php_modifier_list_wrap = false
|
||||
ij_php_multiline_chained_calls_semicolon_on_new_line = false
|
||||
ij_php_namespace_brace_style = 1
|
||||
ij_php_null_type_position = in_the_end
|
||||
ij_php_package_weight = 28
|
||||
ij_php_param_weight = 4
|
||||
ij_php_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_php_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_php_phpdoc_blank_line_before_tags = true
|
||||
ij_php_phpdoc_blank_lines_around_parameters = true
|
||||
ij_php_phpdoc_keep_blank_lines = true
|
||||
ij_php_phpdoc_param_spaces_between_name_and_description = 1
|
||||
ij_php_phpdoc_param_spaces_between_tag_and_type = 1
|
||||
ij_php_phpdoc_param_spaces_between_type_and_name = 1
|
||||
ij_php_phpdoc_use_fqcn = true
|
||||
ij_php_phpdoc_wrap_long_lines = true
|
||||
ij_php_place_assignment_sign_on_next_line = false
|
||||
ij_php_place_parens_for_constructor = 0
|
||||
ij_php_property_read_weight = 28
|
||||
ij_php_property_weight = 28
|
||||
ij_php_property_write_weight = 28
|
||||
ij_php_return_type_on_new_line = false
|
||||
ij_php_return_weight = 5
|
||||
ij_php_see_weight = 2
|
||||
ij_php_since_weight = 28
|
||||
ij_php_sort_phpdoc_elements = true
|
||||
ij_php_space_after_colon = true
|
||||
ij_php_space_after_colon_in_return_type = true
|
||||
ij_php_space_after_comma = true
|
||||
ij_php_space_after_for_semicolon = true
|
||||
ij_php_space_after_quest = true
|
||||
ij_php_space_after_type_cast = false
|
||||
ij_php_space_after_unary_not = false
|
||||
ij_php_space_before_array_initializer_left_brace = false
|
||||
ij_php_space_before_catch_keyword = true
|
||||
ij_php_space_before_catch_left_brace = true
|
||||
ij_php_space_before_catch_parentheses = true
|
||||
ij_php_space_before_class_left_brace = true
|
||||
ij_php_space_before_closure_left_parenthesis = true
|
||||
ij_php_space_before_colon = true
|
||||
ij_php_space_before_colon_in_return_type = false
|
||||
ij_php_space_before_comma = false
|
||||
ij_php_space_before_do_left_brace = true
|
||||
ij_php_space_before_else_keyword = true
|
||||
ij_php_space_before_else_left_brace = true
|
||||
ij_php_space_before_finally_keyword = true
|
||||
ij_php_space_before_finally_left_brace = true
|
||||
ij_php_space_before_for_left_brace = true
|
||||
ij_php_space_before_for_parentheses = true
|
||||
ij_php_space_before_for_semicolon = false
|
||||
ij_php_space_before_if_left_brace = true
|
||||
ij_php_space_before_if_parentheses = true
|
||||
ij_php_space_before_method_call_parentheses = false
|
||||
ij_php_space_before_method_left_brace = true
|
||||
ij_php_space_before_method_parentheses = false
|
||||
ij_php_space_before_quest = true
|
||||
ij_php_space_before_switch_left_brace = true
|
||||
ij_php_space_before_switch_parentheses = true
|
||||
ij_php_space_before_try_left_brace = true
|
||||
ij_php_space_before_unary_not = false
|
||||
ij_php_space_before_while_keyword = true
|
||||
ij_php_space_before_while_left_brace = true
|
||||
ij_php_space_before_while_parentheses = true
|
||||
ij_php_space_between_ternary_quest_and_colon = false
|
||||
ij_php_spaces_around_additive_operators = true
|
||||
ij_php_spaces_around_arrow = false
|
||||
ij_php_spaces_around_assignment_in_declare = false
|
||||
ij_php_spaces_around_assignment_operators = true
|
||||
ij_php_spaces_around_bitwise_operators = true
|
||||
ij_php_spaces_around_equality_operators = true
|
||||
ij_php_spaces_around_logical_operators = true
|
||||
ij_php_spaces_around_multiplicative_operators = true
|
||||
ij_php_spaces_around_null_coalesce_operator = true
|
||||
ij_php_spaces_around_relational_operators = true
|
||||
ij_php_spaces_around_shift_operators = true
|
||||
ij_php_spaces_around_unary_operator = false
|
||||
ij_php_spaces_around_var_within_brackets = false
|
||||
ij_php_spaces_within_array_initializer_braces = false
|
||||
ij_php_spaces_within_brackets = false
|
||||
ij_php_spaces_within_catch_parentheses = false
|
||||
ij_php_spaces_within_for_parentheses = false
|
||||
ij_php_spaces_within_if_parentheses = false
|
||||
ij_php_spaces_within_method_call_parentheses = false
|
||||
ij_php_spaces_within_method_parentheses = false
|
||||
ij_php_spaces_within_parentheses = false
|
||||
ij_php_spaces_within_short_echo_tags = true
|
||||
ij_php_spaces_within_switch_parentheses = false
|
||||
ij_php_spaces_within_while_parentheses = false
|
||||
ij_php_special_else_if_treatment = false
|
||||
ij_php_subpackage_weight = 28
|
||||
ij_php_ternary_operation_signs_on_next_line = false
|
||||
ij_php_ternary_operation_wrap = off
|
||||
ij_php_throws_weight = 6
|
||||
ij_php_todo_weight = 28
|
||||
ij_php_unknown_tag_weight = 28
|
||||
ij_php_upper_case_boolean_const = false
|
||||
ij_php_upper_case_null_const = false
|
||||
ij_php_uses_weight = 28
|
||||
ij_php_var_weight = 28
|
||||
ij_php_variable_naming_style = mixed
|
||||
ij_php_version_weight = 28
|
||||
ij_php_while_brace_force = always
|
||||
ij_php_while_on_new_line = false
|
||||
|
||||
[{*.sht,*.htm,*.html,*.shtm,*.shtml}]
|
||||
[{*.sht,*.html,*.shtm,*.shtml,*.htm,*.ng}]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
|
||||
@@ -510,185 +467,20 @@ ij_html_space_around_equality_in_attribute = false
|
||||
ij_html_space_inside_empty_tag = false
|
||||
ij_html_text_wrap = normal
|
||||
|
||||
[{*.ts,*.ats}]
|
||||
ij_continuation_indent_size = 4
|
||||
ij_typescript_align_imports = false
|
||||
ij_typescript_align_multiline_array_initializer_expression = false
|
||||
ij_typescript_align_multiline_binary_operation = false
|
||||
ij_typescript_align_multiline_chained_methods = false
|
||||
ij_typescript_align_multiline_extends_list = false
|
||||
ij_typescript_align_multiline_for = true
|
||||
ij_typescript_align_multiline_parameters = true
|
||||
ij_typescript_align_multiline_parameters_in_calls = false
|
||||
ij_typescript_align_multiline_ternary_operation = false
|
||||
ij_typescript_align_object_properties = 0
|
||||
ij_typescript_align_union_types = false
|
||||
ij_typescript_align_var_statements = 0
|
||||
ij_typescript_array_initializer_new_line_after_left_brace = false
|
||||
ij_typescript_array_initializer_right_brace_on_new_line = false
|
||||
ij_typescript_array_initializer_wrap = off
|
||||
ij_typescript_assignment_wrap = off
|
||||
ij_typescript_binary_operation_sign_on_next_line = false
|
||||
ij_typescript_binary_operation_wrap = off
|
||||
ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**/*
|
||||
ij_typescript_blank_lines_after_imports = 1
|
||||
ij_typescript_blank_lines_around_class = 1
|
||||
ij_typescript_blank_lines_around_field = 0
|
||||
ij_typescript_blank_lines_around_field_in_interface = 0
|
||||
ij_typescript_blank_lines_around_function = 1
|
||||
ij_typescript_blank_lines_around_method = 1
|
||||
ij_typescript_blank_lines_around_method_in_interface = 1
|
||||
ij_typescript_block_brace_style = end_of_line
|
||||
ij_typescript_call_parameters_new_line_after_left_paren = false
|
||||
ij_typescript_call_parameters_right_paren_on_new_line = false
|
||||
ij_typescript_call_parameters_wrap = off
|
||||
ij_typescript_catch_on_new_line = false
|
||||
ij_typescript_chained_call_dot_on_new_line = true
|
||||
ij_typescript_class_brace_style = end_of_line
|
||||
ij_typescript_comma_on_new_line = false
|
||||
ij_typescript_do_while_brace_force = never
|
||||
ij_typescript_else_on_new_line = false
|
||||
ij_typescript_enforce_trailing_comma = keep
|
||||
ij_typescript_extends_keyword_wrap = off
|
||||
ij_typescript_extends_list_wrap = off
|
||||
ij_typescript_field_prefix = _
|
||||
ij_typescript_file_name_style = relaxed
|
||||
ij_typescript_finally_on_new_line = false
|
||||
ij_typescript_for_brace_force = never
|
||||
ij_typescript_for_statement_new_line_after_left_paren = false
|
||||
ij_typescript_for_statement_right_paren_on_new_line = false
|
||||
ij_typescript_for_statement_wrap = off
|
||||
ij_typescript_force_quote_style = false
|
||||
ij_typescript_force_semicolon_style = false
|
||||
ij_typescript_function_expression_brace_style = end_of_line
|
||||
ij_typescript_if_brace_force = never
|
||||
ij_typescript_import_merge_members = global
|
||||
ij_typescript_import_prefer_absolute_path = global
|
||||
ij_typescript_import_sort_members = true
|
||||
ij_typescript_import_sort_module_name = false
|
||||
ij_typescript_import_use_node_resolution = true
|
||||
ij_typescript_imports_wrap = on_every_item
|
||||
ij_typescript_indent_case_from_switch = true
|
||||
ij_typescript_indent_chained_calls = true
|
||||
ij_typescript_indent_package_children = 0
|
||||
ij_typescript_jsdoc_include_types = false
|
||||
ij_typescript_jsx_attribute_value = braces
|
||||
ij_typescript_keep_blank_lines_in_code = 2
|
||||
ij_typescript_keep_first_column_comment = true
|
||||
ij_typescript_keep_indents_on_empty_lines = false
|
||||
ij_typescript_keep_line_breaks = true
|
||||
ij_typescript_keep_simple_blocks_in_one_line = false
|
||||
ij_typescript_keep_simple_methods_in_one_line = false
|
||||
ij_typescript_line_comment_add_space = true
|
||||
ij_typescript_line_comment_at_first_column = false
|
||||
ij_typescript_method_brace_style = end_of_line
|
||||
ij_typescript_method_call_chain_wrap = off
|
||||
ij_typescript_method_parameters_new_line_after_left_paren = false
|
||||
ij_typescript_method_parameters_right_paren_on_new_line = false
|
||||
ij_typescript_method_parameters_wrap = off
|
||||
ij_typescript_object_literal_wrap = on_every_item
|
||||
ij_typescript_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_typescript_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_typescript_place_assignment_sign_on_next_line = false
|
||||
ij_typescript_prefer_as_type_cast = false
|
||||
ij_typescript_prefer_parameters_wrap = false
|
||||
ij_typescript_reformat_c_style_comments = false
|
||||
ij_typescript_space_after_colon = true
|
||||
ij_typescript_space_after_comma = true
|
||||
ij_typescript_space_after_dots_in_rest_parameter = false
|
||||
ij_typescript_space_after_generator_mult = true
|
||||
ij_typescript_space_after_property_colon = true
|
||||
ij_typescript_space_after_quest = true
|
||||
ij_typescript_space_after_type_colon = true
|
||||
ij_typescript_space_after_unary_not = false
|
||||
ij_typescript_space_before_async_arrow_lparen = true
|
||||
ij_typescript_space_before_catch_keyword = true
|
||||
ij_typescript_space_before_catch_left_brace = true
|
||||
ij_typescript_space_before_catch_parentheses = true
|
||||
ij_typescript_space_before_class_lbrace = true
|
||||
ij_typescript_space_before_class_left_brace = true
|
||||
ij_typescript_space_before_colon = true
|
||||
ij_typescript_space_before_comma = false
|
||||
ij_typescript_space_before_do_left_brace = true
|
||||
ij_typescript_space_before_else_keyword = true
|
||||
ij_typescript_space_before_else_left_brace = true
|
||||
ij_typescript_space_before_finally_keyword = true
|
||||
ij_typescript_space_before_finally_left_brace = true
|
||||
ij_typescript_space_before_for_left_brace = true
|
||||
ij_typescript_space_before_for_parentheses = true
|
||||
ij_typescript_space_before_for_semicolon = false
|
||||
ij_typescript_space_before_function_left_parenth = true
|
||||
ij_typescript_space_before_generator_mult = false
|
||||
ij_typescript_space_before_if_left_brace = true
|
||||
ij_typescript_space_before_if_parentheses = true
|
||||
ij_typescript_space_before_method_call_parentheses = false
|
||||
ij_typescript_space_before_method_left_brace = true
|
||||
ij_typescript_space_before_method_parentheses = false
|
||||
ij_typescript_space_before_property_colon = false
|
||||
ij_typescript_space_before_quest = true
|
||||
ij_typescript_space_before_switch_left_brace = true
|
||||
ij_typescript_space_before_switch_parentheses = true
|
||||
ij_typescript_space_before_try_left_brace = true
|
||||
ij_typescript_space_before_type_colon = false
|
||||
ij_typescript_space_before_unary_not = false
|
||||
ij_typescript_space_before_while_keyword = true
|
||||
ij_typescript_space_before_while_left_brace = true
|
||||
ij_typescript_space_before_while_parentheses = true
|
||||
ij_typescript_spaces_around_additive_operators = true
|
||||
ij_typescript_spaces_around_arrow_function_operator = true
|
||||
ij_typescript_spaces_around_assignment_operators = true
|
||||
ij_typescript_spaces_around_bitwise_operators = true
|
||||
ij_typescript_spaces_around_equality_operators = true
|
||||
ij_typescript_spaces_around_logical_operators = true
|
||||
ij_typescript_spaces_around_multiplicative_operators = true
|
||||
ij_typescript_spaces_around_relational_operators = true
|
||||
ij_typescript_spaces_around_shift_operators = true
|
||||
ij_typescript_spaces_around_unary_operator = false
|
||||
ij_typescript_spaces_within_array_initializer_brackets = false
|
||||
ij_typescript_spaces_within_brackets = false
|
||||
ij_typescript_spaces_within_catch_parentheses = false
|
||||
ij_typescript_spaces_within_for_parentheses = false
|
||||
ij_typescript_spaces_within_if_parentheses = false
|
||||
ij_typescript_spaces_within_imports = false
|
||||
ij_typescript_spaces_within_interpolation_expressions = false
|
||||
ij_typescript_spaces_within_method_call_parentheses = false
|
||||
ij_typescript_spaces_within_method_parentheses = false
|
||||
ij_typescript_spaces_within_object_literal_braces = false
|
||||
ij_typescript_spaces_within_object_type_braces = true
|
||||
ij_typescript_spaces_within_parentheses = false
|
||||
ij_typescript_spaces_within_switch_parentheses = false
|
||||
ij_typescript_spaces_within_type_assertion = false
|
||||
ij_typescript_spaces_within_union_types = true
|
||||
ij_typescript_spaces_within_while_parentheses = false
|
||||
ij_typescript_special_else_if_treatment = true
|
||||
ij_typescript_ternary_operation_signs_on_next_line = false
|
||||
ij_typescript_ternary_operation_wrap = off
|
||||
ij_typescript_union_types_wrap = on_every_item
|
||||
ij_typescript_use_chained_calls_group_indents = false
|
||||
ij_typescript_use_double_quotes = true
|
||||
ij_typescript_use_explicit_js_extension = global
|
||||
ij_typescript_use_path_mapping = always
|
||||
ij_typescript_use_public_modifier = false
|
||||
ij_typescript_use_semicolon_after_statement = true
|
||||
ij_typescript_var_declaration_wrap = normal
|
||||
ij_typescript_while_brace_force = never
|
||||
ij_typescript_while_on_new_line = false
|
||||
ij_typescript_wrap_comments = false
|
||||
|
||||
[{*.yml,*.yaml}]
|
||||
indent_size = 2
|
||||
ij_continuation_indent_size = 2
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
|
||||
[{*.zsh,*.bash,*.sh}]
|
||||
[{*.zsh,*.sh,*.bash}]
|
||||
ij_shell_binary_ops_start_line = false
|
||||
ij_shell_keep_column_alignment_padding = false
|
||||
ij_shell_minify_program = false
|
||||
ij_shell_redirect_followed_by_space = false
|
||||
ij_shell_switch_cases_indented = false
|
||||
|
||||
[{.stylelintrc,.eslintrc,.babelrc,jest.config,*.bowerrc,*.jsb3,*.jsb2,*.json}]
|
||||
[{.babelrc,.stylelintrc,.eslintrc,jest.config,*.json,*.jsb3,*.jsb2,*.bowerrc}]
|
||||
indent_size = 2
|
||||
ij_json_keep_blank_lines_in_code = 0
|
||||
ij_json_keep_indents_on_empty_lines = false
|
||||
@@ -701,7 +493,7 @@ ij_json_spaces_within_braces = false
|
||||
ij_json_spaces_within_brackets = false
|
||||
ij_json_wrap_long_lines = false
|
||||
|
||||
[{phpunit.xml.dist,*.jhm,*.rng,*.wsdl,*.fxml,*.xslt,*.jrxml,*.ant,*.xul,*.xsl,*.xsd,*.tld,*.jnlp,*.xml}]
|
||||
[{phpunit.xml.dist,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.jhm,*.tld,*.fxml,*.wsdl,*.jrxml,*.xml,*.jnlp}]
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
tab_width = 2
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -140,3 +140,4 @@ local.properties
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
/css/setup.css
|
||||
|
||||
42
.idea/inspectionProfiles/Combodo.xml
generated
42
.idea/inspectionProfiles/Combodo.xml
generated
@@ -2,6 +2,12 @@
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Combodo" />
|
||||
<inspection_tool class="CascadeStringReplacementInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="CucumberExamplesColon" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="CucumberMissedExamples" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="CucumberTableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="CucumberUndefinedStep" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="DuplicateKeyInSection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="DuplicateSectionInFile" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="ForgottenDebugOutputInspection" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<option name="configuration">
|
||||
<list>
|
||||
@@ -68,11 +74,17 @@
|
||||
</option>
|
||||
<option name="migratedIntoUserSpace" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="GherkinBrokenTableInspection" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="GherkinMisplacedBackground" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="GherkinScenarioToScenarioOutline" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="HtmlRequiredAltAttribute" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="HtmlRequiredLangAttribute" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="IsNullFunctionUsageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="LessResolvedByNameOnly" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="LessUnresolvedMixin" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="LessUnresolvedVariable" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="MysqlParsingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="NodeModulesDependencies" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PhpComposerExtensionStubsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="PhpIncludeInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PhpMethodParametersCountMismatchInspection" enabled="true" level="ERROR" enabled_by_default="true" />
|
||||
@@ -84,7 +96,6 @@
|
||||
<option name="DONT_REPORT_MULTI_RESOLVE" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PhpUndefinedMethodInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PhpUnhandledExceptionInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PhpUnusedLocalVariableInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="DONT_REPORT_INSIDE_LIST" value="true" />
|
||||
</inspection_tool>
|
||||
@@ -146,6 +157,8 @@
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ShellCheck" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="SlowArrayOperationsInLoopInspection" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SqlAddNotNullColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SqlAmbiguousColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SqlAutoIncrementDuplicateInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
@@ -167,5 +180,30 @@
|
||||
<inspection_tool class="SqlStorageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SqlTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SqlUnusedVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TaskProblemsInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptAbstractClassConstructorCanBeMadeProtected" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptAccessibilityCheck" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptCheckImport" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptConfig" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptDuplicateUnionOrIntersectionType" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptExplicitMemberType" enabled="false" level="INFORMATION" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptFieldCanBeMadeReadonly" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptLibrary" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptMissingAugmentationImport" enabled="false" level="INFORMATION" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptMissingConfigOption" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptRedundantGenericType" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptSmartCast" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptSuspiciousConstructorParameterAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptUMDGlobal" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptUnresolvedFunction" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptUnresolvedVariable" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptValidateGenericTypes" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptValidateJSTypes" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="TypeScriptValidateTypes" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="UnresolvedReference" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="XsltDeclarations" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="XsltTemplateInvocation" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="XsltUnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="XsltVariableShadowing" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
# create target dirs
|
||||
mkdir -p var
|
||||
mkdir -p toolkit
|
||||
|
||||
# cleanup target dirs
|
||||
rm -rf toolkit/*
|
||||
|
||||
# fill target dirs
|
||||
curl https://www.combodo.com/documentation/iTopDataModelToolkit-2.3.zip > toolkit.zip
|
||||
unzip toolkit.zip
|
||||
rm toolkit.zip
|
||||
cp -r .jenkins/configuration/default-environment/unattended_install/* toolkit
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
# on the root dir
|
||||
# composer install -a # => Not needed anymore (libs were added to git with N°2435)
|
||||
|
||||
|
||||
# under the test dir
|
||||
cd test
|
||||
composer install
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
|
||||
|
||||
whoami
|
||||
pwd
|
||||
ls
|
||||
|
||||
echo "$BRANCH_NAME:${BRANCH_NAME}"
|
||||
|
||||
echo "printenv :"
|
||||
printenv
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
|
||||
cd test
|
||||
|
||||
export DEBUG_UNIT_TEST=0
|
||||
RUN_NONREG_TESTS=0
|
||||
|
||||
#USAGE ${debugMode} ${runNonRegOQLTests} "${coverture}" "${testFile}"
|
||||
|
||||
if [ $# -ge 1 -a "x$1" == "xtrue" ]
|
||||
then
|
||||
export DEBUG_UNIT_TEST=1
|
||||
else
|
||||
export DEBUG_UNIT_TEST=0
|
||||
fi
|
||||
|
||||
set -x
|
||||
OPTION=""
|
||||
if [ $# -ge 3 -a "x$3" == "xtrue" ]
|
||||
then
|
||||
##coverture
|
||||
OPTION="-dxdebug.coverage_enable=1 --coverage-clover ../var/test/coverage.xml"
|
||||
fi
|
||||
|
||||
TESTFILE="$4"
|
||||
if [ "x$TESTFILE" != "x" ]
|
||||
then
|
||||
# shellcheck disable=SC2001
|
||||
TESTFILE=$(echo "$TESTFILE" | sed 's|test/||1')
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml $OPTION $TESTFILE --teamcity
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ $# -ge 2 -a "x$2" == "xtrue" ]
|
||||
then
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml $OPTION --teamcity
|
||||
else
|
||||
#echo php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml $OPTION --exclude-group OQL --teamcity
|
||||
fi
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
chmod 666 conf/production/config-itop.php
|
||||
|
||||
cd toolkit
|
||||
php unattended_install.php --response_file=default-params.xml --clean=true
|
||||
@@ -1,284 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Configuration file, generated by the iTop configuration wizard
|
||||
*
|
||||
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
*
|
||||
*/
|
||||
$MySettings = array(
|
||||
|
||||
// access_message: Message displayed to the users when there is any access restriction
|
||||
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
|
||||
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
|
||||
|
||||
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
|
||||
// default: 3
|
||||
'access_mode' => 3,
|
||||
|
||||
'allowed_login_types' => 'form|basic|external',
|
||||
|
||||
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
|
||||
// default: true
|
||||
'apc_cache.enabled' => true,
|
||||
|
||||
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
|
||||
// default: 3600
|
||||
'apc_cache.query_ttl' => 3600,
|
||||
|
||||
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
|
||||
// default: ''
|
||||
'app_root_url' => 'http://127.0.0.1/itop/svn/trunk/',
|
||||
|
||||
// buttons_position: Position of the forms buttons: bottom | top | both
|
||||
// default: 'both'
|
||||
'buttons_position' => 'both',
|
||||
|
||||
// cas_include_path: The path where to find the phpCAS library
|
||||
// default: '/usr/share/php'
|
||||
'cas_include_path' => '/usr/share/php',
|
||||
|
||||
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
|
||||
// default: 600
|
||||
'cron_max_execution_time' => 600,
|
||||
|
||||
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
|
||||
// default: 'ISO-8859-1'
|
||||
'csv_file_default_charset' => 'ISO-8859-1',
|
||||
|
||||
'csv_import_charsets' => array (
|
||||
),
|
||||
|
||||
// csv_import_history_display: Display the history tab in the import wizard
|
||||
// default: false
|
||||
'csv_import_history_display' => false,
|
||||
|
||||
// date_and_time_format: Format for date and time display (per language)
|
||||
// default: array (
|
||||
// 'default' =>
|
||||
// array (
|
||||
// 'date' => 'Y-m-d',
|
||||
// 'time' => 'H:i:s',
|
||||
// 'date_time' => '$date $time',
|
||||
// ),
|
||||
// )
|
||||
'date_and_time_format' => array (
|
||||
'default' =>
|
||||
array (
|
||||
'date' => 'Y-m-d',
|
||||
'time' => 'H:i:s',
|
||||
'date_time' => '$date $time',
|
||||
),
|
||||
'FR FR' =>
|
||||
array (
|
||||
'date' => 'd/m/Y',
|
||||
'time' => 'H:i:s',
|
||||
'date_time' => '$date $time',
|
||||
),
|
||||
),
|
||||
|
||||
'db_host' => '',
|
||||
|
||||
'db_name' => 'itop_ci',
|
||||
|
||||
'db_pwd' => 'IKnowYouSeeMeInJenkinsConf',
|
||||
|
||||
'db_subname' => '',
|
||||
|
||||
'db_user' => 'jenkins_itop',
|
||||
|
||||
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
|
||||
// default: '$difference$'
|
||||
'deadline_format' => '$difference$',
|
||||
|
||||
'default_language' => 'EN US',
|
||||
|
||||
// draft_attachments_lifetime: Lifetime (in seconds) of drafts' attachments and inline images: after this duration, the garbage collector will delete them.
|
||||
// default: 3600
|
||||
'draft_attachments_lifetime' => 3600,
|
||||
|
||||
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
|
||||
// default: false
|
||||
'email_asynchronous' => false,
|
||||
|
||||
// email_default_sender_address: Default address provided in the email from header field.
|
||||
// default: ''
|
||||
'email_default_sender_address' => '',
|
||||
|
||||
// email_default_sender_label: Default label provided in the email from header field.
|
||||
// default: ''
|
||||
'email_default_sender_label' => '',
|
||||
|
||||
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocole)
|
||||
// default: 'PHPMail'
|
||||
'email_transport' => 'SMTP',
|
||||
|
||||
// email_transport_smtp.host: host name or IP address (optional)
|
||||
// default: 'localhost'
|
||||
'email_transport_smtp.host' => 'smtp.combodo.com',
|
||||
|
||||
// email_transport_smtp.password: Authentication password (optional)
|
||||
// default: ''
|
||||
'email_transport_smtp.password' => 'IDoNotWork',
|
||||
|
||||
// email_transport_smtp.port: port number (optional)
|
||||
// default: 25
|
||||
'email_transport_smtp.port' => 25,
|
||||
|
||||
// email_transport_smtp.username: Authentication user (optional)
|
||||
// default: ''
|
||||
'email_transport_smtp.username' => 'test2@combodo.com',
|
||||
|
||||
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
|
||||
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
|
||||
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
|
||||
|
||||
'encryption_key' => '@iT0pEncr1pti0n!',
|
||||
|
||||
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
|
||||
|
||||
'fast_reload_interval' => '60',
|
||||
|
||||
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
|
||||
// default: '/usr/bin/dot'
|
||||
'graphviz_path' => '/usr/bin/dot',
|
||||
|
||||
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
|
||||
// default: '250'
|
||||
'inline_image_max_display_width' => 250,
|
||||
|
||||
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
|
||||
// default: '1600'
|
||||
'inline_image_max_storage_width' => 1600,
|
||||
|
||||
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
|
||||
// default: '\''
|
||||
'link_set_attribute_qualifier' => '\'',
|
||||
|
||||
// link_set_attribute_separator: Link set from string: attribute separator
|
||||
// default: ';'
|
||||
'link_set_attribute_separator' => ';',
|
||||
|
||||
// link_set_item_separator: Link set from string: line separator
|
||||
// default: '|'
|
||||
'link_set_item_separator' => '|',
|
||||
|
||||
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
|
||||
// default: ':'
|
||||
'link_set_value_separator' => ':',
|
||||
|
||||
'log_global' => true,
|
||||
|
||||
'log_issue' => true,
|
||||
|
||||
'log_notification' => true,
|
||||
|
||||
'log_web_service' => true,
|
||||
|
||||
// max_combo_length: The maximum number of elements in a drop-down list. If more then an autocomplete will be used
|
||||
// default: 50
|
||||
'max_combo_length' => 50,
|
||||
|
||||
'max_display_limit' => '15',
|
||||
|
||||
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
|
||||
// default: 100
|
||||
'max_linkset_output' => 100,
|
||||
|
||||
'min_display_limit' => '10',
|
||||
|
||||
// online_help: Hyperlink to the online-help web page
|
||||
// default: 'http://www.combodo.com/itop-help'
|
||||
'online_help' => 'http://www.combodo.com/itop-help',
|
||||
|
||||
// php_path: Path to the php executable in CLI mode
|
||||
// default: 'php'
|
||||
'php_path' => 'php',
|
||||
|
||||
// portal_tickets: CSV list of classes supported in the portal
|
||||
// default: 'UserRequest'
|
||||
'portal_tickets' => 'UserRequest',
|
||||
|
||||
'query_cache_enabled' => true,
|
||||
|
||||
// search_manual_submit: Force manual submit of search requests (class => true)
|
||||
// default: false
|
||||
'search_manual_submit' => array (
|
||||
'Person' => true,
|
||||
),
|
||||
|
||||
'secure_connection_required' => false,
|
||||
|
||||
// session_name: The name of the cookie used to store the PHP session id
|
||||
// default: 'iTop'
|
||||
'session_name' => 'iTop',
|
||||
|
||||
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
|
||||
// default: 'UI:Menu:Modify,UI:Menu:New'
|
||||
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
|
||||
|
||||
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
|
||||
// default: ''
|
||||
'source_dir' => 'datamodels/2.x/',
|
||||
|
||||
'standard_reload_interval' => '300',
|
||||
|
||||
// synchro_trace: Synchronization details: none, display, save (includes 'display')
|
||||
// default: 'none'
|
||||
'synchro_trace' => 'none',
|
||||
|
||||
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitely configured in PHP
|
||||
// default: 'Europe/Paris'
|
||||
'timezone' => 'Europe/Paris',
|
||||
|
||||
// tracking_level_linked_set_default: Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
|
||||
// default: 1
|
||||
'tracking_level_linked_set_default' => 0,
|
||||
|
||||
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
|
||||
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
|
||||
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* Modules specific settings
|
||||
*
|
||||
*/
|
||||
$MyModuleSettings = array(
|
||||
'authent-local' => array (
|
||||
'password_validation.pattern' => '',
|
||||
),
|
||||
'itop-attachments' => array (
|
||||
'allowed_classes' => array (
|
||||
0 => 'Ticket',
|
||||
),
|
||||
'position' => 'relations',
|
||||
'preview_max_width' => 290,
|
||||
),
|
||||
'itop-backup' => array (
|
||||
'mysql_bindir' => '',
|
||||
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
|
||||
'time' => '23:30',
|
||||
'retention_count' => 5,
|
||||
'enabled' => true,
|
||||
'debug' => false,
|
||||
),
|
||||
'molkobain-console-tooltips' => array (
|
||||
'decoration_class' => 'fas fa-question',
|
||||
'enabled' => true,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* Data model modules to be loaded. Names are specified as relative paths
|
||||
*
|
||||
*/
|
||||
$MyModules = array(
|
||||
'addons' => array (
|
||||
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
|
||||
),
|
||||
);
|
||||
?>
|
||||
@@ -1,208 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
//this scrit will be run under the ./toolkit directory, relatively to the document root
|
||||
|
||||
require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
require_once(APPROOT.'/application/clipage.class.inc.php');
|
||||
require_once(APPROOT.'/core/config.class.inc.php');
|
||||
require_once(APPROOT.'/core/log.class.inc.php');
|
||||
require_once(APPROOT.'/core/kpi.class.inc.php');
|
||||
require_once(APPROOT.'/core/cmdbsource.class.inc.php');
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
|
||||
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
|
||||
require_once(APPROOT.'/setup/applicationinstaller.class.inc.php');
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
$sParamFile = utils::ReadParam('response_file', 'default-params.xml', true /* CLI allowed */, 'raw_data');
|
||||
$bCheckConsistency = (utils::ReadParam('check_consistency', '0', true /* CLI allowed */) == '1');
|
||||
|
||||
$oParams = new XMLParameters($sParamFile);
|
||||
$sMode = $oParams->Get('mode');
|
||||
|
||||
if ($sMode == 'install')
|
||||
{
|
||||
echo "Installation mode detected.\n";
|
||||
$bClean = utils::ReadParam('clean', false, true /* CLI allowed */);
|
||||
if ($bClean)
|
||||
{
|
||||
echo "Cleanup mode detected.\n";
|
||||
$sTargetEnvironment = $oParams->Get('target_env', '');
|
||||
if ($sTargetEnvironment == '')
|
||||
{
|
||||
$sTargetEnvironment = 'production';
|
||||
}
|
||||
$sTargetDir = APPROOT.'env-'.$sTargetEnvironment;
|
||||
|
||||
// Configuration file
|
||||
$sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
|
||||
if (file_exists($sConfigFile))
|
||||
{
|
||||
echo "Trying to delete the configuration file: '$sConfigFile'.\n";
|
||||
@chmod($sConfigFile, 0770); // RWX for owner and group, nothing for others
|
||||
unlink($sConfigFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "No config file to delete ($sConfigFile does not exist).\n";
|
||||
}
|
||||
|
||||
// env-xxx directory
|
||||
if (file_exists($sTargetDir))
|
||||
{
|
||||
if (is_dir($sTargetDir))
|
||||
{
|
||||
echo "Emptying the target directory '$sTargetDir'.\n";
|
||||
SetupUtils::tidydir($sTargetDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
die("ERROR the target dir '$sTargetDir' exists, but is NOT a directory !!!\nExiting.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "No target directory to delete ($sTargetDir does not exist).\n";
|
||||
}
|
||||
|
||||
// Database
|
||||
$aDBSettings = $oParams->Get('database', array());
|
||||
$sDBServer = $aDBSettings['server'];
|
||||
$sDBUser = $aDBSettings['user'];
|
||||
$sDBPwd = $aDBSettings['pwd'];
|
||||
$sDBName = $aDBSettings['name'];
|
||||
$sDBPrefix = $aDBSettings['prefix'];
|
||||
|
||||
if ($sDBPrefix != '')
|
||||
{
|
||||
die("Cleanup not implemented for a partial database (prefix= '$sDBPrefix')\nExiting.");
|
||||
}
|
||||
|
||||
$oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
|
||||
if ($oMysqli->connect_errno)
|
||||
{
|
||||
die("Cannot connect to the MySQL server (".$oMysqli->connect_errno . ") ".$oMysqli->connect_error."\nExiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($oMysqli->select_db($sDBName))
|
||||
{
|
||||
echo "Deleting database '$sDBName'\n";
|
||||
$oMysqli->query("DROP DATABASE `$sDBName`");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "The database '$sDBName' does not seem to exist. Nothing to cleanup.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$bHasErrors = false;
|
||||
$aChecks = SetupUtils::CheckBackupPrerequisites(APPROOT.'data'); // mmm should be the backup destination dir
|
||||
|
||||
$aSelectedModules = $oParams->Get('selected_modules');
|
||||
$sSourceDir = $oParams->Get('source_dir', 'datamodels/latest');
|
||||
$sExtensionDir = $oParams->Get('extensions_dir', 'extensions');
|
||||
$aChecks = array_merge($aChecks, SetupUtils::CheckSelectedModules($sSourceDir, $sExtensionDir, $aSelectedModules));
|
||||
|
||||
|
||||
foreach($aChecks as $oCheckResult)
|
||||
{
|
||||
switch($oCheckResult->iSeverity)
|
||||
{
|
||||
case CheckResult::ERROR:
|
||||
$bHasErrors = true;
|
||||
$sHeader = "Error";
|
||||
break;
|
||||
|
||||
case CheckResult::WARNING:
|
||||
$sHeader = "Warning";
|
||||
break;
|
||||
|
||||
case CheckResult::INFO:
|
||||
default:
|
||||
$sHeader = "Info";
|
||||
break;
|
||||
}
|
||||
echo $sHeader.": ".$oCheckResult->sLabel;
|
||||
if (strlen($oCheckResult->sDescription))
|
||||
{
|
||||
echo ' - '.$oCheckResult->sDescription;
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
if ($bHasErrors)
|
||||
{
|
||||
echo "Encountered stopper issues. Aborting...\n";
|
||||
die;
|
||||
}
|
||||
|
||||
$bFoundIssues = false;
|
||||
|
||||
$bInstall = utils::ReadParam('install', true, true /* CLI allowed */);
|
||||
if ($bInstall)
|
||||
{
|
||||
echo "Starting the unattended installation...\n";
|
||||
$oWizard = new ApplicationInstaller($oParams);
|
||||
$bRes = $oWizard->ExecuteAllSteps();
|
||||
if (!$bRes)
|
||||
{
|
||||
echo "\nencountered installation issues!";
|
||||
$bFoundIssues = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "No installation requested.\n";
|
||||
}
|
||||
if (!$bFoundIssues && $bCheckConsistency)
|
||||
{
|
||||
echo "Checking data model consistency.\n";
|
||||
ob_start();
|
||||
$sCheckRes = '';
|
||||
try
|
||||
{
|
||||
MetaModel::CheckDefinitions(false);
|
||||
$sCheckRes = ob_get_clean();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$sCheckRes = ob_get_clean()."\nException: ".$e->getMessage();
|
||||
}
|
||||
if (strlen($sCheckRes) > 0)
|
||||
{
|
||||
echo $sCheckRes;
|
||||
echo "\nfound consistency issues!";
|
||||
$bFoundIssues = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bFoundIssues)
|
||||
{
|
||||
// last line: used to check the install
|
||||
// the only way to track issues in case of Fatal error or even parsing error!
|
||||
echo "\ninstalled!";
|
||||
exit;
|
||||
}
|
||||
90
.make/build/afterBuild.php
Normal file
90
.make/build/afterBuild.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
$iBeginTime = time();
|
||||
|
||||
chdir(__DIR__);
|
||||
|
||||
$aCommands = [
|
||||
'php composer/rmDeniedTestDir.php',
|
||||
'php build/commands/setupCssCompiler.php',
|
||||
// 'bash /tmp/gabuzomeu.sh',
|
||||
];
|
||||
|
||||
$aFailedCommands=[];
|
||||
foreach ($aCommands as $sCommand)
|
||||
{
|
||||
if (!ExecCommand($sCommand))
|
||||
{
|
||||
$aFailedCommands[] = $sCommand;
|
||||
}
|
||||
}
|
||||
|
||||
$iElapsed = time() - $iBeginTime;
|
||||
|
||||
if (count($aFailedCommands))
|
||||
{
|
||||
fwrite(STDERR, "\nafterBuild execution failed! (in ${iElapsed}s)\n");
|
||||
fwrite(STDERR, "List of failling commands:\n - " . implode("\n - ", $aFailedCommands) . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
echo "\nDone (${iElapsed}s)\n";
|
||||
exit(0);
|
||||
|
||||
/**
|
||||
* Executes a command and returns an array with exit code, stdout and stderr content
|
||||
*
|
||||
* @param string $cmd - Command to execute
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
function ExecCommand($cmd) {
|
||||
$iBeginTime = time();
|
||||
|
||||
|
||||
echo sprintf("command: %s", str_pad("$cmd ", 50));
|
||||
|
||||
$descriptorspec = array(
|
||||
0 => array("pipe", "r"), // stdin
|
||||
1 => array("pipe", "w"), // stdout
|
||||
2 => array("pipe", "w"), // stderr
|
||||
);
|
||||
$process = proc_open($cmd, $descriptorspec, $pipes, __DIR__ . '/..', null);
|
||||
|
||||
$stdout = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
|
||||
$stderr = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
$iCode = proc_close($process);
|
||||
$bSuccess = (0 === $iCode);
|
||||
|
||||
$iElapsed = time() - $iBeginTime;
|
||||
if (!$bSuccess) {
|
||||
fwrite(STDERR, sprintf(
|
||||
"\nCOMMAND FAILED! (%s) \n - status:%s \n - stderr:%s \n - stdout: %s\n - elapsed:%ss\n\n",
|
||||
$cmd,
|
||||
$iCode,
|
||||
rtrim($stderr),
|
||||
rtrim($stdout),
|
||||
$iElapsed
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "| elapsed:${iElapsed}s \n";
|
||||
}
|
||||
|
||||
if (!empty($stderr))
|
||||
{
|
||||
fwrite(STDERR, "$stderr\n");
|
||||
}
|
||||
if (!empty($stdout))
|
||||
{
|
||||
echo "stdout :$stdout\n\n";
|
||||
}
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
51
.make/build/commands/setupCssCompiler.php
Normal file
51
.make/build/commands/setupCssCompiler.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Composer\iTopComposer;
|
||||
|
||||
$iTopFolder = __DIR__."/../../../";
|
||||
|
||||
require_once("$iTopFolder/approot.inc.php");
|
||||
require_once(APPROOT."/application/utils.inc.php");
|
||||
|
||||
if (php_sapi_name() !== 'cli')
|
||||
{
|
||||
throw new \Exception('This script can only run from CLI');
|
||||
}
|
||||
|
||||
$sCssFile = APPROOT.'/css/setup.css';
|
||||
if (file_exists($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "$sCssFile already exists (it should not), removing it.");
|
||||
if (!unlink($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "Failed to remove $sCssFile, exiting.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
$sCssRelPath = utils::GetCSSFromSASS('css/setup.scss');
|
||||
|
||||
if (!file_exists($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "Failed to compile $sCssFile, exiting.");
|
||||
exit(1);
|
||||
}
|
||||
78
Jenkinsfile
vendored
78
Jenkinsfile
vendored
@@ -1,73 +1,11 @@
|
||||
pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
booleanParam(name: 'debugMode', defaultValue: 'false', description: 'Debug mode?')
|
||||
string(name: 'testFile', defaultValue: '', description: 'Provide test file to execute. Example: test/core/LogAPITest.php')
|
||||
booleanParam(name: 'coverture', defaultValue: 'false', description: 'Test coverture?')
|
||||
booleanParam(name: 'runNonRegOQLTests', defaultValue: 'false', description: 'Do You want to run legacy OQL regression tests?')
|
||||
}
|
||||
stages {
|
||||
def infra
|
||||
|
||||
stage('init') {
|
||||
parallel {
|
||||
stage('debug') {
|
||||
steps {
|
||||
sh './.jenkins/bin/init/debug.sh'
|
||||
}
|
||||
}
|
||||
stage('append files to project') {
|
||||
steps {
|
||||
sh './.jenkins/bin/init/append_files.sh'
|
||||
}
|
||||
}
|
||||
stage('composer install') {
|
||||
steps {
|
||||
sh './.jenkins/bin/init/composer_install.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node(){
|
||||
checkout scm
|
||||
|
||||
stage('unattended_install') {
|
||||
parallel {
|
||||
stage('unattended_install default env') {
|
||||
steps {
|
||||
sh './.jenkins/bin/unattended_install/default_env.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('test') {
|
||||
parallel {
|
||||
stage('phpunit') {
|
||||
steps {
|
||||
sh './.jenkins/bin/tests/phpunit.sh ${debugMode} ${runNonRegOQLTests} "${coverture}" "${testFile}"'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts allowEmptyArchive:true, excludes: '.gitkeep', artifacts: 'var/test/*.xml'
|
||||
junit 'var/test/phpunit-log.junit.xml'
|
||||
}
|
||||
failure {
|
||||
slackSend(channel: "#jenkins-itop", color: '#FF0000', message: "Ho no! Build failed! (${currentBuild.result}), Job '${env.JOB_NAME_UNESCAPED} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
|
||||
}
|
||||
fixed {
|
||||
slackSend(channel: "#jenkins-itop", color: '#FFa500', message: "Yes! Build repaired! (${currentBuild.result}), Job '${env.JOB_NAME_UNESCAPED} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
|
||||
}
|
||||
}
|
||||
|
||||
environment {
|
||||
DEBUG_UNIT_TEST = '0'
|
||||
JOB_NAME_UNESCAPED = env.JOB_NAME.replaceAll("%2F", "/")
|
||||
}
|
||||
options {
|
||||
timeout(time: 20, unit: 'MINUTES')
|
||||
}
|
||||
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'
|
||||
}
|
||||
|
||||
|
||||
infra.call()
|
||||
|
||||
|
||||
@@ -78,10 +78,10 @@ We would like to give a special thank you to the people from the community who c
|
||||
- Alves, David
|
||||
- Beck, Pedro
|
||||
- Bilger, Jean-François
|
||||
- Bostoen, Jeffrey
|
||||
- Bostoen, Jeffrey (a.k.a @jbostoen)
|
||||
- Cardoso, Anderson
|
||||
- Cassaro, Bruno
|
||||
- Casteleyn, Thomas
|
||||
- Casteleyn, Thomas (a.k.a @Hipska)
|
||||
- Castro, Randall Badilla
|
||||
- Colantoni, Maria Laura
|
||||
- Couronné, Guy
|
||||
@@ -97,6 +97,7 @@ We would like to give a special thank you to the people from the community who c
|
||||
- Lazcano, Federico
|
||||
- Lucas, Jonathan
|
||||
- Malik, Remie
|
||||
- Mindêllo de Andrade, Lucas (a.k.a @rokam)
|
||||
- Rosenke, Stephan
|
||||
- Seki, Shoji
|
||||
- Shilov, Vladimir
|
||||
|
||||
@@ -9,7 +9,7 @@ responsible disclosure and will make every effort to acknowledge your contributi
|
||||
### iTop vulnerabilities
|
||||
Please send a procedure to reproduce iTop vulnerabilities to [itop-security@combodo.com](mailto:itop-security@combodo.com).
|
||||
|
||||
You can send us a standard "given / then / when" report, including iTop version, impacts, and maybe installed modules or data if they are
|
||||
You can send us a standard "given / when / then" report, including iTop version, impacts, and maybe installed modules or data if they are
|
||||
needed to reproduce.
|
||||
|
||||
### Dependencies vulnerabilities
|
||||
|
||||
@@ -434,7 +434,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
// Support drastic data model changes: no organization class (or not writable)!
|
||||
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
||||
{
|
||||
$oOrg = new Organization();
|
||||
$oOrg = MetaModel::NewObject('Organization');
|
||||
$oOrg->Set('name', 'My Company/Department');
|
||||
$oOrg->Set('code', 'SOMECODE');
|
||||
$iOrgId = $oOrg->DBInsertNoReload();
|
||||
@@ -442,17 +442,13 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
// Support drastic data model changes: no Person class (or not writable)!
|
||||
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
||||
{
|
||||
$oContact = new Person();
|
||||
$oContact = MetaModel::NewObject('Person');
|
||||
$oContact->Set('name', 'My last name');
|
||||
$oContact->Set('first_name', 'My first name');
|
||||
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
||||
{
|
||||
$oContact->Set('org_id', $iOrgId);
|
||||
}
|
||||
if (MetaModel::IsValidAttCode('Person', 'phone'))
|
||||
{
|
||||
$oContact->Set('phone', '+00 000 000 000');
|
||||
}
|
||||
$oContact->Set('email', 'my.email@foo.org');
|
||||
$iContactId = $oContact->DBInsertNoReload();
|
||||
}
|
||||
@@ -561,7 +557,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
|
||||
/**
|
||||
* @param $oUser User
|
||||
* @return array
|
||||
* @return bool
|
||||
*/
|
||||
public function IsAdministrator($oUser)
|
||||
{
|
||||
@@ -571,16 +567,22 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
|
||||
/**
|
||||
* @param $oUser User
|
||||
* @return array
|
||||
* @return bool
|
||||
*/
|
||||
public function IsPortalUser($oUser)
|
||||
{
|
||||
// UserRights caches the list for us
|
||||
return UserRights::HasProfile(PORTAL_PROFILE_NAME, $oUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $oUser User
|
||||
* @return bool
|
||||
*
|
||||
* @return array
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public function ListProfiles($oUser)
|
||||
{
|
||||
|
||||
@@ -535,7 +535,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
// Support drastic data model changes: no organization class (or not writable)!
|
||||
if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization'))
|
||||
{
|
||||
$oOrg = new Organization();
|
||||
$oOrg = MetaModel::NewObject('Organization');
|
||||
$oOrg->Set('name', 'My Company/Department');
|
||||
$oOrg->Set('code', 'SOMECODE');
|
||||
$oOrg::SetCurrentChange($oChange);
|
||||
@@ -544,17 +544,13 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
// Support drastic data model changes: no Person class (or not writable)!
|
||||
if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person'))
|
||||
{
|
||||
$oContact = new Person();
|
||||
$oContact = MetaModel::NewObject('Person');
|
||||
$oContact->Set('name', 'My last name');
|
||||
$oContact->Set('first_name', 'My first name');
|
||||
if (MetaModel::IsValidAttCode('Person', 'org_id'))
|
||||
{
|
||||
$oContact->Set('org_id', $iOrgId);
|
||||
}
|
||||
if (MetaModel::IsValidAttCode('Person', 'phone'))
|
||||
{
|
||||
$oContact->Set('phone', '+00 000 000 000');
|
||||
}
|
||||
$oContact->Set('email', 'my.email@foo.org');
|
||||
$oContact::SetCurrentChange($oChange);
|
||||
$iContactId = $oContact->DBInsertNoReload();
|
||||
@@ -711,7 +707,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
|
||||
public function LoadCache()
|
||||
{
|
||||
if (!is_null($this->m_aProfiles)) return;
|
||||
if (!is_null($this->m_aProfiles)) return false;
|
||||
// Could be loaded in a shared memory (?)
|
||||
|
||||
$oKPI = new ExecutionKPI();
|
||||
|
||||
@@ -30,8 +30,11 @@ function mb_str_replace($search, $replace, $subject, &$count = 0) {
|
||||
$replacements = array_pad($replacements, count($searches), '');
|
||||
foreach ($searches as $key => $search) {
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
$count += count($parts) - 1;
|
||||
$subject = implode($replacements[$key], $parts);
|
||||
if (is_countable($parts))
|
||||
{
|
||||
$count += count($parts) - 1;
|
||||
$subject = implode($replacements[$key], $parts);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Call mb_str_replace for each subject in array, recursively
|
||||
|
||||
@@ -200,7 +200,15 @@ class ApplicationContext
|
||||
}
|
||||
return implode("&", $aParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0 N°2534 - dashboard: bug with autorefresh that deactivates filtering on organisation
|
||||
* Returns the params as c[menu]:..., c[org_id]:....
|
||||
* @return string The params
|
||||
*/
|
||||
public function GetForPostParams()
|
||||
{
|
||||
return json_encode( $this->aValues);
|
||||
}
|
||||
/**
|
||||
* Returns the context as sequence of input tags to be inserted inside a <form> tag
|
||||
* @return string The context as a sequence of <input type="hidden" /> tags
|
||||
|
||||
@@ -663,7 +663,30 @@ EOF
|
||||
{
|
||||
// n:n links
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sLinkingAttCode = $oLinkingAttDef->GetCode();
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
|
||||
// N°2334 fields to display for n:n relations
|
||||
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
||||
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($sTargetClass);
|
||||
$aLnkAttCodesToDisplay = array_map(function ($oLnkAttDef) {
|
||||
return ormLinkSet::LINK_ALIAS.'.'.$oLnkAttDef->GetCode();
|
||||
},
|
||||
$aLnkAttDefsToDisplay
|
||||
);
|
||||
if (!in_array(ormLinkSet::LINK_ALIAS.'.'.$sLinkingAttCode, $aLnkAttCodesToDisplay))
|
||||
{
|
||||
// we need to display a link to the remote class instance !
|
||||
$aLnkAttCodesToDisplay[] = ormLinkSet::LINK_ALIAS.'.'.$sLinkingAttCode;
|
||||
}
|
||||
$aRemoteAttCodesToDisplay = array_map(function ($oRemoteAttDef) {
|
||||
return ormLinkSet::REMOTE_ALIAS.'.'.$oRemoteAttDef->GetCode();
|
||||
},
|
||||
$aRemoteAttDefsToDisplay
|
||||
);
|
||||
$aAttCodesToDisplay = array_merge($aLnkAttCodesToDisplay, $aRemoteAttCodesToDisplay);
|
||||
$sAttCodesToDisplay = implode(',', $aAttCodesToDisplay);
|
||||
|
||||
$aParams = array(
|
||||
'link_attr' => $oAttDef->GetExtKeyToMe(),
|
||||
'object_id' => $this->GetKey(),
|
||||
@@ -671,8 +694,12 @@ EOF
|
||||
'view_link' => false,
|
||||
'menu' => false,
|
||||
//'menu_actions_target' => '_blank',
|
||||
'display_limit' => true, // By default limit the list to speed up the initial load & display
|
||||
// By default limit the list to speed up the initial load & display
|
||||
'display_limit' => true,
|
||||
'table_id' => $sClass.'_'.$sAttCode,
|
||||
// N°2334 specify fields to display for n:n relations
|
||||
'zlist' => false,
|
||||
'extra_fields' => $sAttCodesToDisplay,
|
||||
);
|
||||
}
|
||||
$oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription());
|
||||
@@ -1286,7 +1313,14 @@ HTML
|
||||
/**
|
||||
* @param \WebPage $oPage
|
||||
* @param \CMDBObjectSet $oSet
|
||||
* @param array $aExtraParams
|
||||
* @param array $aExtraParams key used :
|
||||
* <ul>
|
||||
* <li>view_link : if true then for extkey will display links with friendly name and make column sortable, default true
|
||||
* <li>menu : if true prints DisplayBlock menu, default true
|
||||
* <li>display_aliases : list of query aliases that will be printed, defaults to [] (displays all)
|
||||
* <li>zlist : name of the zlist to use, false to disable zlist lookup, default to 'list'
|
||||
* <li>extra_fields : list of <alias>.<attcode> to add to the result, separator ',', defaults to empty string
|
||||
* </ul>
|
||||
*
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
@@ -1365,7 +1399,7 @@ HTML
|
||||
}
|
||||
|
||||
// Filter the list to removed linked set since we are not able to display them here
|
||||
foreach($aList[$sAlias] as $index => $sAttCode)
|
||||
foreach ($aList[$sAlias] as $index => $sAttCode)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
|
||||
if ($oAttDef instanceof AttributeLinkedSet)
|
||||
@@ -1374,6 +1408,11 @@ HTML
|
||||
unset($aList[$sAlias][$index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($aList[$sAlias]))
|
||||
{
|
||||
unset($aList[$sAlias], $aAuthorizedClasses[$sAlias]);
|
||||
}
|
||||
}
|
||||
|
||||
$sSelectMode = 'none';
|
||||
@@ -1932,6 +1971,11 @@ HTML
|
||||
$sNullValue = $oAttDef->GetNullValue(); // used for the ValidateField() call in js/forms-json-utils.js
|
||||
$sFieldToValidateId = $iId; // can be different than the displayed field (for example in TagSet)
|
||||
|
||||
// List of attributes that depend on the current one
|
||||
// Might be modified depending on the current field
|
||||
$sWizardHelperJsVarName = "oWizardHelper{$sFormPrefix}";
|
||||
$aDependencies = MetaModel::GetDependentAttributes($sClass, $sAttCode);
|
||||
|
||||
switch ($oAttDef->GetEditClass())
|
||||
{
|
||||
case 'Date':
|
||||
@@ -2222,6 +2266,7 @@ EOF
|
||||
break;
|
||||
|
||||
case 'ExtKey':
|
||||
/** @var \AttributeExternalKey $oAttDef */
|
||||
$aEventsList[] = 'validate';
|
||||
$aEventsList[] = 'change';
|
||||
|
||||
@@ -2240,6 +2285,19 @@ EOF
|
||||
$sHTMLValue = UIExtKeyWidget::DisplayFromAttCode($oPage, $sAttCode, $sClass, $oAttDef->GetLabel(),
|
||||
$oAllowedValues, $value, $iId, $bMandatory, $sFieldName, $sFormPrefix, $aExtKeyParams);
|
||||
$sHTMLValue .= "<!-- iFlags: $iFlags bMandatory: $bMandatory -->\n";
|
||||
|
||||
$bHasExtKeyUpdatingRemoteClassFields = (
|
||||
array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs)
|
||||
&& ($aArgs['replaceDependenciesByRemoteClassFields'])
|
||||
);
|
||||
if ($bHasExtKeyUpdatingRemoteClassFields)
|
||||
{
|
||||
// On this field update we need to update all the corresponding remote class fields
|
||||
// Used when extkey widget is in a linkedset indirect
|
||||
$sWizardHelperJsVarName = $aArgs['wizHelperRemote'];
|
||||
$aDependencies = $aArgs['remoteCodes'];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'RedundancySetting':
|
||||
@@ -2293,23 +2351,23 @@ EOF
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/form_field.js');
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/subform_field.js');
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#{$iId}_field_set').field_set($sFieldSetOptions);
|
||||
|
||||
$('#{$iId}_console_form').console_form_handler($sFormHandlerOptions);
|
||||
$('#{$iId}_console_form').console_form_handler('alignColumns');
|
||||
$('#{$iId}_console_form').console_form_handler('option', 'field_set', $('#{$iId}_field_set'));
|
||||
// field_change must be processed to refresh the hidden value at anytime
|
||||
$('#{$iId}_console_form').bind('value_change', function() { $('#{$iId}').val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); });
|
||||
// Initialize the hidden value with current state
|
||||
// update_value is triggered when preparing the wizard helper object for ajax calls
|
||||
$('#{$iId}').bind('update_value', function() { $(this).val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); });
|
||||
// validate is triggered by CheckFields, on all the input fields, once at page init and once before submitting the form
|
||||
$('#{$iId}').bind('validate', function(evt, sFormId) {
|
||||
$(this).val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values')));
|
||||
return ValidateCustomFields('$iId', sFormId); // Custom validation function
|
||||
});
|
||||
EOF
|
||||
<<<JS
|
||||
$('#{$iId}_field_set').field_set($sFieldSetOptions);
|
||||
|
||||
$('#{$iId}_console_form').console_form_handler($sFormHandlerOptions);
|
||||
$('#{$iId}_console_form').console_form_handler('alignColumns');
|
||||
$('#{$iId}_console_form').console_form_handler('option', 'field_set', $('#{$iId}_field_set'));
|
||||
// field_change must be processed to refresh the hidden value at anytime
|
||||
$('#{$iId}_console_form').bind('value_change', function() { $('#{$iId}').val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); });
|
||||
// Initialize the hidden value with current state
|
||||
// update_value is triggered when preparing the wizard helper object for ajax calls
|
||||
$('#{$iId}').bind('update_value', function() { $(this).val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values'))); });
|
||||
// validate is triggered by CheckFields, on all the input fields, once at page init and once before submitting the form
|
||||
$('#{$iId}').bind('validate', function(evt, sFormId) {
|
||||
$(this).val(JSON.stringify($('#{$iId}_field_set').triggerHandler('get_current_values')));
|
||||
return ValidateCustomFields('$iId', sFormId); // Custom validation function
|
||||
});
|
||||
JS
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -2437,16 +2495,39 @@ EOF
|
||||
$sNullValue = "'$sNullValue'"; // Add quotes to turn this into a JS string if it's not a number
|
||||
}
|
||||
$sOriginalValue = ($iFlags & OPT_ATT_MUSTCHANGE) ? json_encode($value) : 'undefined';
|
||||
$oPage->add_ready_script("$('#$sFieldToValidateId').bind('".implode(' ',
|
||||
$aEventsList)."', function(evt, sFormId) { return ValidateField('$sFieldToValidateId', '$sPattern', $bMandatory, sFormId, $sNullValue, $sOriginalValue) } );\n"); // Bind to a custom event: validate
|
||||
$sEventList = implode(' ', $aEventsList);
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$('#$sFieldToValidateId')
|
||||
.bind('$sEventList',
|
||||
function(evt, sFormId) {
|
||||
// Bind to a custom event: validate
|
||||
return ValidateField('$sFieldToValidateId', '$sPattern', $bMandatory, sFormId, $sNullValue, $sOriginalValue);
|
||||
}
|
||||
);
|
||||
JS
|
||||
);
|
||||
}
|
||||
$aDependencies = MetaModel::GetDependentAttributes($sClass,
|
||||
$sAttCode); // List of attributes that depend on the current one
|
||||
|
||||
// handle dependent fields updates (init for WizardHelper JS object)
|
||||
if (count($aDependencies) > 0)
|
||||
{
|
||||
// Unbind first to avoid duplicate event handlers in case of reload of the whole (or part of the) form
|
||||
$oPage->add_ready_script("$('#$iId').unbind('change.dependencies').bind('change.dependencies', function(evt, sFormId) { return oWizardHelper{$sFormPrefix}.UpdateDependentFields(['".implode("','",
|
||||
$aDependencies)."']) } );\n"); // Bind to a custom event: validate
|
||||
//--- Add an event handler to launch a custom event: validate
|
||||
// * Unbind first to avoid duplicate event handlers in case of reload of the whole (or part of the) form
|
||||
// * We were using off/on directly on the node before, but that was causing an issue when adding dynamically new nodes
|
||||
// indeed the events weren't attached on the of the new nodes !
|
||||
// So we're adding the handler on a node above, and we're using a selector to catch only the event we're interested in !
|
||||
$sDependencies = implode("','", $aDependencies);
|
||||
|
||||
$oPage->add_ready_script(<<<JS
|
||||
$('div#field_{$iId}')
|
||||
.off('change.dependencies', '#$iId')
|
||||
.on('change.dependencies', '#$iId',
|
||||
function(evt, sFormId) {
|
||||
return $sWizardHelperJsVarName.UpdateDependentFields(['$sDependencies']);
|
||||
}
|
||||
);
|
||||
JS
|
||||
);
|
||||
}
|
||||
}
|
||||
$oPage->add_dict_entry('UI:ValueMustBeSet');
|
||||
@@ -3111,7 +3192,7 @@ EOF
|
||||
$this->GetOwnershipJSHandler($oPage, $sOwnershipToken);
|
||||
}
|
||||
|
||||
// Note: This part (inline images activation) is duplicated in self::DisplayModifyForm and several other places. Maybe it should be refactored so it automatically activates when an HTML field is present, or be an option of the attribute. See bug n°1240.
|
||||
// Note: This part (inline images activation) is duplicated in self::DisplayModifyForm and several other places. Maybe it should be refactored so it automatically activates when an HTML field is present, or be an option of the attribute. See bug N°1240.
|
||||
$sTempId = utils::GetUploadTempId($iTransactionId);
|
||||
$oPage->add_ready_script(InlineImage::EnableCKEditorImageUpload($this, $sTempId));
|
||||
}
|
||||
@@ -3796,19 +3877,24 @@ EOF
|
||||
break;
|
||||
|
||||
case 'Image':
|
||||
$value = null;
|
||||
$oImage = utils::ReadPostedDocument("attr_{$sFormPrefix}{$sAttCode}", 'fcontents');
|
||||
$aSize = utils::GetImageSize($oImage->GetData());
|
||||
$oImage = utils::ResizeImageToFit($oImage, $aSize[0], $aSize[1], $oAttDef->Get('storage_max_width'),
|
||||
$oAttDef->Get('storage_max_height'));
|
||||
if (!is_null($oImage->GetData()))
|
||||
{
|
||||
$aSize = utils::GetImageSize($oImage->GetData());
|
||||
$oImage = utils::ResizeImageToFit(
|
||||
$oImage,
|
||||
$aSize[0],
|
||||
$aSize[1],
|
||||
$oAttDef->Get('storage_max_width'),
|
||||
$oAttDef->Get('storage_max_height')
|
||||
);
|
||||
}
|
||||
$aOtherData = utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}", null, 'raw_data');
|
||||
if (is_array($aOtherData))
|
||||
{
|
||||
$value = array('fcontents' => $oImage, 'remove' => $aOtherData['remove']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'RedundancySetting':
|
||||
@@ -4131,6 +4217,16 @@ EOF
|
||||
$this->bAllowWrite = $bAllow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to bypass the checks of user rights when writing this object, could be used in {@link \iApplicationObjectExtension::OnCheckToWrite()}
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GetAllowWrite()
|
||||
{
|
||||
return $this->bAllowWrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bypass the check of the user rights when deleting this object
|
||||
*
|
||||
|
||||
@@ -491,7 +491,7 @@ abstract class Dashboard
|
||||
$("#attr_auto_reload_sec").prop('disabled', !$(this).is(':checked'));
|
||||
} );
|
||||
|
||||
$('#select_layout').buttonset();
|
||||
$('#select_layout').controlgroup();
|
||||
$('#select_dashlet').droppable({
|
||||
accept: '.dashlet',
|
||||
drop: function(event, ui) {
|
||||
@@ -928,6 +928,9 @@ class RuntimeDashboard extends Dashboard
|
||||
$sExtraParams = json_encode($aAjaxParams);
|
||||
$iReloadInterval = 1000 * $this->GetAutoReloadInterval();
|
||||
$sReloadURL = $this->GetReloadURL();
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext=$oAppContext->GetForPostParams();
|
||||
//$sContext is named "c" because it use the existing code for context parameters c[org_id] and c[menu]
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
if (typeof(AutoReloadDashboardId$sDivId) !== 'undefined')
|
||||
@@ -945,7 +948,7 @@ class RuntimeDashboard extends Dashboard
|
||||
{
|
||||
$('.dashboard_contents#$sDivId').block();
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
|
||||
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL'},
|
||||
{ operation: 'reload_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, c: $sContext, reload_url: '$sReloadURL'},
|
||||
function(data){
|
||||
$('.dashboard_contents#$sDivId').html(data);
|
||||
$('.dashboard_contents#$sDivId').unblock();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.6">
|
||||
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
|
||||
<classes>
|
||||
<class id="AbstractResource" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
@@ -399,7 +399,8 @@
|
||||
<stylesheets>
|
||||
<stylesheet id="jqueryui">../css/ui-lightness/jqueryui.scss</stylesheet>
|
||||
<stylesheet id="main">../css/light-grey.scss</stylesheet>
|
||||
</stylesheets>
|
||||
</stylesheets>
|
||||
<precompiled_stylesheet>itop-config-mgmt/precompiled-themes/light-grey/main.css</precompiled_stylesheet>
|
||||
</theme>
|
||||
<theme id="test-red" _delta="define">
|
||||
<variables>
|
||||
@@ -415,6 +416,7 @@
|
||||
<stylesheet id="main">../css/light-grey.scss</stylesheet>
|
||||
<stylesheet id="environment-banner">../css/backoffice-environment-banner.scss</stylesheet>
|
||||
</stylesheets>
|
||||
<precompiled_stylesheet>itop-config-mgmt/precompiled-themes/test-red/main.css</precompiled_stylesheet>
|
||||
</theme>
|
||||
</themes>
|
||||
</branding>
|
||||
|
||||
@@ -971,13 +971,13 @@ class DataTableSettings implements Serializable
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
static public function GetDataModelSettings($aClassAliases, $bViewLink, $aDefaultLists)
|
||||
public static function GetDataModelSettings($aClassAliases, $bViewLink, $aDefaultLists)
|
||||
{
|
||||
$oSettings = new DataTableSettings($aClassAliases);
|
||||
// Retrieve the class specific settings for each class/alias based on the 'list' ZList
|
||||
//TODO let the caller pass some other default settings (another Zlist, extre fields...)
|
||||
$aColumns = array();
|
||||
foreach($aClassAliases as $sAlias => $sClass)
|
||||
foreach ($aClassAliases as $sAlias => $sClass)
|
||||
{
|
||||
if ($aDefaultLists == null)
|
||||
{
|
||||
|
||||
@@ -24,15 +24,6 @@ require_once(APPROOT.'/application/utils.inc.php');
|
||||
*
|
||||
* Each block is actually rendered as a <div></div> tag that can be rendered synchronously
|
||||
* or as a piece of Javascript/JQuery/Ajax that will get its content from another page (ajax.render.php).
|
||||
* The list of cmdbObjects to be displayed into the block is defined by a filter
|
||||
* Right now the type of display is either: list, count, bare_details, details, csv, modify or search
|
||||
* - list produces a table listing the objects
|
||||
* - count produces a paragraphs with a sentence saying 'cont' objects found
|
||||
* - bare_details displays just the details of the attributes of the object (best if only one)
|
||||
* - details display the full details of each object found using its template (best if only one)
|
||||
* - csv displays a textarea with the CSV export of the list of objects
|
||||
* - modify displays the form to modify an object (best if only one)
|
||||
* - search displays a search form with the criteria of the filter set
|
||||
*/
|
||||
class DisplayBlock
|
||||
{
|
||||
@@ -45,7 +36,23 @@ class DisplayBlock
|
||||
protected $m_aParams;
|
||||
protected $m_oSet;
|
||||
protected $m_bShowObsoleteData = null;
|
||||
|
||||
|
||||
/**
|
||||
* @param \DBSearch $oFilter list of cmdbObjects to be displayed into the block
|
||||
* @param string $sStyle one of :
|
||||
* <ul>
|
||||
* <li>list : produces a table listing the objects</li>
|
||||
* <li>count : produces a paragraphs with a sentence saying 'cont' objects found</li>
|
||||
* <li>bare_details : displays just the details of the attributes of the object (best if only one)</li>
|
||||
* <li>details : display the full details of each object found using its template (best if only one)</li>
|
||||
* <li>csv : displays a textarea with the CSV export of the list of objects</li>
|
||||
* <li>modify : displays the form to modify an object (best if only one)</li>
|
||||
* <li>search : displays a search form with the criteria of the filter set</li>
|
||||
* </ul>
|
||||
* @param bool $bAsynchronous
|
||||
* @param array $aParams
|
||||
* @param \DBObjectSet $oSet
|
||||
*/
|
||||
public function __construct(DBSearch $oFilter, $sStyle = 'list', $bAsynchronous = false, $aParams = array(), $oSet = null)
|
||||
{
|
||||
$this->m_oFilter = $oFilter->DeepClone();
|
||||
|
||||
@@ -79,6 +79,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
$this->add_linked_stylesheet("../css/c3.min.css");
|
||||
$this->add_linked_stylesheet("../css/font-awesome/css/all.min.css");
|
||||
$this->add_linked_stylesheet("../js/ckeditor/plugins/codesnippet/lib/highlight/styles/obsidian.css");
|
||||
$this->add_linked_stylesheet("../css/selectize.default.css");
|
||||
|
||||
$this->add_linked_script('../js/jquery.layout.min.js');
|
||||
$this->add_linked_script('../js/jquery.ba-bbq.min.js');
|
||||
@@ -106,6 +107,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
$this->add_linked_script('../js/moment-with-locales.min.js');
|
||||
$this->add_linked_script('../js/showdown.min.js');
|
||||
$this->add_linked_script('../js/newsroom_menu.js');
|
||||
$this->add_linked_script("../js/selectize.min.js");
|
||||
|
||||
$this->add_dict_entry('UI:FillAllMandatoryFields');
|
||||
|
||||
@@ -804,21 +806,18 @@ JS
|
||||
break;
|
||||
|
||||
default:
|
||||
$sHtml = '';
|
||||
$oAppContext = new ApplicationContext();
|
||||
$iCurrentOrganization = $oAppContext->GetCurrentValue('org_id');
|
||||
$sHtml = '<div id="SiloSelection">';
|
||||
$sHtml .= '<form style="display:inline" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">';
|
||||
|
||||
$sFavoriteOrgs = '';
|
||||
$oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */);
|
||||
$sHtml .= $oWidget->Display($this, 50, false, '', $oSet, $iCurrentOrganization, 'org_id', false, 'c[org_id]', '',
|
||||
$sHtml .= $oWidget->DisplaySelect($this, 50, false, '', $oSet, $iCurrentOrganization, false, 'c[org_id]', '',
|
||||
array(
|
||||
'iFieldSize' => 20,
|
||||
'iMinChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'),
|
||||
'sDefaultValue' => Dict::S('UI:AllOrganizations'),
|
||||
),
|
||||
null, 'select', false /* bSearchMultiple */);
|
||||
));
|
||||
$this->add_ready_script('$("#org_id").bind("extkeychange", function() { $("#SiloSelection form").submit(); } )');
|
||||
$this->add_ready_script("$('#label_org_id').click( function() { if ($('#org_id').val() == '') { $(this).val(''); } } );\n");
|
||||
// Add other dimensions/context information to this form
|
||||
|
||||
@@ -107,7 +107,7 @@ class LoginWebPage extends NiceWebPage
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
*/
|
||||
public static function SynchroniseProfiles(&$oUser, array $aProfiles, $sOrigin)
|
||||
public static function SynchronizeProfiles(&$oUser, array $aProfiles, $sOrigin)
|
||||
{
|
||||
$oProfilesSet = $oUser->Get(‘profile_list’);
|
||||
//delete old profiles
|
||||
@@ -928,7 +928,7 @@ class LoginWebPage extends NiceWebPage
|
||||
{
|
||||
$sOrigin .= " ({$_SESSION['login_mode']})";
|
||||
}
|
||||
$aExistingProfiles = self::SynchroniseProfiles($oUser, $aProfiles, $sOrigin);
|
||||
$aExistingProfiles = self::SynchronizeProfiles($oUser, $aProfiles, $sOrigin);
|
||||
if ($oUser->IsModified())
|
||||
{
|
||||
$oUser->DBWrite();
|
||||
|
||||
@@ -39,7 +39,7 @@ class NiceWebPage extends WebPage
|
||||
{
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-migrate.prod.min.js');
|
||||
}
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui-1.11.4.custom.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui.custom.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/hovertip.js');
|
||||
// table sorting
|
||||
|
||||
@@ -35,7 +35,17 @@ register_shutdown_function(function()
|
||||
$sReservedMemory = null;
|
||||
if (!is_null($err = error_get_last()) && ($err['type'] == E_ERROR))
|
||||
{
|
||||
IssueLog::error($err['message']);
|
||||
// Remove stack trace from MySQLException
|
||||
$sMessage = $err['message'];
|
||||
if (strpos($sMessage, 'MySQLException') !== false)
|
||||
{
|
||||
$iStackTracePos = strpos($sMessage, 'Stack trace:');
|
||||
if ($iStackTracePos !== false)
|
||||
{
|
||||
$sMessage = substr($sMessage, 0, $iStackTracePos);
|
||||
}
|
||||
}
|
||||
IssueLog::error($sMessage);
|
||||
if (strpos($err['message'], 'Allowed memory size of') !== false)
|
||||
{
|
||||
$sLimit = ini_get('memory_limit');
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
*/
|
||||
class ThemeHandler
|
||||
{
|
||||
const IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg'];
|
||||
|
||||
private static $oCompileCSSService;
|
||||
/**
|
||||
* Return default theme name and parameters
|
||||
*
|
||||
@@ -33,19 +36,19 @@ class ThemeHandler
|
||||
*/
|
||||
public static function GetDefaultThemeInformation()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'name' => 'light-grey',
|
||||
'parameters' => array(
|
||||
'variables' => array(),
|
||||
'imports' => array(
|
||||
'parameters' => [
|
||||
'variables' => [],
|
||||
'imports' => [
|
||||
'css-variables' => '../css/css-variables.scss',
|
||||
),
|
||||
'stylesheets' => array(
|
||||
],
|
||||
'stylesheets' => [
|
||||
'jqueryui' => '../css/ui-lightness/jqueryui.scss',
|
||||
'main' => '../css/light-grey.scss',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +60,10 @@ class ThemeHandler
|
||||
{
|
||||
try
|
||||
{
|
||||
if (is_null(MetaModel::GetConfig()))
|
||||
{
|
||||
throw new CoreException('no config');
|
||||
}
|
||||
$sThemeId = MetaModel::GetConfig()->Get('backoffice_default_theme');
|
||||
}
|
||||
catch(CoreException $oCompileException)
|
||||
@@ -108,37 +115,49 @@ class ThemeHandler
|
||||
SetupUtils::builddir($sDefaultThemeDirPath);
|
||||
}
|
||||
|
||||
static::CompileTheme($sThemeId, $aDefaultTheme['parameters']);
|
||||
static::CompileTheme($sThemeId, false, "", $aDefaultTheme['parameters']);
|
||||
}
|
||||
|
||||
// Return absolute url to theme compiled css
|
||||
return utils::GetAbsoluteUrlModulesRoot().'/branding/themes/'.$sThemeId.'/main.css';
|
||||
return utils::GetAbsoluteUrlModulesRoot().'branding/themes/'.$sThemeId.'/main.css';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the $sThemeId theme
|
||||
* Compile the $sThemeId theme, the actual compilation is skipped when either
|
||||
* 1) The produced CSS file exists and is more recent than any of its components (imports, stylesheets)
|
||||
* 2) The produced CSS file exists and its signature is equal to the expected signature (imports, stylesheets, variables)
|
||||
*
|
||||
* @param string $sThemeId
|
||||
* @param boolean $bSetup
|
||||
* @param string $sSetupCompilationTimestamp : setup compilation timestamp in micro secunds
|
||||
* @param array|null $aThemeParameters Parameters (variables, imports, stylesheets) for the theme, if not passed, will be retrieved from compiled DM
|
||||
* @param array|null $aImportsPaths Paths where imports can be found. Must end with '/'
|
||||
* @param string|null $sWorkingPath Path of the folder used during compilation. Must end with a '/'
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @return boolean: indicate whether theme compilation occured
|
||||
*/
|
||||
public static function CompileTheme($sThemeId, $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||
public static function CompileTheme($sThemeId, $bSetup=false, $sSetupCompilationTimestamp="", $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
|
||||
{
|
||||
if ($sSetupCompilationTimestamp==="")
|
||||
{
|
||||
$sSetupCompilationTimestamp = microtime(true);
|
||||
}
|
||||
|
||||
$sSetupCompilationTimestampInSecunds = (strpos($sSetupCompilationTimestamp, '.') !==false) ? explode('.', $sSetupCompilationTimestamp)[0] : $sSetupCompilationTimestamp;
|
||||
|
||||
$sEnv = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
||||
|
||||
// Default working path
|
||||
if($sWorkingPath === null)
|
||||
{
|
||||
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
|
||||
$sWorkingPath = $sEnv;
|
||||
}
|
||||
|
||||
// Default import paths (env-*)
|
||||
if($aImportsPaths === null)
|
||||
{
|
||||
$aImportsPaths = array(
|
||||
APPROOT.'env-'.utils::GetCurrentEnvironment().'/',
|
||||
);
|
||||
$aImportsPaths = [ $sEnv];
|
||||
}
|
||||
|
||||
// Note: We do NOT check that the folder exists!
|
||||
@@ -148,6 +167,11 @@ class ThemeHandler
|
||||
// Save parameters if passed... (typically during DM compilation)
|
||||
if(is_array($aThemeParameters))
|
||||
{
|
||||
if (!is_dir($sThemeFolderPath))
|
||||
{
|
||||
mkdir($sWorkingPath.'/branding/');
|
||||
mkdir($sWorkingPath.'/branding/themes/');
|
||||
}
|
||||
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
||||
}
|
||||
// ... Otherwise, retrieve them from compiled DM (typically when switching current theme in the config. file)
|
||||
@@ -160,31 +184,589 @@ class ThemeHandler
|
||||
}
|
||||
}
|
||||
|
||||
$aThemeParametersWithVersion = self::CloneThemeParameterAndIncludeVersion($aThemeParameters, $sSetupCompilationTimestampInSecunds);
|
||||
|
||||
$sTmpThemeScssContent = '';
|
||||
$iStyleLastModified = 0;
|
||||
clearstatcache();
|
||||
// Loading files to import and stylesheet to compile, also getting most recent modification time on overall files
|
||||
|
||||
$aStylesheetFiles = [];
|
||||
foreach ($aThemeParameters['imports'] as $sImport)
|
||||
{
|
||||
$sTmpThemeScssContent .= '@import "'.$sImport.'";'."\n";
|
||||
|
||||
$iImportLastModified = @filemtime($sWorkingPath.$sImport);
|
||||
$sFile = static::FindStylesheetFile($sImport, $aImportsPaths);
|
||||
$iImportLastModified = @filemtime($sFile);
|
||||
$aStylesheetFiles[] = $sFile;
|
||||
$iStyleLastModified = $iStyleLastModified < $iImportLastModified ? $iImportLastModified : $iStyleLastModified;
|
||||
}
|
||||
foreach ($aThemeParameters['stylesheets'] as $sStylesheet)
|
||||
{
|
||||
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
|
||||
|
||||
$iStylesheetLastModified = @filemtime($sWorkingPath.$sStylesheet);
|
||||
$sFile = static::FindStylesheetFile($sStylesheet, $aImportsPaths);
|
||||
$iStylesheetLastModified = @filemtime($sFile);
|
||||
$aStylesheetFiles[] = $sFile;
|
||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||
}
|
||||
|
||||
// Checking if our compiled css is outdated
|
||||
if (!file_exists($sThemeCssPath) || (is_writable($sThemeFolderPath) && (@filemtime($sThemeCssPath) < $iStyleLastModified)))
|
||||
$aIncludedImages=static::GetIncludedImages($aThemeParametersWithVersion, $aStylesheetFiles, $sThemeId);
|
||||
foreach ($aIncludedImages as $sImage)
|
||||
{
|
||||
$sTmpThemeCssContent = utils::CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths, $aThemeParameters['variables']);
|
||||
file_put_contents($sThemeCssPath, $sTmpThemeCssContent);
|
||||
if (is_file($sImage))
|
||||
{
|
||||
$iStylesheetLastModified = @filemtime($sImage);
|
||||
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
|
||||
}
|
||||
}
|
||||
|
||||
// Checking if our compiled css is outdated
|
||||
$iFilemetime = @filemtime($sThemeCssPath);
|
||||
$bFileExists = file_exists($sThemeCssPath);
|
||||
$bVarSignatureChanged=false;
|
||||
if ($bFileExists && $bSetup)
|
||||
{
|
||||
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||
//check variable signature has changed which is independant from any file modification
|
||||
if (!empty($sPrecompiledSignature)){
|
||||
$sPreviousVariableSignature = static::GetVarSignature($sPrecompiledSignature);
|
||||
$sCurrentVariableSignature = md5(json_encode($aThemeParameters['variables']));
|
||||
$bVarSignatureChanged= ($sPreviousVariableSignature!==$sCurrentVariableSignature);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bFileExists || $bVarSignatureChanged || (is_writable($sThemeFolderPath) && ($iFilemetime < $iStyleLastModified)))
|
||||
{
|
||||
// Dates don't match. Second chance: check if the already compiled stylesheet exists and is consistent based on its signature
|
||||
$sActualSignature = static::ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages);
|
||||
|
||||
if ($bFileExists && !$bSetup)
|
||||
{
|
||||
$sPrecompiledSignature = static::GetSignature($sThemeCssPath);
|
||||
}
|
||||
|
||||
if (!empty($sPrecompiledSignature) && $sActualSignature == $sPrecompiledSignature)
|
||||
{
|
||||
touch($sThemeCssPath); // Stylesheet is up to date, mark it as more recent to speedup next time
|
||||
}
|
||||
else
|
||||
{
|
||||
// Alas, we really need to recompile
|
||||
// Add the signature to the generated CSS file so that the file can be used as a precompiled stylesheet if needed
|
||||
$sSignatureComment =
|
||||
<<<CSS
|
||||
/*
|
||||
=== SIGNATURE BEGIN ===
|
||||
$sActualSignature
|
||||
=== SIGNATURE END ===
|
||||
*/
|
||||
|
||||
CSS;
|
||||
if (!static::$oCompileCSSService)
|
||||
{
|
||||
static::$oCompileCSSService = new CompileCSSService();
|
||||
}
|
||||
//store it again to change $version with latest compiled time
|
||||
$sTmpThemeCssContent = static::$oCompileCSSService->CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths,
|
||||
$aThemeParametersWithVersion);
|
||||
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
|
||||
file_put_contents($sThemeCssPath, $sSignatureComment.$sTmpThemeCssContent);
|
||||
SetupLog::Info("Theme $sThemeId file compiled.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the signature of a theme defined by its theme parameters. The signature is a JSON structure of
|
||||
* 1) one MD5 of all the variables/values (JSON encoded)
|
||||
* 2) the MD5 of each stylesheet file
|
||||
* 3) the MD5 of each import file
|
||||
* 3) the MD5 of each images referenced in style sheets
|
||||
*
|
||||
* @param string[] $aThemeParameters
|
||||
* @param string[] $aImportsPaths
|
||||
* @param string[] $aIncludedImages
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function ComputeSignature($aThemeParameters, $aImportsPaths, $aIncludedImages)
|
||||
{
|
||||
$aSignature = [
|
||||
'variables' => md5(json_encode($aThemeParameters['variables'])),
|
||||
'stylesheets' => [],
|
||||
'imports' => [],
|
||||
'images' => []
|
||||
];
|
||||
|
||||
foreach ($aThemeParameters['imports'] as $key => $sImport)
|
||||
{
|
||||
$sFile = static::FindStylesheetFile($sImport, $aImportsPaths);
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
}
|
||||
foreach ($aThemeParameters['stylesheets'] as $key => $sStylesheet)
|
||||
{
|
||||
$sFile = static::FindStylesheetFile($sStylesheet, $aImportsPaths);
|
||||
$aSignature['stylesheets'][$key] = md5_file($sFile);
|
||||
}
|
||||
foreach ($aIncludedImages as $sImage)
|
||||
{
|
||||
if (is_file($sImage))
|
||||
{
|
||||
$sUri = str_replace(APPROOT, '', $sImage);
|
||||
$aSignature['images'][$sUri] = md5_file($sImage);
|
||||
}
|
||||
}
|
||||
|
||||
return json_encode($aSignature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for images referenced in stylesheet files
|
||||
*
|
||||
* @param array $aThemeParametersVariables
|
||||
* @param array $aStylesheetFiles
|
||||
* @param string $sThemeId: used only for logging purpose
|
||||
*
|
||||
* @return array
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public static function GetIncludedImages($aThemeParametersVariables, $aStylesheetFiles, $sThemeId)
|
||||
{
|
||||
$sTargetThemeFolderPath = static::GetCompiledThemeFolderAbsolutePath($sThemeId);
|
||||
|
||||
$aCompleteUrls = [];
|
||||
$aToCompleteUrls = [];
|
||||
$aMissingVariables = [];
|
||||
$aFoundVariables = ['version'=>''];
|
||||
$aMap = [
|
||||
'aCompleteUrls' => $aCompleteUrls,
|
||||
'aToCompleteUrls' => $aToCompleteUrls,
|
||||
'aMissingVariables' => $aMissingVariables,
|
||||
'aFoundVariables' => $aFoundVariables,
|
||||
];
|
||||
|
||||
foreach ($aStylesheetFiles as $sStylesheetFile)
|
||||
{
|
||||
$aRes = static::GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile);
|
||||
/** @var array $aVal */
|
||||
foreach($aMap as $key => $aVal)
|
||||
{
|
||||
if (array_key_exists($key, $aMap))
|
||||
{
|
||||
$aMap[$key] = array_merge($aVal, $aRes[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$aMap = static::ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFiles);
|
||||
$aImages = [];
|
||||
|
||||
foreach ($aMap ['aCompleteUrls'] as $sUri => $sUrl)
|
||||
{
|
||||
$sImg = $sUrl;
|
||||
if (preg_match("/(.*)\?/", $sUrl, $aMatches))
|
||||
{
|
||||
$sImg=$aMatches[1];
|
||||
}
|
||||
|
||||
if (static::HasImageExtension($sImg)
|
||||
&& ! array_key_exists($sImg, $aImages))
|
||||
{
|
||||
$sFilePath = realpath($sImg);
|
||||
if ($sFilePath!==false)
|
||||
{
|
||||
$aImages[$sImg]=$sFilePath;
|
||||
continue;
|
||||
}
|
||||
|
||||
$sCanonicalPath = static::CanonicalizePath($sTargetThemeFolderPath.DIRECTORY_SEPARATOR.$sImg);
|
||||
$sFilePath=realpath($sCanonicalPath);
|
||||
if ($sFilePath!==false)
|
||||
{
|
||||
$aImages[$sImg]=$sFilePath;
|
||||
continue;
|
||||
}
|
||||
|
||||
SetupLog::Warning("Cannot find $sCanonicalPath ($sImg) during SCSS $sThemeId precompilation");
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($aImages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce path without using realpath (works only when file exists)
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function CanonicalizePath($path)
|
||||
{
|
||||
$path = explode('/', str_replace('//','/', $path));
|
||||
$stack = array();
|
||||
foreach ($path as $seg) {
|
||||
if ($seg == '..') {
|
||||
// Ignore this segment, remove last segment from stack
|
||||
array_pop($stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($seg == '.') {
|
||||
// Ignore this segment
|
||||
continue;
|
||||
}
|
||||
|
||||
$stack[] = $seg;
|
||||
}
|
||||
|
||||
return implode('/', $stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete url using provided variables. Example with $var=1: XX + $var => XX1
|
||||
* @param $aMap
|
||||
* @param $aThemeParametersVariables
|
||||
* @param $aStylesheetFile
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function ResolveUncompleteUrlsFromScss($aMap, $aThemeParametersVariables, $aStylesheetFile)
|
||||
{
|
||||
$sContent="";
|
||||
foreach ($aStylesheetFile as $sStylesheetFile)
|
||||
{
|
||||
if (is_file($sStylesheetFile))
|
||||
{
|
||||
$sContent .= '\n' . file_get_contents($sStylesheetFile);
|
||||
}
|
||||
}
|
||||
|
||||
$aMissingVariables=$aMap['aMissingVariables'];
|
||||
$aFoundVariables=$aMap['aFoundVariables'];
|
||||
$aToCompleteUrls=$aMap['aToCompleteUrls'];
|
||||
$aCompleteUrls=$aMap['aCompleteUrls'];
|
||||
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, true);
|
||||
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||
$aMap['aMissingVariables']=$aMissingVariables;
|
||||
$aMap['aFoundVariables']=$aFoundVariables;
|
||||
$aMap['aToCompleteUrls']=$aToCompleteUrls;
|
||||
$aMap['aCompleteUrls']=$aCompleteUrls;
|
||||
return $aMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find missing variable values from SCSS content based on their name.
|
||||
*
|
||||
* @param $aThemeParametersVariables
|
||||
* @param $aMissingVariables
|
||||
* @param $aFoundVariables
|
||||
* @param $sContent : scss content
|
||||
* @param bool $bForceEmptyValueWhenNotFound
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent, $bForceEmptyValueWhenNotFound=false)
|
||||
{
|
||||
$aNewMissingVars = [];
|
||||
if (!empty($aMissingVariables))
|
||||
{
|
||||
foreach ($aMissingVariables as $var)
|
||||
{
|
||||
if (array_key_exists($var, $aThemeParametersVariables))
|
||||
{
|
||||
$aFoundVariables[$var] = $aThemeParametersVariables[$var];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (preg_match_all("/\\\$$var\s*:\s*[\"']{0,1}(.*)[\"']{0,1};/", $sContent, $aValues))
|
||||
{
|
||||
$sValue = $aValues[1][0];
|
||||
if (preg_match_all("/([^!]+)!/", $sValue, $aSubValues))
|
||||
{
|
||||
$sValue = trim($aSubValues[1][0], ' "\'');
|
||||
}
|
||||
|
||||
if (strpos($sValue, '$') === false)
|
||||
{
|
||||
$aFoundVariables[$var] = $sValue;
|
||||
}
|
||||
else{
|
||||
$aNewMissingVars[] = $var;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($bForceEmptyValueWhenNotFound)
|
||||
{
|
||||
$aFoundVariables[$var] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aNewMissingVars[] = $var;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [ $aNewMissingVars, $aFoundVariables ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aFoundVariables
|
||||
* @param array $aToCompleteUrls
|
||||
* @param array $aCompleteUrls
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function ResolveUrls($aFoundVariables, array $aToCompleteUrls, array $aCompleteUrls)
|
||||
{
|
||||
if (!empty($aFoundVariables))
|
||||
{
|
||||
$aFoundVariablesWithEmptyValue = [];
|
||||
foreach ($aFoundVariables as $aFoundVariable => $sValue)
|
||||
{
|
||||
$aFoundVariablesWithEmptyValue[$aFoundVariable] = '';
|
||||
}
|
||||
|
||||
foreach ($aToCompleteUrls as $sUrlTemplate)
|
||||
{
|
||||
unset($aToCompleteUrls[$sUrlTemplate]);
|
||||
$sResolvedUrl = static::ResolveUrl($sUrlTemplate, $aFoundVariables);
|
||||
if ($sResolvedUrl == false)
|
||||
{
|
||||
$aToCompleteUrls[$sUrlTemplate] = $sUrlTemplate;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUri = static::ResolveUrl($sUrlTemplate, $aFoundVariablesWithEmptyValue);
|
||||
$aExplodedUri = explode('?', $sUri);
|
||||
if (empty($aExplodedUri))
|
||||
{
|
||||
$aCompleteUrls[$sUri] = $sResolvedUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCompleteUrls[$aExplodedUri[0]] = $sResolvedUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [ $aToCompleteUrls, $aCompleteUrls];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all referenced URLs from a SCSS file.
|
||||
* @param $aThemeParametersVariables
|
||||
* @param $sStylesheetFile
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetAllUrlFromScss($aThemeParametersVariables, $sStylesheetFile)
|
||||
{
|
||||
$aCompleteUrls = [];
|
||||
$aToCompleteUrls = [];
|
||||
$aMissingVariables = [];
|
||||
$aFoundVariables = [];
|
||||
|
||||
if (is_file($sStylesheetFile))
|
||||
{
|
||||
$sContent = file_get_contents($sStylesheetFile);
|
||||
if (preg_match_all("/url\s*\((.*)\)/", $sContent, $aMatches))
|
||||
{
|
||||
foreach ($aMatches[1] as $path)
|
||||
{
|
||||
if (!array_key_exists($path, $aCompleteUrls)
|
||||
&& !array_key_exists($path, $aToCompleteUrls))
|
||||
{
|
||||
if (preg_match_all("/\\$([\w\-_]+)/", $path, $aCurrentVars))
|
||||
{
|
||||
/** @var string $aCurrentVars */
|
||||
foreach ($aCurrentVars[1] as $var)
|
||||
{
|
||||
if (!array_key_exists($var, $aMissingVariables))
|
||||
{
|
||||
$aMissingVariables[$var] = $var;
|
||||
}
|
||||
}
|
||||
$aToCompleteUrls[$path] = $path;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCompleteUrls[$path] = trim($path, "\"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($aMissingVariables))
|
||||
{
|
||||
list($aMissingVariables, $aFoundVariables) = static::FindMissingVariables($aThemeParametersVariables, $aMissingVariables, $aFoundVariables, $sContent);
|
||||
list($aToCompleteUrls, $aCompleteUrls) = static::ResolveUrls($aFoundVariables, $aToCompleteUrls, $aCompleteUrls);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'aCompleteUrls' => $aCompleteUrls,
|
||||
'aToCompleteUrls' => $aToCompleteUrls,
|
||||
'aMissingVariables' => $aMissingVariables,
|
||||
'aFoundVariables' => $aFoundVariables
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate url based on its template + variables.
|
||||
* @param $sUrlTemplate
|
||||
* @param $aFoundVariables
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function ResolveUrl($sUrlTemplate, $aFoundVariables)
|
||||
{
|
||||
$aPattern= [];
|
||||
$aReplacement= [];
|
||||
foreach ($aFoundVariables as $aFoundVariable => $aFoundVariableValue)
|
||||
{
|
||||
//XX + $key + YY
|
||||
$aPattern[]="/['\"]\s*\+\s*\\\$" . $aFoundVariable . "[\s\+]+\s*['\"]/";
|
||||
$aReplacement[]=$aFoundVariableValue;
|
||||
//$key + YY
|
||||
$aPattern[]="/\\\$" . $aFoundVariable. "[\s\+]+\s*['\"]/";
|
||||
$aReplacement[]=$aFoundVariableValue;
|
||||
//XX + $key
|
||||
$aPattern[]="/['\"]\s*[\+\s]+\\\$" . $aFoundVariable . "$/";
|
||||
$aReplacement[]=$aFoundVariableValue;
|
||||
}
|
||||
$sResolvedUrl=preg_replace($aPattern, $aReplacement, $sUrlTemplate);
|
||||
if (strpos($sResolvedUrl, "+")!==false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return trim($sResolvedUrl, "\"'");
|
||||
}
|
||||
|
||||
/**
|
||||
* indicate whether a string ends with image suffix.
|
||||
* @param $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function HasImageExtension($path)
|
||||
{
|
||||
foreach (static::IMAGE_EXTENSIONS as $sExt)
|
||||
{
|
||||
if (endsWith($path, $sExt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract the signature for a generated CSS file. The signature MUST be alone one line immediately
|
||||
* followed (on the next line) by the === SIGNATURE END === pattern
|
||||
*
|
||||
* Note the signature can be place anywhere in the CSS file (obviously inside a CSS comment !) but the
|
||||
* function will be faster if the signature is at the beginning of the file (since the file is scanned from the start)
|
||||
*
|
||||
* @param $sFilepath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function GetSignature($sFilepath)
|
||||
{
|
||||
$sPreviousLine = '';
|
||||
$hFile = @fopen($sFilepath, "r");
|
||||
if ($hFile !== false)
|
||||
{
|
||||
$sLine = '';
|
||||
do
|
||||
{
|
||||
$sPreviousLine = $sLine;
|
||||
$sLine = rtrim(fgets($hFile)); // Remove the trailing \n
|
||||
}
|
||||
while (($sLine !== false) && ($sLine != '=== SIGNATURE END ==='));
|
||||
fclose($hFile);
|
||||
}
|
||||
return $sPreviousLine;
|
||||
}
|
||||
|
||||
public static function GetVarSignature($JsonSignature)
|
||||
{
|
||||
$aJsonArray = json_decode($JsonSignature, true);
|
||||
if (array_key_exists('variables', $aJsonArray))
|
||||
{
|
||||
return $aJsonArray['variables'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the given file in the list of ImportsPaths directory
|
||||
* @param string $sFile
|
||||
* @param string[] $aImportsPaths
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public static function FindStylesheetFile($sFile, $aImportsPaths)
|
||||
{
|
||||
foreach($aImportsPaths as $sPath)
|
||||
{
|
||||
$sImportedFile = realpath($sPath.'/'.$sFile);
|
||||
if (file_exists($sImportedFile))
|
||||
{
|
||||
return $sImportedFile;
|
||||
}
|
||||
}
|
||||
return ''; // Not found, fail silently, maybe the SCSS compiler knowns better...
|
||||
}
|
||||
|
||||
public static function MockCompileCSSService($oCompileCSSServiceMock)
|
||||
{
|
||||
static::$oCompileCSSService = $oCompileCSSServiceMock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone variable array and include $version with bSetupCompilationTimestamp value
|
||||
* @param $aThemeParameters
|
||||
* @param $bSetupCompilationTimestamp
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp)
|
||||
{
|
||||
$aThemeParametersVariable = [];
|
||||
if (array_key_exists('variables', $aThemeParameters))
|
||||
{
|
||||
if (is_array($aThemeParameters['variables']))
|
||||
{
|
||||
$aThemeParametersVariable = array_merge([], $aThemeParameters['variables']);
|
||||
}
|
||||
}
|
||||
|
||||
$aThemeParametersVariable['$version'] = $bSetupCompilationTimestamp;
|
||||
return $aThemeParametersVariable;
|
||||
}
|
||||
}
|
||||
|
||||
class CompileCSSService
|
||||
{
|
||||
/**
|
||||
* CompileCSSService constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function CompileCSSFromSASS($sSassContent, $aImportPaths = [], $aVariables = []){
|
||||
return utils::CompileCSSFromSASS($sSassContent, $aImportPaths, $aVariables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +234,14 @@ class privUITransactionFile
|
||||
*/
|
||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||
{
|
||||
$sFilepath = APPROOT.'data/transactions/'.$id;
|
||||
// Constraint the transaction file within APPROOT.'data/transactions'
|
||||
$sTransactionDir = realpath(APPROOT.'data/transactions');
|
||||
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
||||
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
clearstatcache(true, $sFilepath);
|
||||
$bResult = file_exists($sFilepath);
|
||||
if ($bResult)
|
||||
|
||||
@@ -68,6 +68,7 @@ class UIExtKeyWidget
|
||||
protected $iId;
|
||||
protected $sTargetClass;
|
||||
protected $sAttCode;
|
||||
//@deprecated
|
||||
protected $bSearchMode;
|
||||
|
||||
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
|
||||
@@ -86,7 +87,29 @@ class UIExtKeyWidget
|
||||
$sDisplayStyle = 'select'; // In search mode, always use a drop-down list
|
||||
}
|
||||
$oWidget = new UIExtKeyWidget($sTargetClass, $iInputId, $sAttCode, $bSearchMode);
|
||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle);
|
||||
if(!$bSearchMode)
|
||||
{
|
||||
switch($sDisplayStyle)
|
||||
{
|
||||
case 'radio':
|
||||
case 'radio_horizontal':
|
||||
case 'radio_vertical':
|
||||
|
||||
return $oWidget->DisplayRadio($oPage, $iMaxComboLength, $bAllowTargetCreation, $oAllowedValues, $value, $sFieldName, $sDisplayStyle);
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
case 'list':
|
||||
default:
|
||||
return $oWidget->DisplaySelect($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value,
|
||||
$bMandatory, $sFieldName, $sFormPrefix, $aArgs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oWidget->Display($oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix, $aArgs, null, $sDisplayStyle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function __construct($sTargetClass, $iInputId, $sAttCode = '', $bSearchMode = false)
|
||||
@@ -98,6 +121,289 @@ class UIExtKeyWidget
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||
* Get the HTML fragment corresponding to the ext key editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param array $aArgs Extra context arguments
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
*/
|
||||
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array())
|
||||
{
|
||||
$sTitle = addslashes($sTitle);
|
||||
$oPage->add_linked_script('../js/extkeywidget.js');
|
||||
$oPage->add_linked_script('../js/forms-json-utils.js');
|
||||
|
||||
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||
$bExtensions = true;
|
||||
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
|
||||
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||
$sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
|
||||
if($this->bSearchMode)
|
||||
{
|
||||
$sWizHelper = 'null';
|
||||
$sWizHelperJSON = "''";
|
||||
$sJSSearchMode = 'true';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($aArgs['wizHelper']))
|
||||
{
|
||||
$sWizHelper = $aArgs['wizHelper'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
}
|
||||
$sWizHelperJSON = $sWizHelper.'.UpdateWizardToJSON()';
|
||||
$sJSSearchMode = 'false';
|
||||
}
|
||||
if (is_null($oAllowedValues))
|
||||
{
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
// Don't automatically launch the search if the table is huge
|
||||
$bDoSearch = !utils::IsHighCardinality($this->sTargetClass);
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
|
||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
||||
{
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
$sHelpText = ''; //$this->oAttDef->GetHelpOnEdition();
|
||||
//$sHTMLValue .= "<div class=\"field_select_wrapper\">\n";
|
||||
$aOptions = [];
|
||||
$sDisplayValue = "";
|
||||
|
||||
$aOption = [];
|
||||
$aOption['value'] = "";
|
||||
$aOption['label'] = Dict::S('UI:SelectOne');
|
||||
array_push($aOptions,$aOption);
|
||||
|
||||
$oAllowedValues->Rewind();
|
||||
$bAddingValue=false;
|
||||
|
||||
$aComplementAttributeSpec = MetaModel::GetComplementAttributeSpec($oAllowedValues->GetClass());
|
||||
$sFormatAdditionalField = $aComplementAttributeSpec[0];
|
||||
$aAdditionalField = $aComplementAttributeSpec[1];
|
||||
|
||||
if (count($aAdditionalField)>0)
|
||||
{
|
||||
$bAddingValue=true;
|
||||
}
|
||||
while($oObj = $oAllowedValues->Fetch())
|
||||
{
|
||||
$aOption=[];
|
||||
$aOption['value'] = $oObj->GetKey();
|
||||
$aOption['label'] = $oObj->GetName();//.'<span class=\"object-ref-icon fas fa-eye-slash object-obsolete fa-1x fa-fw\"></span>';
|
||||
|
||||
if (($oAllowedValues->Count() == 1) && ($bMandatory == 'true') )
|
||||
{
|
||||
// When there is only once choice, select it by default
|
||||
$sDisplayValue=$oObj->GetName();
|
||||
if($value != $oObj->GetKey())
|
||||
{
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
$('#$this->iId').attr('data-validate','dependencies');
|
||||
EOF
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((is_array($value) && in_array($oObj->GetKey(), $value)) || ($value == $oObj->GetKey()))
|
||||
{
|
||||
$sDisplayValue=$oObj->GetKey();
|
||||
// $sHTMLValue.="<div class='item' data-value='".$oObj->GetKey)."'>".$oObj->GetName()."</div>";
|
||||
}
|
||||
}
|
||||
if ($oObj->IsObsolete()){
|
||||
$aOption['obsolescence_flag'] ="1";
|
||||
}
|
||||
if ($bAddingValue)
|
||||
{
|
||||
$aArguments = [];
|
||||
foreach ($aAdditionalField as $sAdditionalField)
|
||||
{
|
||||
array_push($aArguments,$oObj->Get($sAdditionalField));
|
||||
}
|
||||
$aOption['additional_field'] = vsprintf($sFormatAdditionalField, $aArguments);
|
||||
}
|
||||
array_push($aOptions,$aOption);
|
||||
}
|
||||
$sHTMLValue .= "<select title=\"$sHelpText\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"$this->iId\"></select>";
|
||||
$sJsonOptions=json_encode($aOptions);
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', true, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
oACWidget_{$this->iId}.AddSelectize('$sJsonOptions','$sDisplayValue');
|
||||
$('#$this->iId').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
|
||||
$('#$this->iId').bind('change', function() { $(this).trigger('extkeychange') } );
|
||||
|
||||
JS
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too many choices, use an autocomplete
|
||||
// Check that the given value is allowed
|
||||
$oSearch = $oAllowedValues->GetFilter();
|
||||
$oSearch->AddCondition('id', $value);
|
||||
$oSet = new DBObjectSet($oSearch);
|
||||
if ($oSet->Count() == 0)
|
||||
{
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if (is_null($value) || ($value == 0)) // Null values are displayed as ''
|
||||
{
|
||||
$sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sDisplayValue = $this->GetObjectName($value);
|
||||
}
|
||||
$iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 2; //@@@ $this->oAttDef->GetMinAutoCompleteChars();
|
||||
|
||||
// the input for the auto-complete
|
||||
$sHTMLValue .= "<input class=\"field_autocomplete\" type=\"text\" id=\"label_$this->iId\" value=\"$sDisplayValue\"/>";
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_search_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.Search();\"><i class=\"fas fa-search\"></i></div></span>";
|
||||
|
||||
// another hidden input to store & pass the object's Id
|
||||
$sHTMLValue .= "<input type=\"hidden\" id=\"$this->iId\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"".htmlentities($value, ENT_QUOTES, 'UTF-8')."\" />\n";
|
||||
|
||||
$JSSearchMode = $this->bSearchMode ? 'true' : 'false';
|
||||
// Scripts to start the autocomplete and bind some events to it
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
oACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '$sFilter', '$sTitle', false, $sWizHelper, '{$this->sAttCode}', $sJSSearchMode, $sJSDoSearch);
|
||||
oACWidget_{$this->iId}.emptyHtml = "<div style=\"background: #fff; border:0; text-align:center; vertical-align:middle;\"><p>$sMessage</p></div>";
|
||||
oACWidget_{$this->iId}.AddAutocomplete($iMinChars, $sWizHelperJSON);
|
||||
if ($('#ac_dlg_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
if ($bCreate && $bExtensions)
|
||||
{
|
||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
$sHTMLValue .= "</div>";
|
||||
$sHTMLValue .= "<span class=\"form_validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
|
||||
return $sHTMLValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0 N°2508 - Include Obsolescence icon within list and autocomplete
|
||||
* Get the HTML fragment corresponding to the ext key editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param array $aArgs Extra context arguments
|
||||
* @return string The HTML fragment to be inserted into the page
|
||||
*/
|
||||
public function DisplayRadio(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, DBObjectset $oAllowedValues, $value, $sFieldName, $sDisplayStyle)
|
||||
{
|
||||
$oPage->add_linked_script('../js/forms-json-utils.js');
|
||||
|
||||
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||
$bExtensions = true;
|
||||
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
|
||||
|
||||
$sHTMLValue = "<div class=\"field_input_zone field_input_extkey\">";
|
||||
|
||||
if (is_null($oAllowedValues))
|
||||
{
|
||||
throw new Exception('Implementation: null value for allowed values definition');
|
||||
}
|
||||
$oAllowedValues->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
|
||||
// We just need to compare the number of entries with MaxComboLength, so no need to get the real count.
|
||||
if (!$oAllowedValues->CountExceeds($iMaxComboLength))
|
||||
{
|
||||
// Discrete list of values, use a SELECT or RADIO buttons depending on the config
|
||||
$sValidationField = null;
|
||||
|
||||
$bVertical = ($sDisplayStyle != 'radio_horizontal');
|
||||
$bExtensions = false;
|
||||
$oAllowedValues->Rewind();
|
||||
$aAllowedValues = array();
|
||||
while($oObj = $oAllowedValues->Fetch())
|
||||
{
|
||||
$aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
|
||||
}
|
||||
$sHTMLValue .= $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", false /* $bMandatory will be placed manually */, $bVertical, $sValidationField);
|
||||
$aEventsList[] ='change';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sHTMLValue .= "unable to display. Too much values";
|
||||
}
|
||||
if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false)
|
||||
{
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_tree_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"><i class=\"fas fa-sitemap\"></i></div></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ac_tree_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ac_tree_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
if ($bCreate && $bExtensions)
|
||||
{
|
||||
$sCallbackName = (MetaModel::IsAbstract($this->sTargetClass)) ? 'SelectObjectClass' : 'CreateObject';
|
||||
|
||||
$sHTMLValue .= "<span class=\"field_input_btn\"><div class=\"mini_button\" id=\"mini_add_{$this->iId}\" onClick=\"oACWidget_{$this->iId}.{$sCallbackName}();\"><i class=\"fas fa-plus\"></i></div></span>";
|
||||
$oPage->add_ready_script(
|
||||
<<<JS
|
||||
if ($('#ajax_{$this->iId}').length == 0)
|
||||
{
|
||||
$('body').append('<div id="ajax_{$this->iId}"></div>');
|
||||
}
|
||||
JS
|
||||
);
|
||||
}
|
||||
$sHTMLValue .= "</div>";
|
||||
|
||||
// Note: This test is no longer necessary as we changed the markup to extract validation decoration in the standard .field_input_xxx container
|
||||
//if (($sDisplayStyle == 'select') || ($sDisplayStyle == 'list'))
|
||||
//{
|
||||
$sHTMLValue .= "<span class=\"form_validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
//}
|
||||
|
||||
return $sHTMLValue;
|
||||
}
|
||||
/**
|
||||
* @deprecated Use DisplayBob
|
||||
* Get the HTML fragment corresponding to the ext key editing widget
|
||||
* @param WebPage $oP The web page used for all the output
|
||||
* @param array $aArgs Extra context arguments
|
||||
@@ -319,12 +625,7 @@ JS
|
||||
);
|
||||
}
|
||||
$sHTMLValue .= "</div>";
|
||||
|
||||
// Note: This test is no longer necessary as we changed the markup to extract validation decoration in the standard .field_input_xxx container
|
||||
//if (($sDisplayStyle == 'select') || ($sDisplayStyle == 'list'))
|
||||
//{
|
||||
$sHTMLValue .= "<span class=\"form_validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
//}
|
||||
$sHTMLValue .= "<span class=\"form_validation\" id=\"v_{$this->iId}\"></span><span class=\"field_status\" id=\"fstatus_{$this->iId}\"></span>";
|
||||
|
||||
return $sHTMLValue;
|
||||
}
|
||||
@@ -433,19 +734,18 @@ EOF
|
||||
|
||||
// Current extkey value, so we can display event if it is not available anymore (eg. archived).
|
||||
$iCurrentExtKeyId = (is_null($oObj) || $this->sAttCode === '') ? 0 : $oObj->Get($this->sAttCode);
|
||||
|
||||
$oValuesSet = new ValueSetObjects($sFilter, 'friendlyname'); // Bypass GetName() to avoid the encoding by htmlentities
|
||||
$iMax = 150;
|
||||
$oValuesSet->SetLimit($iMax);
|
||||
$oValuesSet->SetSort(false);
|
||||
$oValuesSet->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode);
|
||||
$oValuesSet->SetLimit($iMax);
|
||||
$aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'start_with');
|
||||
asort($aValuesContains);
|
||||
$aValues = $aValuesContains;
|
||||
if (sizeof($aValues) < $iMax)
|
||||
{
|
||||
$aValuesContains = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
||||
$aValuesContains = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'contains');
|
||||
asort($aValuesContains);
|
||||
$iSize = sizeof($aValuesContains);
|
||||
foreach ($aValuesContains as $sKey => $sFriendlyName)
|
||||
@@ -462,7 +762,7 @@ EOF
|
||||
}
|
||||
elseif (!in_array($sContains, $aValues))
|
||||
{
|
||||
$aValuesEquals = $oValuesSet->GetValues(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'equals');
|
||||
$aValuesEquals = $oValuesSet->GetValuesForAutocomplete(array('this' => $oObj, 'current_extkey_id' => $iCurrentExtKeyId), $sContains, 'equals');
|
||||
$aValues = array_merge($aValuesEquals, $aValues);
|
||||
}
|
||||
|
||||
@@ -471,9 +771,16 @@ EOF
|
||||
case static::ENUM_OUTPUT_FORMAT_JSON:
|
||||
|
||||
$aJsonMap = array();
|
||||
foreach ($aValues as $sKey => $sLabel)
|
||||
foreach ($aValues as $sKey => $aValue)
|
||||
{
|
||||
$aJsonMap[] = array('value' => $sKey, 'label' => $sLabel);
|
||||
if ($aValue['additional_field'] != '')
|
||||
{
|
||||
$aJsonMap[] = array('value' => $sKey, 'label' => $aValue['label'], 'obsolescence_flag' => $aValue['obsolescence_flag'], 'additional_field' => $aValue['additional_field']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aJsonMap[] = array('value' => $sKey, 'label' => $aValue['label'], 'obsolescence_flag' => $aValue['obsolescence_flag']);
|
||||
}
|
||||
}
|
||||
|
||||
$oP->SetContentType('application/json');
|
||||
@@ -481,9 +788,9 @@ EOF
|
||||
break;
|
||||
|
||||
case static::ENUM_OUTPUT_FORMAT_CSV:
|
||||
foreach($aValues as $sKey => $sFriendlyName)
|
||||
foreach($aValues as $sKey => $aValue)
|
||||
{
|
||||
$oP->add(trim($sFriendlyName)."\t".$sKey."\n");
|
||||
$oP->add(trim($aValue['label'])."\t".$sKey."\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -39,6 +39,7 @@ class UILinksWidget
|
||||
protected $m_sLinkedClass;
|
||||
protected $m_sRemoteClass;
|
||||
protected $m_bDuplicatesAllowed;
|
||||
/** @var string[] list of editables attcodes */
|
||||
protected $m_aEditableFields;
|
||||
protected $m_aTableConfig;
|
||||
|
||||
@@ -46,7 +47,7 @@ class UILinksWidget
|
||||
* UILinksWidget constructor.
|
||||
*
|
||||
* @param string $sClass
|
||||
* @param string $sAttCode
|
||||
* @param string $sAttCode AttributeLinkedSetIndirect attcode
|
||||
* @param int $iInputId
|
||||
* @param string $sNameSuffix
|
||||
* @param bool $bDuplicatesAllowed
|
||||
@@ -73,41 +74,36 @@ class UILinksWidget
|
||||
/** @var AttributeExternalKey $oLinkingAttDef */
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $this->m_sExtKeyToRemote);
|
||||
$this->m_sRemoteClass = $oLinkingAttDef->GetTargetClass();
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($this->m_sClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($this->m_sClass);
|
||||
|
||||
$this->m_aEditableFields = array();
|
||||
$this->m_aTableConfig = array();
|
||||
$this->m_aTableConfig['form::checkbox'] = array( 'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_iInputId.".OnSelectChange();\">", 'description' => Dict::S('UI:SelectAllToggle+'));
|
||||
$this->m_aTableConfig['form::checkbox'] = array(
|
||||
'label' => "<input class=\"select_all\" type=\"checkbox\" value=\"1\" onClick=\"CheckAll('#linkedset_{$this->m_sAttCode}{$this->m_sNameSuffix} .selection', this.checked); oWidget".$this->m_iInputId.".OnSelectChange();\">",
|
||||
'description' => Dict::S('UI:SelectAllToggle+'),
|
||||
);
|
||||
|
||||
foreach(MetaModel::FlattenZList(MetaModel::GetZListItems($this->m_sLinkedClass, 'list')) as $sAttCode)
|
||||
$aLnkAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode);
|
||||
foreach ($aLnkAttDefsToDisplay as $oLnkAttDef)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sAttCode);
|
||||
if ($sStateAttCode == $sAttCode)
|
||||
{
|
||||
// State attribute is always hidden from the UI
|
||||
}
|
||||
else if ($oAttDef->IsWritable() && ($sAttCode != $sExtKeyToMe) && ($sAttCode != $this->m_sExtKeyToRemote) && ($sAttCode != 'finalclass'))
|
||||
{
|
||||
$iFlags = MetaModel::GetAttributeFlags($this->m_sLinkedClass, $sDefaultState, $sAttCode);
|
||||
if ( !($iFlags & OPT_ATT_HIDDEN) && !($iFlags & OPT_ATT_READONLY) )
|
||||
{
|
||||
$this->m_aEditableFields[] = $sAttCode;
|
||||
$this->m_aTableConfig[$sAttCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
}
|
||||
$sLnkAttCode = $oLnkAttDef->GetCode();
|
||||
$this->m_aEditableFields[] = $sLnkAttCode;
|
||||
$this->m_aTableConfig[$sLnkAttCode] = array('label' => $oLnkAttDef->GetLabel(), 'description' => $oLnkAttDef->GetDescription());
|
||||
}
|
||||
|
||||
$this->m_aTableConfig['static::key'] = array( 'label' => MetaModel::GetName($this->m_sRemoteClass), 'description' => MetaModel::GetClassDescription($this->m_sRemoteClass));
|
||||
foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
||||
|
||||
$this->m_aTableConfig['static::key'] = array(
|
||||
'label' => MetaModel::GetName($this->m_sRemoteClass),
|
||||
'description' => MetaModel::GetClassDescription($this->m_sRemoteClass),
|
||||
);
|
||||
$this->m_aEditableFields[] = $this->m_sExtKeyToRemote;
|
||||
|
||||
$aRemoteAttDefsToDisplay = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||
foreach ($aRemoteAttDefsToDisplay as $oRemoteAttDef)
|
||||
{
|
||||
// TO DO: check the state of the attribute: hidden or visible ?
|
||||
if ($sFieldCode != 'finalclass')
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sRemoteClass, $sFieldCode);
|
||||
$this->m_aTableConfig['static::'.$sFieldCode] = array( 'label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
|
||||
}
|
||||
$sRemoteAttCode = $oRemoteAttDef->GetCode();
|
||||
$this->m_aTableConfig['static::'.$sRemoteAttCode] = array(
|
||||
'label' => $oRemoteAttDef->GetLabel(),
|
||||
'description' => $oRemoteAttDef->GetDescription(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +112,7 @@ class UILinksWidget
|
||||
*
|
||||
* @param WebPage $oP Web page used for the ouput
|
||||
* @param DBObject $oLinkedObj Remote object
|
||||
* @param mixed $linkObjOrId Either the object linked or a unique number for new link records to add
|
||||
* @param DBObject|int $linkObjOrId Either the lnk object or a unique number for new link records to add
|
||||
* @param array $aArgs Extra context arguments
|
||||
* @param DBObject $oCurrentObj The object to which all the elements of the linked set refer to
|
||||
* @param int $iUniqueId A unique identifier of new links
|
||||
@@ -134,43 +130,39 @@ class UILinksWidget
|
||||
$aRow = array();
|
||||
$aFieldsMap = array();
|
||||
$iKey = 0;
|
||||
if(is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
||||
|
||||
if (is_object($linkObjOrId) && (!$linkObjOrId->IsNew()))
|
||||
{
|
||||
$iKey = $linkObjOrId->GetKey();
|
||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||
$iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote);
|
||||
$sPrefix .= "[$iKey][";
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}";
|
||||
$aArgs['this'] = $linkObjOrId;
|
||||
|
||||
if($bReadOnly)
|
||||
{
|
||||
$aRow['form::checkbox'] = "";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
||||
$aRow[$sFieldCode] = $sDisplayValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']';
|
||||
$sSafeId = utils::GetSafeId($sFieldId);
|
||||
$sValue = $linkObjOrId->Get($sFieldCode);
|
||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'.
|
||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId, $sNameSuffix, 0, $aArgs).
|
||||
'</div></div></div>';
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
}
|
||||
}
|
||||
if ($bReadOnly)
|
||||
{
|
||||
$aRow['form::checkbox'] = "";
|
||||
foreach ($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sDisplayValue = $linkObjOrId->GetEditValue($sFieldCode);
|
||||
$aRow[$sFieldCode] = $sDisplayValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$iKey\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$iKey\">";
|
||||
foreach ($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sSafeFieldId = $this->GetFieldId($linkObjOrId->GetKey(), $sFieldCode);
|
||||
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $linkObjOrId, $oP, $sNameSuffix, $sSafeFieldId);
|
||||
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||
}
|
||||
}
|
||||
|
||||
$sState = $linkObjOrId->GetState();
|
||||
$sRemoteKeySafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $this->m_sExtKeyToRemote);;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -180,15 +172,18 @@ class UILinksWidget
|
||||
// New link existing only in memory
|
||||
$oNewLinkObj = $linkObjOrId;
|
||||
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe,
|
||||
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
}
|
||||
else
|
||||
{
|
||||
$iRemoteObjKey = $linkObjOrId;
|
||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote,
|
||||
$oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe,
|
||||
$oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
}
|
||||
$sPrefix .= "[-$iUniqueId][";
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
@@ -222,58 +217,133 @@ EOF
|
||||
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.-$iUniqueId.']';
|
||||
$sSafeId = utils::GetSafeId($sFieldId);
|
||||
$sSafeFieldId = $this->GetFieldId($iUniqueId, $sFieldCode);
|
||||
$this->AddRowForFieldCode($aRow, $sFieldCode, $aArgs, $oNewLinkObj, $oP, $sNameSuffix, $sSafeFieldId);
|
||||
$aFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||
|
||||
$sValue = $oNewLinkObj->Get($sFieldCode);
|
||||
$sDisplayValue = $oNewLinkObj->GetEditValue($sFieldCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
$aRow[$sFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'.
|
||||
cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId /* id */, $sNameSuffix, 0, $aArgs).
|
||||
'</div></div></div>';
|
||||
$aFieldsMap[$sFieldCode] = $sSafeId;
|
||||
$oP->add_ready_script(<<<EOF
|
||||
$oP->add_ready_script(
|
||||
<<<JS
|
||||
oWidget{$this->m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue');
|
||||
EOF
|
||||
);
|
||||
JS
|
||||
);
|
||||
}
|
||||
|
||||
$sState = '';
|
||||
$sRemoteKeySafeFieldId = $this->GetFieldId($iUniqueId, $this->m_sExtKeyToRemote);
|
||||
}
|
||||
|
||||
if(!$bReadOnly)
|
||||
{
|
||||
$sExtKeyToMeId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToMe);
|
||||
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
|
||||
if (!$bReadOnly)
|
||||
{
|
||||
$sExtKeyToMeId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToMe);
|
||||
$aFieldsMap[$this->m_sExtKeyToMe] = $sExtKeyToMeId;
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToMeId\" value=\"".$oCurrentObj->GetKey()."\">";
|
||||
|
||||
$sExtKeyToRemoteId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToRemote);
|
||||
$aFieldsMap[$this->m_sExtKeyToRemote] = $sExtKeyToRemoteId;
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToRemoteId\" value=\"$iRemoteObjKey\">";
|
||||
}
|
||||
$sExtKeyToRemoteId = utils::GetSafeId($sPrefix.$this->m_sExtKeyToRemote);
|
||||
$aFieldsMap[$this->m_sExtKeyToRemote] = $sExtKeyToRemoteId;
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" id=\"$sExtKeyToRemoteId\" value=\"$iRemoteObjKey\">";
|
||||
}
|
||||
|
||||
// Adding fields from remote class
|
||||
// all fields are embedded in a span + added to $aFieldsMap array so that we can refresh them after extkey change
|
||||
$aRemoteFieldsMap = [];
|
||||
foreach (MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
||||
{
|
||||
$sSafeFieldId = $this->GetFieldId($aArgs['this']->GetKey(), $sFieldCode);
|
||||
$aRow['static::'.$sFieldCode] = "<span id='field_$sSafeFieldId'>".$oLinkedObj->GetAsHTML($sFieldCode).'</span>';
|
||||
$aRemoteFieldsMap[$sFieldCode] = $sSafeFieldId;
|
||||
}
|
||||
// id field is needed so that remote object could be load server side
|
||||
$aRemoteFieldsMap['id'] = $sRemoteKeySafeFieldId;
|
||||
|
||||
// Generate WizardHelper to update dependant fields
|
||||
$this->AddWizardHelperInit($oP, $aArgs['wizHelper'], $this->m_sLinkedClass, $sState, $aFieldsMap);
|
||||
//instantiate specific WizarHelper instance for remote class fields refresh
|
||||
$bHasExtKeyUpdatingRemoteClassFields = (
|
||||
array_key_exists('replaceDependenciesByRemoteClassFields', $aArgs)
|
||||
&& ($aArgs['replaceDependenciesByRemoteClassFields'])
|
||||
);
|
||||
if ($bHasExtKeyUpdatingRemoteClassFields)
|
||||
{
|
||||
$this->AddWizardHelperInit($oP, $aArgs['wizHelperRemote'], $this->m_sRemoteClass, $sState, $aRemoteFieldsMap);
|
||||
}
|
||||
|
||||
return $aRow;
|
||||
}
|
||||
|
||||
private function AddRowForFieldCode(&$aRow, $sFieldCode, &$aArgs, $oLnk, $oP, $sNameSuffix, $sSafeFieldId): void
|
||||
{
|
||||
if (($sFieldCode === $this->m_sExtKeyToRemote))
|
||||
{
|
||||
// current field is the lnk extkey to the remote class
|
||||
$aArgs['replaceDependenciesByRemoteClassFields'] = true;
|
||||
$sRowFieldCode = 'static::key';
|
||||
$aArgs['wizHelperRemote'] = $aArgs['wizHelper'].'_remote';
|
||||
$aRemoteAttDefs = MetaModel::GetZListAttDefsFilteredForIndirectRemoteClass($this->m_sRemoteClass);
|
||||
$aRemoteCodes = array_map(
|
||||
function ($value) {
|
||||
return $value->GetCode();
|
||||
},
|
||||
$aRemoteAttDefs
|
||||
);
|
||||
$aArgs['remoteCodes'] = $aRemoteCodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aArgs['replaceDependenciesByRemoteClassFields'] = false;
|
||||
$sRowFieldCode = $sFieldCode;
|
||||
}
|
||||
$sValue = $oLnk->Get($sFieldCode);
|
||||
$sDisplayValue = $oLnk->GetEditValue($sFieldCode);
|
||||
$oAttDef = MetaModel::GetAttributeDef($this->m_sLinkedClass, $sFieldCode);
|
||||
|
||||
$aRow[$sRowFieldCode] = '<div class="field_container" style="border:none;"><div class="field_data"><div class="field_value">'
|
||||
.cmdbAbstractObject::GetFormElementForField(
|
||||
$oP,
|
||||
$this->m_sLinkedClass,
|
||||
$sFieldCode,
|
||||
$oAttDef,
|
||||
$sValue,
|
||||
$sDisplayValue,
|
||||
$sSafeFieldId,
|
||||
$sNameSuffix,
|
||||
0,
|
||||
$aArgs
|
||||
)
|
||||
.'</div></div></div>';
|
||||
}
|
||||
|
||||
private function GetFieldId($iLnkId, $sFieldCode, $bSafe = true)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$iLnkId.']';
|
||||
|
||||
return ($bSafe) ? utils::GetSafeId($sFieldId) : $sFieldId;
|
||||
}
|
||||
|
||||
private function AddWizardHelperInit($oP, $sWizardHelperVarName, $sWizardHelperClass, $sState, $aFieldsMap): void
|
||||
{
|
||||
$iFieldsCount = count($aFieldsMap);
|
||||
$sJsonFieldsMap = json_encode($aFieldsMap);
|
||||
|
||||
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
var {$aArgs['wizHelper']} = new WizardHelper('{$this->m_sLinkedClass}', '', '$sState');
|
||||
{$aArgs['wizHelper']}.SetFieldsMap($sJsonFieldsMap);
|
||||
{$aArgs['wizHelper']}.SetFieldsCount($iFieldsCount);
|
||||
EOF
|
||||
<<<JS
|
||||
var $sWizardHelperVarName = new WizardHelper('$sWizardHelperClass', '', '$sState');
|
||||
$sWizardHelperVarName.SetFieldsMap($sJsonFieldsMap);
|
||||
$sWizardHelperVarName.SetFieldsCount($iFieldsCount);
|
||||
$sWizardHelperVarName.SetReturnNotEditableFields(true);
|
||||
$sWizardHelperVarName.SetWizHelperJsVarName('$sWizardHelperVarName');
|
||||
JS
|
||||
);
|
||||
$aRow['static::key'] = $oLinkedObj->GetHyperLink();
|
||||
foreach(MetaModel::GetZListItems($this->m_sRemoteClass, 'list') as $sFieldCode)
|
||||
{
|
||||
$aRow['static::'.$sFieldCode] = $oLinkedObj->GetAsHTML($sFieldCode);
|
||||
}
|
||||
return $aRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display one row of the whole form
|
||||
*
|
||||
* @param WebPage $oP
|
||||
* @param array $aConfig
|
||||
* @param array $aRow
|
||||
* @param int $iRowId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function DisplayFormRow(WebPage $oP, $aConfig, $aRow, $iRowId)
|
||||
@@ -309,7 +379,7 @@ EOF
|
||||
}
|
||||
$sHtml .= "</tr>\n";
|
||||
$sHtml .= "</thead>\n";
|
||||
|
||||
|
||||
// Content
|
||||
$sHtml .= "</tbody>\n";
|
||||
$sEmptyRowStyle = '';
|
||||
@@ -318,16 +388,16 @@ EOF
|
||||
$sEmptyRowStyle = 'style="display:none;"';
|
||||
}
|
||||
|
||||
foreach($aData as $iRowId => $aRow)
|
||||
foreach ($aData as $iRowId => $aRow)
|
||||
{
|
||||
$sHtml .= $this->DisplayFormRow($oP, $aConfig, $aRow, $iRowId);
|
||||
}
|
||||
}
|
||||
$sHtml .= "<tr $sEmptyRowStyle id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_empty_row\"><td colspan=\"".count($aConfig)."\" style=\"text-align:center;\">".Dict::S('UI:Message:EmptyList:UseAdd')."</td></tr>";
|
||||
$sHtml .= "</tbody>\n";
|
||||
|
||||
|
||||
// Footer
|
||||
$sHtml .= "</table>\n";
|
||||
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
@@ -360,20 +430,21 @@ EOF
|
||||
$bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass);
|
||||
$sJSDoSearch = $bDoSearch ? 'true' : 'false';
|
||||
$sWizHelper = 'oWizardHelper'.$sFormPrefix;
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}', $sJSDoSearch);
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
EOF
|
||||
$oPage->add_ready_script(<<<JS
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}', $sJSDoSearch);
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
JS
|
||||
);
|
||||
|
||||
while($oCurrentLink = $oValue->Fetch())
|
||||
while ($oCurrentLink = $oValue->Fetch())
|
||||
{
|
||||
// We try to retrieve the remote object as usual
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote), false /* Must not be found */);
|
||||
// We try to retrieve the remote object as usual
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote),
|
||||
false /* Must not be found */);
|
||||
// If successful, it means that we can edit its link
|
||||
if($oLinkedObj !== null)
|
||||
{
|
||||
$bReadOnly = false;
|
||||
if ($oLinkedObj !== null)
|
||||
{
|
||||
$bReadOnly = false;
|
||||
}
|
||||
// Else we retrieve it without restrictions (silos) and will display its link as readonly
|
||||
else
|
||||
|
||||
@@ -309,6 +309,7 @@ class utils
|
||||
case 'context_param':
|
||||
case 'parameter':
|
||||
case 'field_name':
|
||||
case 'transaction_id':
|
||||
if (is_array($value))
|
||||
{
|
||||
$retValue = array();
|
||||
@@ -768,19 +769,22 @@ class utils
|
||||
return new Config();
|
||||
}
|
||||
|
||||
public static function InitTimeZone() {
|
||||
$oConfig = self::GetConfig();
|
||||
public static function InitTimeZone($oConfig = null)
|
||||
{
|
||||
if (is_null($oConfig))
|
||||
{
|
||||
$oConfig = self::GetConfig();
|
||||
}
|
||||
$sItopTimeZone = $oConfig->Get('timezone');
|
||||
|
||||
if (!empty($sItopTimeZone))
|
||||
{
|
||||
date_default_timezone_set($sItopTimeZone);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave as is... up to the admin to set a value somewhere...
|
||||
// see http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// // Leave as is... up to the admin to set a value somewhere...
|
||||
// // see http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1389,13 +1393,12 @@ class utils
|
||||
// For instance fopen does not allow to work around the bug: http://stackoverflow.com/questions/18191672/php-curl-ssl-routinesssl23-get-server-helloreason1112
|
||||
// by setting the SSLVERSION to 3 as done below.
|
||||
$aHeaders = explode("\n", $sOptionnalHeaders);
|
||||
// N°3267 - Webservices: Fix optional headers not being taken into account
|
||||
// See https://www.php.net/curl_setopt CURLOPT_HTTPHEADER
|
||||
$aHTTPHeaders = array();
|
||||
foreach($aHeaders as $sHeaderString)
|
||||
{
|
||||
if(preg_match('/^([^:]): (.+)$/', $sHeaderString, $aMatches))
|
||||
{
|
||||
$aHTTPHeaders[$aMatches[1]] = $aMatches[2];
|
||||
}
|
||||
$aHTTPHeaders[] = trim($sHeaderString);
|
||||
}
|
||||
// Default options, can be overloaded/extended with the 4th parameter of this method, see above $aCurlOptions
|
||||
$aOptions = array(
|
||||
@@ -2090,6 +2093,41 @@ class utils
|
||||
return COMPILATION_TIMESTAMP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg : '2_7_0' ITOP_VERSION is '2.7.1-dev'
|
||||
*/
|
||||
public static function GetItopVersionWikiSyntax()
|
||||
{
|
||||
$sMinorVersion = self::GetItopMinorVersion();
|
||||
return str_replace('.', '_', $sMinorVersion).'_0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg 2.7 if ITOP_VERSION is '2.7.0-dev'
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function GetItopMinorVersion()
|
||||
{
|
||||
$sPatchVersion = self::GetItopPatchVersion();
|
||||
$aExplodedVersion = explode('.', $sPatchVersion);
|
||||
|
||||
if (empty($aExplodedVersion[0]) || empty($aExplodedVersion[1]))
|
||||
{
|
||||
throw new Exception('iTop version is wrongfully configured!');
|
||||
}
|
||||
|
||||
return sprintf('%d.%d', $aExplodedVersion[0], $aExplodedVersion[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg '2.7.0' if ITOP_VERSION is '2.7.0-dev'
|
||||
*/
|
||||
public static function GetItopPatchVersion()
|
||||
{
|
||||
$aExplodedVersion = explode('-', ITOP_VERSION);
|
||||
return $aExplodedVersion[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given class if configured as a high cardinality class.
|
||||
*
|
||||
@@ -2190,7 +2228,7 @@ class utils
|
||||
* @param string $sPath for example '/var/www/html/itop/data/backups/manual/itop_27-2019-10-03_15_35.tar.gz'
|
||||
* @param string $sBasePath for example '/var/www/html/itop/data/'
|
||||
*
|
||||
* @return bool false if path :
|
||||
* @return bool|string false if path :
|
||||
* * invalid
|
||||
* * not allowed
|
||||
* * not contained in base path
|
||||
|
||||
@@ -335,20 +335,41 @@ class WizardHelper
|
||||
{
|
||||
$sResult = $this->m_aData['m_oFieldsMap'][$sFieldName];
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
|
||||
|
||||
public function GetReturnNotEditableFields()
|
||||
{
|
||||
return $this->m_aData['m_bReturnNotEditableFields'] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string JS code to be executed for fields update
|
||||
* @since 2.8.0 N°3198
|
||||
*/
|
||||
public function GetJsForUpdateFields()
|
||||
{
|
||||
$sWizardHelperJsVar = ($this->m_aData['m_sWizHelperJsVarName']) ?? 'oWizardHelper'.$this->GetFormPrefix();
|
||||
$sWizardHelperJson = $this->ToJSON();
|
||||
|
||||
return <<<JS
|
||||
{$sWizardHelperJsVar}.m_oData = {$sWizardHelperJson};
|
||||
{$sWizardHelperJsVar}.UpdateFields();
|
||||
JS;
|
||||
}
|
||||
|
||||
static function ParseJsonSet($oMe, $sLinkClass, $sExtKeyToMe, $sJsonSet)
|
||||
{
|
||||
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
|
||||
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
|
||||
foreach($aSet as $aLinkObj)
|
||||
foreach ($aSet as $aLinkObj)
|
||||
{
|
||||
$oLink = MetaModel::NewObject($sLinkClass);
|
||||
foreach($aLinkObj as $sAttCode => $value)
|
||||
foreach ($aLinkObj as $sAttCode => $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
|
||||
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0))
|
||||
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0))
|
||||
{
|
||||
// For external keys: load the target object so that external fields
|
||||
// get filled too
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"type": "project",
|
||||
"license": "AGPLv3",
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"php": ">=7.1.3",
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-gd": "*",
|
||||
@@ -51,7 +51,8 @@
|
||||
"core",
|
||||
"application",
|
||||
"sources/application",
|
||||
"sources/Composer"
|
||||
"sources/Composer",
|
||||
"sources/Controller"
|
||||
],
|
||||
"exclude-from-classmap": [
|
||||
"core/dbobjectsearch.class.php",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Form\Field\LabelField;
|
||||
use Combodo\iTop\Form\Field\TextAreaField;
|
||||
use Combodo\iTop\Form\Validator\NotEmptyExtKeyValidator;
|
||||
use Combodo\iTop\Form\Validator\Validator;
|
||||
|
||||
@@ -7466,6 +7467,12 @@ class AttributeExternalField extends AttributeDefinition
|
||||
}
|
||||
}
|
||||
parent::MakeFormField($oObject, $oFormField);
|
||||
if ($oFormField instanceof TextAreaField) {
|
||||
if (method_exists($oRemoteAttDef, 'GetFormat')) {
|
||||
/** @var \Combodo\iTop\Form\Field\TextAreaField $oFormField */
|
||||
$oFormField->SetFormat($oRemoteAttDef->GetFormat());
|
||||
}
|
||||
}
|
||||
|
||||
// Manually setting for remote ExternalKey, otherwise, the id would be displayed.
|
||||
if ($oRemoteAttDef instanceof AttributeExternalKey)
|
||||
@@ -7483,6 +7490,16 @@ class AttributeExternalField extends AttributeDefinition
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetFormat()
|
||||
{
|
||||
$oRemoteAttDef = $this->GetExtAttDef();
|
||||
if (method_exists($oRemoteAttDef, 'GetFormat')) {
|
||||
/** @var \Combodo\iTop\Form\Field\TextAreaField $oFormField */
|
||||
return $oRemoteAttDef->GetFormat();
|
||||
}
|
||||
return 'text';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -185,12 +185,9 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
||||
static::DEFAULT_MODULE_SETTING_ENABLED
|
||||
);
|
||||
|
||||
$sItopTimeZone = $this->getOConfig()->Get('timezone');
|
||||
$timezone = new DateTimeZone($sItopTimeZone);
|
||||
|
||||
if (!$bEnabled)
|
||||
{
|
||||
return new DateTime('3000-01-01', $timezone);
|
||||
return new DateTime('3000-01-01');
|
||||
}
|
||||
|
||||
// 1st - Interpret the list of days as ordered numbers (monday = 1)
|
||||
@@ -209,7 +206,7 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
||||
throw new ProcessInvalidConfigException($this->GetModuleName().": wrong format for setting '".static::MODULE_SETTING_TIME."' (found '$sProcessTime')");
|
||||
}
|
||||
|
||||
$oNow = new DateTime($sCurrentTime, $timezone);
|
||||
$oNow = new DateTime($sCurrentTime);
|
||||
$iNextPos = false;
|
||||
$sDay = $oNow->format('N');
|
||||
for ($iDay = (int) $sDay; $iDay <= 7; $iDay++)
|
||||
@@ -244,7 +241,6 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
|
||||
$oRet->modify('+'.$iMove.' days');
|
||||
}
|
||||
list($sHours, $sMinutes) = explode(':', $sProcessTime);
|
||||
/** @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection non used new parameter in PHP 7.1 */
|
||||
$oRet->setTime((int)$sHours, (int)$sMinutes);
|
||||
|
||||
return $oRet;
|
||||
|
||||
@@ -26,6 +26,24 @@
|
||||
*/
|
||||
class BackgroundTask extends DBObject
|
||||
{
|
||||
protected $bDebug = false;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function IsDebug()
|
||||
{
|
||||
return $this->bDebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bDebug
|
||||
*/
|
||||
public function SetDebug($bDebug)
|
||||
{
|
||||
$this->bDebug = $bDebug;
|
||||
}
|
||||
|
||||
public static function Init()
|
||||
{
|
||||
$aParams = array
|
||||
@@ -54,7 +72,7 @@ class BackgroundTask extends DBObject
|
||||
MetaModel::Init_AddAttribute(new AttributeDecimal("average_run_duration", array("allowed_values"=>null, "sql"=>"average_run_duration", "digits"=> 8, "decimals"=> 3, "default_value"=>"0", "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeBoolean("running", array("allowed_values"=>null, "sql"=>"running", "default_value"=>false, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('active,paused'), "sql"=>"status", "default_value"=>'active', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('active,paused,removed'), "sql"=>"status", "default_value"=>'active', "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("system_user", array("allowed_values"=>null, "sql"=>"system_user", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
|
||||
}
|
||||
|
||||
|
||||
@@ -345,10 +345,10 @@ abstract class BulkExport
|
||||
$this->oBulkExportResult->Set('format', $this->sFormatCode);
|
||||
$this->oBulkExportResult->Set('search', $this->oSearch->serialize());
|
||||
$this->oBulkExportResult->Set('chunk_size', $this->iChunkSize);
|
||||
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
|
||||
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
|
||||
}
|
||||
$this->oBulkExportResult->Set('status_info', json_encode($this->GetStatusInfo()));
|
||||
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
|
||||
utils::PushArchiveMode(false);
|
||||
$ret = $this->oBulkExportResult->DBWrite();
|
||||
utils::PopArchiveMode();
|
||||
@@ -420,6 +420,11 @@ abstract class BulkExport
|
||||
public function GetStatistics()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function SetFields($sFields)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function GetDownloadFileName()
|
||||
|
||||
@@ -95,11 +95,17 @@ abstract class CMDBObject extends DBObject
|
||||
protected static $m_oCurrChange = null;
|
||||
protected static $m_sInfo = null; // null => the information is built in a standard way
|
||||
protected static $m_sOrigin = null; // null => the origin is 'interactive'
|
||||
|
||||
|
||||
/**
|
||||
* Specify another change (this is mainly for backward compatibility)
|
||||
* Specify the change to be used by the API to attach any CMDBChangeOp* object created
|
||||
*
|
||||
* @see SetTrackInfo if CurrentChange is null, then a new one will be create using trackinfo
|
||||
*
|
||||
* @param CMDBChange|null $oChange use null so that the API will recreate a new CMDBChange using TrackInfo & TrackOrigin
|
||||
*
|
||||
* @since 2.7.2 N°3219 can now reset CMDBChange by passing null
|
||||
*/
|
||||
public static function SetCurrentChange(CMDBChange $oChange)
|
||||
public static function SetCurrentChange($oChange)
|
||||
{
|
||||
self::$m_oCurrChange = $oChange;
|
||||
}
|
||||
@@ -126,11 +132,15 @@ abstract class CMDBObject extends DBObject
|
||||
/**
|
||||
* Override the additional information (defaulting to user name)
|
||||
* A call to this verb should replace every occurence of
|
||||
* $oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
* $oMyChange = MetaModel::NewObject("CMDBChange");
|
||||
* $oMyChange->Set("date", time());
|
||||
* $oMyChange->Set("userinfo", 'this is done by ... for ...');
|
||||
* $iChangeId = $oMyChange->DBInsert();
|
||||
*/
|
||||
*
|
||||
* @see SetCurrentChange to specify a CMDBObject instance instead
|
||||
*
|
||||
* @param string $sInfo
|
||||
*/
|
||||
public static function SetTrackInfo($sInfo)
|
||||
{
|
||||
self::$m_sInfo = $sInfo;
|
||||
@@ -138,8 +148,13 @@ abstract class CMDBObject extends DBObject
|
||||
|
||||
/**
|
||||
* Provides information about the origin of the change
|
||||
* @param $sOrigin String: one of: interactive, csv-interactive, csv-import.php, webservice-soap, webservice-rest, syncho-data-source, email-processing, custom-extension
|
||||
*/
|
||||
*
|
||||
* @see SetTrackInfo
|
||||
* @see SetCurrentChange to specify a CMDBObject instance instead
|
||||
*
|
||||
* @param $sOrigin String: one of: interactive, csv-interactive, csv-import.php, webservice-soap, webservice-rest, syncho-data-source,
|
||||
* email-processing, custom-extension
|
||||
*/
|
||||
public static function SetTrackOrigin($sOrigin)
|
||||
{
|
||||
self::$m_sOrigin = $sOrigin;
|
||||
@@ -488,7 +503,13 @@ abstract class CMDBObject extends DBObject
|
||||
/**
|
||||
* Helper to ultimately check user rights before writing (Insert, Update or Delete)
|
||||
* The check should never fail, because the UI should prevent from such a usage
|
||||
* Anyhow, if the user has found a workaround... the security gets enforced here
|
||||
* Anyhow, if the user has found a workaround... the security gets enforced here
|
||||
*
|
||||
* @param $bSkipStrongSecurity
|
||||
* @param $iActionCode
|
||||
*
|
||||
* @throws \SecurityException
|
||||
* @deprecated in 2.8.0 will be removed in 2.9
|
||||
*/
|
||||
protected function CheckUserRights($bSkipStrongSecurity, $iActionCode)
|
||||
{
|
||||
|
||||
@@ -547,72 +547,64 @@ abstract class DBObject implements iDisplay
|
||||
*/
|
||||
public function Set($sAttCode, $value)
|
||||
{
|
||||
if ($sAttCode == 'finalclass')
|
||||
{
|
||||
if ($sAttCode == 'finalclass') {
|
||||
// Ignore it - this attribute is set upon object creation and that's it
|
||||
return false;
|
||||
}
|
||||
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
|
||||
if (!$oAttDef->IsWritable())
|
||||
{
|
||||
if (!$oAttDef->IsWritable()) {
|
||||
$sClass = get_class($this);
|
||||
throw new Exception("Attempting to set the value on the read-only attribute $sClass::$sAttCode");
|
||||
}
|
||||
|
||||
if ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty)
|
||||
{
|
||||
if ($this->m_bIsInDB && !$this->m_bFullyLoaded && !$this->m_bDirty) {
|
||||
// First time Set is called... ensure that the object gets fully loaded
|
||||
// Otherwise we would lose the values on a further Reload
|
||||
// + consistency does not make sense !
|
||||
$this->Reload();
|
||||
}
|
||||
|
||||
if ($oAttDef->IsExternalKey() && is_object($value))
|
||||
{
|
||||
if ($oAttDef->IsExternalKey() && is_object($value)) {
|
||||
// Setting an external key with a whole object (instead of just an ID)
|
||||
// let's initialize also the external fields that depend on it
|
||||
// (useful when building objects in memory and not from a query)
|
||||
/** @var \AttributeExternalKey $oAttDef */
|
||||
if ((get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass())))
|
||||
{
|
||||
if ((get_class($value) != $oAttDef->GetTargetClass()) && (!is_subclass_of($value, $oAttDef->GetTargetClass()))) {
|
||||
throw new CoreUnexpectedValue("Trying to set the value of '$sAttCode', to an object of class '".get_class($value)."', whereas it's an ExtKey to '".$oAttDef->GetTargetClass()."'. Ignored");
|
||||
}
|
||||
|
||||
foreach (MetaModel::ListAttributeDefs(get_class($this)) as $sCode => $oDef)
|
||||
{
|
||||
foreach (MetaModel::GetDependentAttributes(get_class($this), $sAttCode) as $sCode) {
|
||||
$oDef = MetaModel::GetAttributeDef(get_class($this), $sCode);
|
||||
/** @var \AttributeExternalField $oDef */
|
||||
if ($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode))
|
||||
{
|
||||
if ($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode)) {
|
||||
/** @var \DBObject $value */
|
||||
$this->m_aCurrValues[$sCode] = $value->Get($oDef->GetExtAttCode());
|
||||
$this->m_aLoadedAtt[$sCode] = true;
|
||||
}
|
||||
elseif (in_array($sAttCode, $oDef->GetPrerequisiteAttributes(get_class($this))))
|
||||
{
|
||||
elseif ($oDef->IsBasedOnOQLExpression()) {
|
||||
$this->m_aCurrValues[$sCode] = $this->GetDefaultValue($sCode);
|
||||
unset($this->m_aLoadedAtt[$sCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($this->m_aCurrValues[$sAttCode] !== $value)
|
||||
{
|
||||
// Invalidate dependent fields so that they get reloaded in case they are needed (See Get())
|
||||
//
|
||||
foreach (MetaModel::GetDependentAttributes(get_class($this), $sAttCode) as $sCode)
|
||||
{
|
||||
$this->m_aCurrValues[$sCode] = $this->GetDefaultValue($sCode);
|
||||
unset($this->m_aLoadedAtt[$sCode]);
|
||||
} else {
|
||||
if ($this->m_aCurrValues[$sAttCode] !== $value) {
|
||||
// Invalidate dependent fields so that they get reloaded in case they are needed (See Get())
|
||||
//
|
||||
foreach (MetaModel::GetDependentAttributes(get_class($this), $sAttCode) as $sCode) {
|
||||
$oDef = MetaModel::GetAttributeDef(get_class($this), $sCode);
|
||||
if (($oDef->IsExternalField() && ($oDef->GetKeyAttCode() == $sAttCode)) || $oDef->IsBasedOnOQLExpression()) {
|
||||
$this->m_aCurrValues[$sCode] = $this->GetDefaultValue($sCode);
|
||||
unset($this->m_aLoadedAtt[$sCode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($oAttDef->IsLinkSet() && ($value != null))
|
||||
{
|
||||
if ($oAttDef->IsLinkSet() && ($value != null)) {
|
||||
$realvalue = clone $this->m_aCurrValues[$sAttCode];
|
||||
$realvalue->UpdateFromCompleteList($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$realvalue = $oAttDef->MakeRealValue($value, $this);
|
||||
}
|
||||
$this->_Set($sAttCode, $realvalue);
|
||||
|
||||
@@ -443,7 +443,6 @@ class DBObjectSearch extends DBSearch
|
||||
case '<|':
|
||||
case '=|':
|
||||
throw new CoreException('Deprecated operator, please consider using OQL (SQL) expressions like "(TO_DAYS(NOW()) - TO_DAYS(x)) AS AgeDays"', array('operator' => $sOpCode));
|
||||
break;
|
||||
|
||||
case 'IN':
|
||||
if (!is_array($value)) $value = array($value);
|
||||
@@ -625,17 +624,32 @@ class DBObjectSearch extends DBSearch
|
||||
public function AddCondition_FullText($sNeedle)
|
||||
{
|
||||
// Transform the full text condition into additional condition expression
|
||||
$aFullTextFields = array();
|
||||
foreach (MetaModel::ListAttributeDefs($this->GetClass()) as $sAttCode => $oAttDef)
|
||||
{
|
||||
$aAttCodes = [];
|
||||
foreach (MetaModel::ListAttributeDefs($this->GetClass()) as $sAttCode => $oAttDef) {
|
||||
if (!$oAttDef->IsScalar()) continue;
|
||||
if ($oAttDef->IsExternalKey()) continue;
|
||||
if (!$oAttDef->IsSearchable()) continue;
|
||||
$aAttCodes[] = $sAttCode;
|
||||
}
|
||||
$this->AddCondition_FullTextOnAttributes($aAttCodes, $sNeedle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aAttCodes array of attCodes to search into
|
||||
* @param string $sNeedle one word to be searched
|
||||
*
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle)
|
||||
{
|
||||
$aFullTextFields = [];
|
||||
foreach ($aAttCodes as $sAttCode) {
|
||||
$aFullTextFields[] = new FieldExpression($sAttCode, $this->GetClassAlias());
|
||||
}
|
||||
|
||||
$oTextFields = new CharConcatWSExpression(' ', $aFullTextFields);
|
||||
|
||||
$sQueryParam = 'needle';
|
||||
$sQueryParam = str_replace('.', '', uniqid('needle_', true));
|
||||
$oFlexNeedle = new CharConcatExpression(array(new ScalarExpression('%'), new VariableExpression($sQueryParam), new ScalarExpression('%')));
|
||||
|
||||
$oNewCond = new BinaryExpression($oTextFields, 'LIKE', $oFlexNeedle);
|
||||
@@ -792,10 +806,11 @@ class DBObjectSearch extends DBSearch
|
||||
* Helper to
|
||||
* - convert a translation table (format optimized for the translation in an expression tree) into simple hash
|
||||
* - compile over an eventually existing map
|
||||
* - accept multiple translations for the same alias for unions
|
||||
*
|
||||
* @param array $aRealiasingMap Map to update
|
||||
* @param array $aAliasTranslation Translation table resulting from calls to MergeWith_InNamespace
|
||||
* @return void of <old-alias> => <new-alias>
|
||||
* @return void of [old-alias][] => new-alias (@since 2.7.2)
|
||||
*/
|
||||
protected function UpdateRealiasingMap(&$aRealiasingMap, $aAliasTranslation)
|
||||
{
|
||||
@@ -803,17 +818,33 @@ class DBObjectSearch extends DBSearch
|
||||
{
|
||||
foreach ($aAliasTranslation as $sPrevAlias => $aRules)
|
||||
{
|
||||
if (isset($aRules['*']))
|
||||
if (!isset($aRules['*']))
|
||||
{
|
||||
$sNewAlias = $aRules['*'];
|
||||
$sOriginalAlias = array_search($sPrevAlias, $aRealiasingMap);
|
||||
if ($sOriginalAlias !== false)
|
||||
continue;
|
||||
}
|
||||
|
||||
$sNewAlias = $aRules['*'];
|
||||
$bOriginalFound = false;
|
||||
$iIndex = 0;
|
||||
foreach ($aRealiasingMap as $sOriginalAlias => $aAliases)
|
||||
{
|
||||
$iIndex = array_search($sPrevAlias, $aAliases);
|
||||
if ($iIndex !== false)
|
||||
{
|
||||
$aRealiasingMap[$sOriginalAlias] = $sNewAlias;
|
||||
$bOriginalFound = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
}
|
||||
if ($bOriginalFound)
|
||||
{
|
||||
$aRealiasingMap[$sOriginalAlias][$iIndex] = $sNewAlias;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($aRealiasingMap[$sPrevAlias]) || !in_array($sNewAlias, $aRealiasingMap[$sPrevAlias]))
|
||||
{
|
||||
$aRealiasingMap[$sPrevAlias] = $sNewAlias;
|
||||
$aRealiasingMap[$sPrevAlias][] = $sNewAlias;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -861,7 +892,7 @@ class DBObjectSearch extends DBSearch
|
||||
/**
|
||||
* Add a link to another filter, using an extkey already present in current filter
|
||||
*
|
||||
* @param DBObjectSearch $oFilter filter to join to
|
||||
* @param DBObjectSearch $oFilter filter to join to (can be modified)
|
||||
* @param string $sExtKeyAttCode extkey present in current filter, that allows to points to $oFilter
|
||||
* @param int $iOperatorCode
|
||||
* @param array $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed.
|
||||
@@ -955,7 +986,7 @@ class DBObjectSearch extends DBSearch
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DBObjectSearch $oFilter
|
||||
* @param DBObjectSearch $oFilter (can be modified)
|
||||
* @param $sForeignExtKeyAttCode
|
||||
* @param int $iOperatorCode
|
||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
||||
|
||||
@@ -222,6 +222,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
if (!is_array($aAttToLoad))
|
||||
{
|
||||
$this->m_aAttToLoad = null;
|
||||
trigger_error ( "OptimizeColumnLoad : wrong format actual :(".print_r($aAttToLoad, true)."). should be [alias=>[attributes]]", E_USER_WARNING );
|
||||
return;
|
||||
}
|
||||
foreach ($aAttToLoad as $sAlias => $aAttCodes)
|
||||
@@ -229,6 +230,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
if (!is_array($aAttCodes))
|
||||
{
|
||||
$this->m_aAttToLoad = null;
|
||||
trigger_error ( "OptimizeColumnLoad : wrong format actual :(".print_r($aAttToLoad, true)."). should be [alias=>[attributes]]", E_USER_WARNING );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -267,6 +269,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the friendly name anytime
|
||||
$oFriendlyNameAttDef = MetaModel::GetAttributeDef($sClass, 'friendlyname');
|
||||
$aAttToLoadWithAttDef[$sClassAlias]['friendlyname'] = $oFriendlyNameAttDef;
|
||||
|
||||
@@ -404,7 +404,9 @@ abstract class DBSearch
|
||||
*/
|
||||
abstract public function AddCondition_FullText($sFullText);
|
||||
|
||||
/**
|
||||
abstract public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle);
|
||||
|
||||
/**
|
||||
* Perform a join, the remote class being matched by the mean of its primary key
|
||||
*
|
||||
* The join is performed
|
||||
@@ -631,7 +633,7 @@ abstract class DBSearch
|
||||
}
|
||||
|
||||
$sOql = $this->ToOql($bDevelopParams, $aContextParams);
|
||||
return json_encode(array($sOql, $aQueryParams, $this->m_aModifierProperties));
|
||||
return urlencode(json_encode(array($sOql, $aQueryParams, $this->m_aModifierProperties)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,7 +650,7 @@ abstract class DBSearch
|
||||
*/
|
||||
static public function unserialize($sValue)
|
||||
{
|
||||
$aData = json_decode($sValue, true);
|
||||
$aData = json_decode(urldecode($sValue), true);
|
||||
if (is_null($aData))
|
||||
{
|
||||
throw new CoreException("Invalid filter parameter");
|
||||
@@ -1112,6 +1114,8 @@ abstract class DBSearch
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*
|
||||
* @since 2.7.0 N°2555
|
||||
*/
|
||||
public function GetFirstResult($bMustHaveOneResultMax = true, $aOrderBy = array(), $aSearchParams = array())
|
||||
{
|
||||
|
||||
@@ -376,19 +376,26 @@ class DBUnionSearch extends DBSearch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle)
|
||||
{
|
||||
foreach ($this->aSearches as $oSearch)
|
||||
{
|
||||
$oSearch->AddCondition_FullTextOnAttributes($aAttCodes, $sNeedle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DBObjectSearch $oFilter
|
||||
* @param $sExtKeyAttCode
|
||||
* @param int $iOperatorCode
|
||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
||||
* @throws CoreException
|
||||
* @throws CoreWarning
|
||||
* @param null $aRealiasingMap array of [old-alias][] => <new-alias>, for each alias that has changed (@since 2.7.2)
|
||||
*/
|
||||
public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
||||
{
|
||||
foreach ($this->aSearches as $oSearch)
|
||||
{
|
||||
$oSearch->AddCondition_PointingTo($oFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||
$oConditionFilter = $oFilter->DeepClone();
|
||||
$oSearch->AddCondition_PointingTo($oConditionFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,13 +403,14 @@ class DBUnionSearch extends DBSearch
|
||||
* @param DBObjectSearch $oFilter
|
||||
* @param $sForeignExtKeyAttCode
|
||||
* @param int $iOperatorCode
|
||||
* @param null $aRealiasingMap array of <old-alias> => <new-alias>, for each alias that has changed
|
||||
* @param null $aRealiasingMap array of [old-alias][] => <new-alias>, for each alias that has changed (@since 2.7.2)
|
||||
*/
|
||||
public function AddCondition_ReferencedBy(DBObjectSearch $oFilter, $sForeignExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
|
||||
{
|
||||
foreach ($this->aSearches as $oSearch)
|
||||
{
|
||||
$oSearch->AddCondition_ReferencedBy($oFilter, $sForeignExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||
$oConditionFilter = $oFilter->DeepClone();
|
||||
$oSearch->AddCondition_ReferencedBy($oConditionFilter, $sForeignExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -353,7 +353,8 @@ EOF
|
||||
|
||||
$fStartExcel = microtime(true);
|
||||
$writer = new XLSXWriter();
|
||||
$oDateTimeFormat = new DateTimeFormat($this->aStatusInfo['date_format']);
|
||||
$sDateFormat = isset($this->aStatusInfo['date_format']) ? $this->aStatusInfo['date_format'] : (string)AttributeDateTime::GetFormat();
|
||||
$oDateTimeFormat = new DateTimeFormat($sDateFormat);
|
||||
$writer->setDateTimeFormat($oDateTimeFormat->ToExcel());
|
||||
$oDateFormat = new DateTimeFormat($oDateTimeFormat->ToDateFormat());
|
||||
$writer->setDateFormat($oDateFormat->ToExcel());
|
||||
|
||||
@@ -129,8 +129,7 @@ abstract class RotatingLogFileNameBuilder implements iLogFileNameBuilder
|
||||
public function CheckAndRotateLogFile()
|
||||
{
|
||||
$oConfig = utils::GetConfig();
|
||||
$sItopTimeZone = $oConfig->Get('timezone');
|
||||
$timezone = new DateTimeZone($sItopTimeZone);
|
||||
utils::InitTimeZone($oConfig);
|
||||
|
||||
if ($this->GetLastModifiedDateForFile() === null)
|
||||
{
|
||||
@@ -145,11 +144,13 @@ abstract class RotatingLogFileNameBuilder implements iLogFileNameBuilder
|
||||
return;
|
||||
}
|
||||
$oDateTime = DateTime::createFromFormat('U', $iLogDateLastModifiedTimeStamp);
|
||||
$sItopTimeZone = $oConfig->Get('timezone');
|
||||
$timezone = new DateTimeZone($sItopTimeZone);
|
||||
$oDateTime->setTimezone($timezone);
|
||||
$this->SetLastModifiedDateForFile($oDateTime);
|
||||
}
|
||||
|
||||
$oNow = new DateTime('now', $timezone);
|
||||
$oNow = new DateTime();
|
||||
$bShouldRotate = $this->ShouldRotate($this->GetLastModifiedDateForFile(), $oNow);
|
||||
if (!$bShouldRotate)
|
||||
{
|
||||
@@ -830,4 +831,4 @@ class LogFileRotationProcess implements iScheduledProcess
|
||||
|
||||
throw new ProcessException(self::class.' : The configured filename builder is invalid (log_filename_builder_impl="'.$sLogFileNameBuilder.'")');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,13 @@ abstract class MetaModel
|
||||
/** @var string */
|
||||
protected static $m_sEnvironment = 'production';
|
||||
|
||||
/**
|
||||
* MetaModel constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -741,7 +748,51 @@ abstract class MetaModel
|
||||
return array('%1$s', array($nameRawSpec));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return array
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
final static public function GetComplementAttributeSpec($sClass)
|
||||
{
|
||||
self::_check_subclass($sClass);
|
||||
if (!isset(self::$m_aClassParams[$sClass]["name_complement_for_select"]))
|
||||
{
|
||||
return array($sClass, array());
|
||||
}
|
||||
$nameRawSpec = self::$m_aClassParams[$sClass]["name_complement_for_select"];
|
||||
if (is_array($nameRawSpec))
|
||||
{
|
||||
$sFormat = Dict::S("Class:$sClass/ComplementForSelect", '');
|
||||
if (strlen($sFormat) == 0)
|
||||
{
|
||||
// Default to "%1$s %2$s..."
|
||||
for($i = 1; $i <= count($nameRawSpec); $i++)
|
||||
{
|
||||
if (empty($sFormat))
|
||||
{
|
||||
$sFormat .= '%'.$i.'$s';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sFormat .= ' %'.$i.'$s';
|
||||
}
|
||||
}
|
||||
}
|
||||
return array($sFormat, $nameRawSpec);
|
||||
}
|
||||
elseif (empty($nameRawSpec))
|
||||
{
|
||||
return array($sClass, array());
|
||||
}
|
||||
else
|
||||
{
|
||||
// string -> attcode
|
||||
return array('%1$s', array($nameRawSpec));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the friendly name expression for a given class
|
||||
*
|
||||
@@ -1848,7 +1899,7 @@ abstract class MetaModel
|
||||
* @param string $sClass
|
||||
* @param string $sListCode
|
||||
*
|
||||
* @return array
|
||||
* @return array list of attribute codes
|
||||
*/
|
||||
public static function GetZListItems($sClass, $sListCode)
|
||||
{
|
||||
@@ -1868,6 +1919,82 @@ abstract class MetaModel
|
||||
return self::GetZListItems($sParentClass, $sListCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sRemoteClass
|
||||
*
|
||||
* @return \AttributeDefinition[] list of attdefs to display by default for the remote class
|
||||
*
|
||||
* @since 2.8.0 N°2334
|
||||
*/
|
||||
public static function GetZListAttDefsFilteredForIndirectRemoteClass($sRemoteClass)
|
||||
{
|
||||
$aAttCodesToPrint = [];
|
||||
|
||||
foreach (MetaModel::GetZListItems($sRemoteClass, 'list') as $sFieldCode)
|
||||
{
|
||||
//TODO: check the state of the attribute: hidden or visible ?
|
||||
if ($sFieldCode == 'finalclass')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$oRemoteAttDef = MetaModel::GetAttributeDef($sRemoteClass, $sFieldCode);
|
||||
$aAttCodesToPrint[] = $oRemoteAttDef;
|
||||
}
|
||||
|
||||
return $aAttCodesToPrint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass left class
|
||||
* @param string $sAttCode AttributeLinkedSetIndirect attcode
|
||||
*
|
||||
* @return \AttributeDefinition[] list of attdefs to display by default for lnk class
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @since 2.8.0 N°2334
|
||||
*/
|
||||
public static function GetZListAttDefsFilteredForIndirectLinkClass($sClass, $sAttCode)
|
||||
{
|
||||
$aAttCodesToPrint = [];
|
||||
|
||||
$oLinkedSetAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$sLinkedClass = $oLinkedSetAttDef->GetLinkedClass();
|
||||
$sExtKeyToRemote = $oLinkedSetAttDef->GetExtKeyToRemote();
|
||||
$sExtKeyToMe = $oLinkedSetAttDef->GetExtKeyToMe();
|
||||
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||
$sDefaultState = MetaModel::GetDefaultState($sClass);
|
||||
|
||||
foreach (MetaModel::FlattenZList(MetaModel::GetZListItems($sLinkedClass, 'list')) as $sLnkAttCode)
|
||||
{
|
||||
$oLnkAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sLnkAttCode);
|
||||
if ($sStateAttCode == $sLnkAttCode)
|
||||
{
|
||||
// State attribute is always hidden from the UI
|
||||
continue;
|
||||
}
|
||||
if (($sLnkAttCode == $sExtKeyToMe)
|
||||
|| ($sLnkAttCode == $sExtKeyToRemote)
|
||||
|| ($sLnkAttCode == 'finalclass'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!($oLnkAttDef->IsWritable()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$iFlags = MetaModel::GetAttributeFlags($sLinkedClass, $sDefaultState, $sLnkAttCode);
|
||||
if (!($iFlags & OPT_ATT_HIDDEN) && !($iFlags & OPT_ATT_READONLY))
|
||||
{
|
||||
$aAttCodesToPrint[] = $oLnkAttDef;
|
||||
}
|
||||
}
|
||||
|
||||
return $aAttCodesToPrint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
* @param string $sListCode
|
||||
@@ -2681,7 +2808,7 @@ abstract class MetaModel
|
||||
$aInterfaces = array('iApplicationUIExtension', 'iPreferencesExtension', 'iApplicationObjectExtension', 'iLoginFSMExtension', 'iLoginUIExtension', 'iLogoutExtension', 'iQueryModifier', 'iOnClassInitialization', 'iPopupMenuExtension', 'iPageUIExtension', 'iPortalUIExtension', 'ModuleHandlerApiInterface', 'iNewsroomProvider', 'iModuleExtension');
|
||||
foreach($aInterfaces as $sInterface)
|
||||
{
|
||||
self::$m_aExtensionClasses[$sInterface] = array();
|
||||
self::$m_aExtensionClassNames[$sInterface] = array();
|
||||
}
|
||||
|
||||
foreach(get_declared_classes() as $sPHPClass)
|
||||
@@ -2692,11 +2819,7 @@ abstract class MetaModel
|
||||
{
|
||||
if ($oRefClass->implementsInterface($sInterface) && $oRefClass->isInstantiable())
|
||||
{
|
||||
if (is_null($oExtensionInstance))
|
||||
{
|
||||
$oExtensionInstance = new $sPHPClass;
|
||||
}
|
||||
self::$m_aExtensionClasses[$sInterface][$sPHPClass] = $oExtensionInstance;
|
||||
self::$m_aExtensionClassNames[$sInterface][$sPHPClass] = $sPHPClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4068,7 +4191,7 @@ abstract class MetaModel
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT Contact WHERE id = :id");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('id' => UserRights::GetContactId()));
|
||||
$oSet->OptimizeColumnLoad($aCurrentContact);
|
||||
$oSet->OptimizeColumnLoad(['Contact' => $aCurrentContact]);
|
||||
$oUser = $oSet->fetch();
|
||||
foreach ($aCurrentContact as $sField)
|
||||
{
|
||||
@@ -5421,7 +5544,7 @@ abstract class MetaModel
|
||||
{
|
||||
$sIndexName = $sField;
|
||||
$sColumns = '`'.$sField.'`';
|
||||
if (!is_null($aLength[0]))
|
||||
if (isset($aLength[0]))
|
||||
{
|
||||
$sColumns .= ' ('.$aLength[0].')';
|
||||
}
|
||||
@@ -6185,6 +6308,7 @@ abstract class MetaModel
|
||||
|
||||
// N°2478 utils has his own private attribute
|
||||
// @see utils::GetConfig : it always call MetaModel, but to be sure we're doing this extra copy anyway O:)
|
||||
utils::InitTimeZone($oConfiguration);
|
||||
utils::SetConfig($oConfiguration);
|
||||
|
||||
// Set log ASAP
|
||||
@@ -6225,19 +6349,6 @@ abstract class MetaModel
|
||||
DBSearch::EnableQueryIndentation(self::$m_oConfig->Get('query_indentation_enabled'));
|
||||
DBSearch::EnableOptimizeQuery(self::$m_oConfig->Get('query_optimization_enabled'));
|
||||
|
||||
// PHP timezone first...
|
||||
//
|
||||
$sPHPTimezone = self::$m_oConfig->Get('timezone');
|
||||
if ($sPHPTimezone == '')
|
||||
{
|
||||
// Leave as is... up to the admin to set a value somewhere...
|
||||
//$sPHPTimezone = date_default_timezone_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
date_default_timezone_set($sPHPTimezone);
|
||||
}
|
||||
|
||||
// Note: load the dictionary as soon as possible, because it might be
|
||||
// needed when some error occur
|
||||
$sAppIdentity = 'itop-'.MetaModel::GetEnvironmentId();
|
||||
@@ -6281,7 +6392,7 @@ abstract class MetaModel
|
||||
if (is_array($result))
|
||||
{
|
||||
// todo - verifier que toutes les classes mentionnees ici sont chargees dans InitClasses()
|
||||
self::$m_aExtensionClasses = $result['m_aExtensionClasses'];
|
||||
self::$m_aExtensionClassNames = $result['m_aExtensionClassNames'];
|
||||
self::$m_Category2Class = $result['m_Category2Class'];
|
||||
self::$m_aRootClasses = $result['m_aRootClasses'];
|
||||
self::$m_aParentClasses = $result['m_aParentClasses'];
|
||||
@@ -6318,7 +6429,7 @@ abstract class MetaModel
|
||||
$oKPI = new ExecutionKPI();
|
||||
|
||||
$aCache = array();
|
||||
$aCache['m_aExtensionClasses'] = self::$m_aExtensionClasses;
|
||||
$aCache['m_aExtensionClassNames'] = self::$m_aExtensionClassNames;
|
||||
$aCache['m_Category2Class'] = self::$m_Category2Class;
|
||||
$aCache['m_aRootClasses'] = self::$m_aRootClasses; // array of "classname" => "rootclass"
|
||||
$aCache['m_aParentClasses'] = self::$m_aParentClasses; // array of ("classname" => array of "parentclass")
|
||||
@@ -6402,8 +6513,8 @@ abstract class MetaModel
|
||||
return md5(APPROOT).'-'.self::$m_sEnvironment;
|
||||
}
|
||||
|
||||
/** @var array */
|
||||
protected static $m_aExtensionClasses = array();
|
||||
/** @var array */
|
||||
protected static $m_aExtensionClassNames = [];
|
||||
|
||||
/**
|
||||
* @param string $sToInclude
|
||||
@@ -7198,25 +7309,9 @@ abstract class MetaModel
|
||||
*/
|
||||
public static function EnumPlugins($sInterface, $sFilterInstanceOf = null)
|
||||
{
|
||||
if (!array_key_exists($sInterface, self::$m_aExtensionClasses))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
$pluginManager = new PluginManager(self::$m_aExtensionClassNames);
|
||||
|
||||
if (is_null($sFilterInstanceOf))
|
||||
{
|
||||
return self::$m_aExtensionClasses[$sInterface];
|
||||
}
|
||||
|
||||
$fFilterCallback = function ($instance) use ($sFilterInstanceOf)
|
||||
{
|
||||
return $instance instanceof $sFilterInstanceOf;
|
||||
};
|
||||
|
||||
return array_filter(
|
||||
self::$m_aExtensionClasses[$sInterface],
|
||||
$fFilterCallback
|
||||
);
|
||||
return $pluginManager->EnumPlugins($sInterface, $sFilterInstanceOf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7227,16 +7322,9 @@ abstract class MetaModel
|
||||
*/
|
||||
public static function GetPlugins($sInterface, $sClassName)
|
||||
{
|
||||
$oInstance = null;
|
||||
if (array_key_exists($sInterface, self::$m_aExtensionClasses))
|
||||
{
|
||||
if (array_key_exists($sClassName, self::$m_aExtensionClasses[$sInterface]))
|
||||
{
|
||||
return self::$m_aExtensionClasses[$sInterface][$sClassName];
|
||||
}
|
||||
}
|
||||
$pluginManager = new PluginManager(self::$m_aExtensionClassNames);
|
||||
|
||||
return $oInstance;
|
||||
return $pluginManager->GetPlugins($sInterface, $sClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2235,7 +2235,15 @@ class ListExpression extends Expression
|
||||
{
|
||||
if ($oExpr instanceof VariableExpression)
|
||||
{
|
||||
$this->m_aExpressions[$idx] = $oExpr->GetAsScalar($aArgs);
|
||||
$oVarExpr = $oExpr->GetAsScalar($aArgs);
|
||||
if ($oVarExpr instanceof ListExpression)
|
||||
{
|
||||
$this->m_aExpressions = $oVarExpr->GetItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_aExpressions[$idx] = $oVarExpr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -30,6 +30,9 @@ require_once('dbobjectiterator.php');
|
||||
|
||||
class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
{
|
||||
const LINK_ALIAS = 'Link';
|
||||
const REMOTE_ALIAS = 'Remote';
|
||||
|
||||
protected $sHostClass; // subclass of DBObject
|
||||
protected $sAttCode; // xxxxxx_list
|
||||
protected $sClass; // class of the links
|
||||
@@ -786,11 +789,13 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
/**
|
||||
* @param bool $bShowObsolete
|
||||
*
|
||||
* @return \DBObjectSet
|
||||
* @return \DBObjectSet indirect relations will get `SELECT L,R ...` (l = lnk class, R = remote)
|
||||
* @throws \CoreException
|
||||
* @throws \CoreWarning
|
||||
* @throws \MySQLException
|
||||
* @throws \Exception
|
||||
*
|
||||
* @since 2.8.0 N°2334 returns both lnk and remote classes for indirect relations
|
||||
*/
|
||||
public function ToDBObjectSet($bShowObsolete = true)
|
||||
{
|
||||
@@ -802,7 +807,12 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
/** @var \AttributeExternalKey $oLinkingAttDef */
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($this->sClass, $sExtKeyToRemote);
|
||||
|
||||
// N°2334 add pointed class (SELECT L,R) to have all fields (lnk + remote) in display
|
||||
// the pointed class is always present in the search, as generated by \AttributeLinkedSet::GetDefaultValue
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
$oRemoteClassSearch = new DBObjectSearch($sTargetClass);
|
||||
|
||||
if (!$bShowObsolete && MetaModel::IsObsoletable($sTargetClass))
|
||||
{
|
||||
$oNotObsolete = new BinaryExpression(
|
||||
@@ -810,10 +820,24 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
'=',
|
||||
new ScalarExpression(0)
|
||||
);
|
||||
$oNotObsoleteRemote = new DBObjectSearch($sTargetClass);
|
||||
$oNotObsoleteRemote->AddConditionExpression($oNotObsolete);
|
||||
$oLinkSearch->AddCondition_PointingTo($oNotObsoleteRemote, $sExtKeyToRemote);
|
||||
$oRemoteClassSearch->AddConditionExpression($oNotObsolete);
|
||||
}
|
||||
|
||||
if (!utils::IsArchiveMode() && MetaModel::IsArchivable($sTargetClass))
|
||||
{
|
||||
$oNotArchived = new BinaryExpression(
|
||||
new FieldExpression('archive_flag', $sTargetClass),
|
||||
'=',
|
||||
new ScalarExpression(0)
|
||||
);
|
||||
|
||||
$oRemoteClassSearch->AddConditionExpression($oNotArchived);
|
||||
}
|
||||
|
||||
$oLinkSearch->AddCondition_PointingTo($oRemoteClassSearch, $sExtKeyToRemote);
|
||||
$oLinkSearch->RenameAlias($oLinkSearch->GetClassAlias(), self::LINK_ALIAS);
|
||||
$oLinkSearch->RenameAlias($sTargetClass, self::REMOTE_ALIAS);
|
||||
$oLinkSearch->SetSelectedClasses([self::LINK_ALIAS, self::REMOTE_ALIAS]);
|
||||
}
|
||||
$oLinkSet = new DBObjectSet($oLinkSearch);
|
||||
$oLinkSet->SetShowObsoleteData($bShowObsolete);
|
||||
@@ -824,4 +848,4 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
|
||||
|
||||
return $oLinkSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
core/plugininstanciationmanager.class.inc.php
Normal file
30
core/plugininstanciationmanager.class.inc.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
class PluginInstanciationManager
|
||||
{
|
||||
public function InstantiatePlugins($m_aExtensionClassNames, $sInterface)
|
||||
{
|
||||
$newPerInstanceClasses = array();
|
||||
if (array_key_exists($sInterface, $m_aExtensionClassNames))
|
||||
{
|
||||
foreach ($m_aExtensionClassNames[$sInterface] as $sClassName)
|
||||
{
|
||||
if (class_exists($sClassName))
|
||||
{
|
||||
$class = new ReflectionClass($sClassName);
|
||||
|
||||
if ($class->isInstantiable())
|
||||
{
|
||||
$newPerInstanceClasses[$sClassName] = new $sClassName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $newPerInstanceClasses;
|
||||
}
|
||||
}
|
||||
105
core/pluginmanager.class.inc.php
Normal file
105
core/pluginmanager.class.inc.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
class PluginManager
|
||||
{
|
||||
|
||||
private $m_aExtensionClassNames;
|
||||
private static $m_aExtensionClasses;
|
||||
private $m_pluginInstantiationManager;
|
||||
|
||||
public function __construct($m_aExtensionClassNames, $m_pluginInstanciationManager = null)
|
||||
{
|
||||
if (is_null(self::$m_aExtensionClasses)) {
|
||||
self::$m_aExtensionClasses = [];
|
||||
}
|
||||
$this->m_aExtensionClassNames = $m_aExtensionClassNames;
|
||||
|
||||
if ($m_pluginInstanciationManager == null)
|
||||
{
|
||||
$this->m_pluginInstantiationManager = new PluginInstanciationManager();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->m_pluginInstantiationManager = $m_pluginInstanciationManager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sInterface
|
||||
* @param bool $bCanInstantiatePlugins internal use, let this value to true
|
||||
* @param string|null $sFilterInstanceOf [optional] if given, only instance of this string will be returned
|
||||
*
|
||||
* @return array classes=>instance implementing the given interface
|
||||
*/
|
||||
public function EnumPlugins($sInterface, $sFilterInstanceOf = null, $bCanInstantiatePlugins = true)
|
||||
{
|
||||
$aPlugins = array();
|
||||
if (array_key_exists($sInterface, self::$m_aExtensionClasses))
|
||||
{
|
||||
$aAllPlugins = array_values(self::$m_aExtensionClasses[$sInterface]);
|
||||
|
||||
if (is_null($sFilterInstanceOf))
|
||||
{
|
||||
return $aAllPlugins;
|
||||
};
|
||||
|
||||
$aPlugins = array();
|
||||
foreach ($aAllPlugins as $instance)
|
||||
{
|
||||
if ($instance instanceof $sFilterInstanceOf)
|
||||
{
|
||||
$aPlugins[] = $instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($bCanInstantiatePlugins && array_key_exists($sInterface, $this->m_aExtensionClassNames))
|
||||
{
|
||||
$this->InstantiatePlugins($sInterface);
|
||||
|
||||
return $this->EnumPlugins($sInterface, $sFilterInstanceOf, false);
|
||||
}
|
||||
}
|
||||
return $aPlugins;
|
||||
}
|
||||
|
||||
public function InstantiatePlugins($sInterface)
|
||||
{
|
||||
self::$m_aExtensionClasses[$sInterface] = $this->m_pluginInstantiationManager->InstantiatePlugins($this->m_aExtensionClassNames, $sInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sInterface
|
||||
* @param string $sClassName
|
||||
* @param bool $bCanInstantiatePlugins internal use, let this value to true
|
||||
*
|
||||
* @return mixed the instance of the specified plug-ins for the given interface
|
||||
*/
|
||||
public function GetPlugins($sInterface, $sClassName, $bCanInstantiatePlugins = true)
|
||||
{
|
||||
$oInstance = null;
|
||||
if (array_key_exists($sInterface, self::$m_aExtensionClasses))
|
||||
{
|
||||
if (array_key_exists($sClassName, self::$m_aExtensionClasses[$sInterface]))
|
||||
{
|
||||
return self::$m_aExtensionClasses[$sInterface][$sClassName];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($bCanInstantiatePlugins && array_key_exists($sInterface, $this->m_aExtensionClassNames))
|
||||
{
|
||||
$this->InstantiatePlugins($sInterface);
|
||||
return $this->GetPlugins($sInterface, $sClassName, false);
|
||||
}
|
||||
}
|
||||
|
||||
return $oInstance;
|
||||
}
|
||||
}
|
||||
@@ -467,6 +467,18 @@ class CoreServices implements iRestServiceProvider
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$bExtendedOutput && RestUtils::GetOptionalParam($aParams, 'output_fields', '*') != '*')
|
||||
{
|
||||
$aFields = $aShowFields[$sClass];
|
||||
//Id is not a valid attribute to optimize
|
||||
if (in_array('id', $aFields))
|
||||
{
|
||||
unset($aFields[array_search('id', $aFields)]);
|
||||
}
|
||||
$aAttToLoad = array($oObjectSet->GetClassAlias() => $aFields);
|
||||
$oObjectSet->OptimizeColumnLoad($aAttToLoad);
|
||||
}
|
||||
|
||||
while ($oObject = $oObjectSet->Fetch())
|
||||
{
|
||||
$oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
|
||||
|
||||
@@ -365,29 +365,37 @@ EOF
|
||||
{
|
||||
throw new BulkExportMissingParameterException('fields');
|
||||
}
|
||||
else if(($sQueryId !== null) && ($sQueryId !== null))
|
||||
else
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
|
||||
$oQueries = new DBObjectSet($oSearch);
|
||||
if ($oQueries->Count() > 0)
|
||||
if (($sQueryId !== null) && ($sQueryId !== null))
|
||||
{
|
||||
$oQuery = $oQueries->Fetch();
|
||||
if (($sFields === null) || ($sFields === ''))
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId));
|
||||
$oQueries = new DBObjectSet($oSearch);
|
||||
if ($oQueries->Count() > 0)
|
||||
{
|
||||
// No 'fields' parameter supplied, take the fields from the query phrasebook definition
|
||||
$sFields = trim($oQuery->Get('fields'));
|
||||
if ($sFields === '')
|
||||
$oQuery = $oQueries->Fetch();
|
||||
if (($sFields === null) || ($sFields === ''))
|
||||
{
|
||||
throw new BulkExportMissingParameterException('fields');
|
||||
// No 'fields' parameter supplied, take the fields from the query phrasebook definition
|
||||
$sFields = trim($oQuery->Get('fields'));
|
||||
if ($sFields === '')
|
||||
{
|
||||
throw new BulkExportMissingParameterException('fields');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw BulkExportException('Invalid value for the parameter: query. There is no Query Phrasebook with id = '.$sQueryId, Dict::Format('Core:BulkExport:InvalidParameter_Query', $sQueryId));
|
||||
else
|
||||
{
|
||||
throw BulkExportException('Invalid value for the parameter: query. There is no Query Phrasebook with id = '.$sQueryId, Dict::Format('Core:BulkExport:InvalidParameter_Query', $sQueryId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->SetFields($sFields);
|
||||
}
|
||||
|
||||
public function SetFields($sFields)
|
||||
{
|
||||
// Interpret (and check) the list of fields
|
||||
//
|
||||
$aSelectedClasses = $this->oSearch->GetSelectedClasses();
|
||||
|
||||
@@ -220,7 +220,7 @@ class ValueSetObjects extends ValueSetDefinition
|
||||
$this->m_sOperation = $sOperation;
|
||||
|
||||
$this->m_aValues = array();
|
||||
|
||||
|
||||
if ($this->m_bAllowAllData)
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
|
||||
@@ -348,6 +348,160 @@ class ValueSetObjects extends ValueSetDefinition
|
||||
{
|
||||
$this->m_bSort = $bSort;
|
||||
}
|
||||
|
||||
public function GetValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation))
|
||||
{
|
||||
$this->LoadValuesForAutocomplete($aArgs, $sContains, $sOperation);
|
||||
$this->m_bIsLoaded = true;
|
||||
}
|
||||
// The results are already filtered and sorted (on friendly name)
|
||||
$aRet = $this->m_aValues;
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aArgs
|
||||
* @param string $sContains
|
||||
* @param string $sOperation 'contains' or 'equals_start_with'
|
||||
*
|
||||
* @return bool
|
||||
* @throws \CoreException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
|
||||
{
|
||||
$this->m_sContains = $sContains;
|
||||
$this->m_sOperation = $sOperation;
|
||||
|
||||
$this->m_aValues = array();
|
||||
|
||||
if ($this->m_bAllowAllData)
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
|
||||
$oFilter->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
}
|
||||
|
||||
if (!$oFilter) return false;
|
||||
if (!is_null($this->m_oExtraCondition))
|
||||
{
|
||||
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
|
||||
}
|
||||
foreach($this->m_aModifierProperties as $sPluginClass => $aProperties)
|
||||
{
|
||||
foreach ($aProperties as $sProperty => $value)
|
||||
{
|
||||
$oFilter->SetModifierProperty($sPluginClass, $sProperty, $value);
|
||||
}
|
||||
}
|
||||
|
||||
//$oExpression = DBObjectSearch::GetPolymorphicExpression($oFilter->GetClass(), 'friendlyname');
|
||||
$sClass = $oFilter->GetClass();
|
||||
|
||||
switch ($sOperation)
|
||||
{
|
||||
case 'equals':
|
||||
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||
$sClassAlias = $oFilter->GetClassAlias();
|
||||
$aFilters = array();
|
||||
$oValueExpr = new ScalarExpression($sContains);
|
||||
foreach($aAttributes as $sAttribute)
|
||||
{
|
||||
$oNewFilter = $oFilter->DeepClone();
|
||||
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||
$oCondition = new BinaryExpression($oNameExpr, '=', $oValueExpr);
|
||||
$oNewFilter->AddConditionExpression($oCondition);
|
||||
$aFilters[] = $oNewFilter;
|
||||
}
|
||||
// Unions are much faster than OR conditions
|
||||
$oFilter = new DBUnionSearch($aFilters);
|
||||
break;
|
||||
case 'start_with':
|
||||
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
|
||||
$sClassAlias = $oFilter->GetClassAlias();
|
||||
$aFilters = array();
|
||||
$oValueExpr = new ScalarExpression($sContains.'%');
|
||||
foreach($aAttributes as $sAttribute)
|
||||
{
|
||||
$oNewFilter = $oFilter->DeepClone();
|
||||
$oNameExpr = new FieldExpression($sAttribute, $sClassAlias);
|
||||
$oCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||
$oNewFilter->AddConditionExpression($oCondition);
|
||||
$aFilters[] = $oNewFilter;
|
||||
}
|
||||
// Unions are much faster than OR conditions
|
||||
$oFilter = new DBUnionSearch($aFilters);
|
||||
break;
|
||||
|
||||
default:
|
||||
$oValueExpr = new ScalarExpression('%'.$sContains.'%');
|
||||
$oNameExpr = new FieldExpression('friendlyname', $oFilter->GetClassAlias());
|
||||
$oNewCondition = new BinaryExpression($oNameExpr, 'LIKE', $oValueExpr);
|
||||
$oFilter->AddConditionExpression($oNewCondition);
|
||||
break;
|
||||
}
|
||||
|
||||
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort);
|
||||
if (empty($this->m_sValueAttCode))
|
||||
{
|
||||
$aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode));
|
||||
}
|
||||
|
||||
$aComplementAttributeSpec = MetaModel::GetComplementAttributeSpec($sClass);
|
||||
$sFormatAdditionalField = $aComplementAttributeSpec[0];
|
||||
$aAdditionalField = $aComplementAttributeSpec[1];
|
||||
|
||||
if (count($aAdditionalField)>0)
|
||||
{
|
||||
$aAttToLoad = array_merge ($aAttToLoad, [$oFilter->GetClassAlias() => $aAdditionalField]);
|
||||
}
|
||||
|
||||
$oObjects->OptimizeColumnLoad($aAttToLoad);
|
||||
while ($oObject = $oObjects->Fetch())
|
||||
{
|
||||
$aData=[];
|
||||
if (empty($this->m_sValueAttCode))
|
||||
{
|
||||
$aData['label'] = $oObject->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
$aData['label'] = $oObject->Get($this->m_sValueAttCode);
|
||||
}
|
||||
if($oObject->IsObsolete())
|
||||
{
|
||||
$aData['obsolescence_flag']='1';
|
||||
}
|
||||
else
|
||||
{
|
||||
$aData['obsolescence_flag']='0';
|
||||
}
|
||||
if (count($aAdditionalField)>0)
|
||||
{
|
||||
$aArguments = [];
|
||||
foreach ($aAdditionalField as $sAdditionalField)
|
||||
{
|
||||
array_push ($aArguments,$oObject->Get($sAdditionalField));
|
||||
}
|
||||
$aData['additional_field'] = vsprintf($sFormatAdditionalField, $aArguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aData['additional_field']='';
|
||||
}
|
||||
$this->m_aValues[$oObject->GetKey()] = $aData;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
// Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0
|
||||
$version: "v2.8.0";
|
||||
$approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css
|
||||
$approot-relative: "../../../../" !default; // relative to env-***/branding/themes/***/main.css
|
||||
|
||||
// Base colors
|
||||
$gray-base: #000 !default;
|
||||
@@ -127,3 +124,8 @@ $highlight-item-color: $white !default;
|
||||
$content-color: #eeeeee !default;
|
||||
$default-font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif !default;
|
||||
$icons-filter: hue-rotate(0deg) !default;
|
||||
|
||||
%font-awesome-prerequisites{
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -2165,6 +2165,11 @@ fieldset .details>.field_container {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.field_input_zone {
|
||||
.selectize-input {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
.field_container {
|
||||
display: table;
|
||||
width: 100%;
|
||||
@@ -2257,6 +2262,7 @@ fieldset .details>.field_container {
|
||||
|
||||
.field_input_zone{
|
||||
width: 100%; /* auto; */
|
||||
align-items:center;
|
||||
|
||||
&.field_input_string,
|
||||
&.field_input_password{
|
||||
@@ -2390,7 +2396,7 @@ fieldset .details>.field_container {
|
||||
}
|
||||
|
||||
&.field_input_extkey{
|
||||
display: table;
|
||||
display: inline-table;
|
||||
width: 100%;
|
||||
|
||||
> .field_select_wrapper{
|
||||
@@ -2874,13 +2880,34 @@ a.summary, a.summary:hover {
|
||||
height: 12px;
|
||||
}
|
||||
.sort_none {
|
||||
background: url($approot-relative + "images/bg.gif?v=" + $version) no-repeat center;
|
||||
padding-right: 5px;
|
||||
&::after {
|
||||
@extend %font-awesome-prerequisites;
|
||||
text-align: right;
|
||||
content: '\f0dc';
|
||||
color: $complement-color;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.sort_asc {
|
||||
background: url($approot-relative + "images/desc.gif?v=" + $version) no-repeat center;
|
||||
padding-right: 5px;
|
||||
&::after {
|
||||
@extend %font-awesome-prerequisites;
|
||||
text-align: right;
|
||||
content: '\f0d8';
|
||||
color: $complement-color;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.sort_desc {
|
||||
background: url($approot-relative + "images/asc.gif?v=" + $version) no-repeat center;
|
||||
padding-right: 5px;
|
||||
&::after {
|
||||
@extend %font-awesome-prerequisites;
|
||||
text-align: right;
|
||||
content: '\f0d7';
|
||||
color: $complement-color;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
.sort_hidden {
|
||||
display: none;
|
||||
|
||||
267
css/setup.css
267
css/setup.css
@@ -1,267 +0,0 @@
|
||||
/*!
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
/* Helpers classes */
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
/* Animations */
|
||||
@keyframes progress_bar_color_ongoing {
|
||||
from {
|
||||
background-color: #FBD38D;
|
||||
}
|
||||
to {
|
||||
background-color: #FEEBC8;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes bg-pan-left {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
@keyframes bg-pan-left {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
/* Theme */
|
||||
body {
|
||||
background-color: #eee;
|
||||
color: #1A202C;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10pt;
|
||||
font-family: Tahoma, Verdana, Arial, Helvetica, serif;
|
||||
overflow-y: auto;
|
||||
}
|
||||
h1 {
|
||||
color: #555555;
|
||||
font-size: 16pt;
|
||||
}
|
||||
h2 {
|
||||
color: #1A202C;
|
||||
font-size: 14pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
h3 {
|
||||
color: #1C94C4;
|
||||
font-size: 12pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
a {
|
||||
color: #1c94c4;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: #EA7D1E;
|
||||
}
|
||||
#header {
|
||||
width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 50px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
height: 54px;
|
||||
border: 3px solid #CBD2D9;
|
||||
border-bottom: none;
|
||||
}
|
||||
#header img {
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
margin-right: 20px;
|
||||
}
|
||||
#header h1 {
|
||||
height: 54px;
|
||||
margin: 0;
|
||||
}
|
||||
#setup {
|
||||
width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 3px solid #CBD2D9;
|
||||
border-top: none;
|
||||
}
|
||||
.next {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
.v-spacer {
|
||||
padding-top: 1em;
|
||||
}
|
||||
button {
|
||||
margin-top: 1em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
p.info {
|
||||
padding-left: 50px;
|
||||
background: url(../images/info-mid.png) no-repeat left -5px;
|
||||
min-height: 48px;
|
||||
}
|
||||
p.ok {
|
||||
padding-left: 50px;
|
||||
background: url(../images/clean-mid.png) no-repeat left -8px;
|
||||
min-height: 48px;
|
||||
}
|
||||
p.warning {
|
||||
padding-left: 50px;
|
||||
background: url(../images/messagebox_warning-mid.png) no-repeat left -5px;
|
||||
min-height: 48px;
|
||||
}
|
||||
p.error {
|
||||
padding-left: 50px;
|
||||
background: url(../images/stop-mid.png) no-repeat left -5px;
|
||||
min-height: 48px;
|
||||
}
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
td.label {
|
||||
text-align: left;
|
||||
}
|
||||
label.read-only {
|
||||
color: #666;
|
||||
cursor: text;
|
||||
}
|
||||
td.input {
|
||||
text-align: left;
|
||||
}
|
||||
table.formTable {
|
||||
border: 0;
|
||||
}
|
||||
.wizlabel, .wizinput {
|
||||
color: #000;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.wizhelp {
|
||||
color: #333;
|
||||
font-size: 8pt;
|
||||
}
|
||||
#progress {
|
||||
border: none;
|
||||
width: 210px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
margin: 5px;
|
||||
box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06) !important;
|
||||
border-radius: 2px;
|
||||
background-color: #EDF2F7 !important;
|
||||
}
|
||||
#progress .progress {
|
||||
color: #000000 !important;
|
||||
/* !important to overload jQuery UI style */
|
||||
background-image: linear-gradient(270deg, #FBD38D 50%, #FEEBC8 55%, #FBD38D 80%) !important;
|
||||
/* !important to overload jQuery UI style */
|
||||
animation: bg-pan-left 3s infinite both;
|
||||
background-size: 600% 100%;
|
||||
border-radius: inherit;
|
||||
}
|
||||
#progress .progress.progress-error {
|
||||
background-image: none !important;
|
||||
background-color: #F56565 !important;
|
||||
/* !important to overload jQuery UI style */
|
||||
animation: none;
|
||||
}
|
||||
h3.clickable {
|
||||
background: url(../images/plus.gif) no-repeat left;
|
||||
padding-left: 16px;
|
||||
cursor: hand;
|
||||
}
|
||||
h3.clickable.open {
|
||||
background: url(../images/minus.gif) no-repeat left;
|
||||
padding-left: 16px;
|
||||
cursor: hand;
|
||||
}
|
||||
.message {
|
||||
color: #1A202C;
|
||||
background-color: #F7FAFC;
|
||||
border-left: 4px solid #4A5568;
|
||||
padding: 10px;
|
||||
}
|
||||
.message > .message-title {
|
||||
font-weight: bold;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.message ~ .message {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.message.message-valid {
|
||||
color: #276749;
|
||||
background-color: #F0FFF4;
|
||||
border-color: #48BB78;
|
||||
}
|
||||
.message.message-warning {
|
||||
color: #C05621;
|
||||
background-color: #FFFAF0;
|
||||
border-color: #ED8936;
|
||||
}
|
||||
.message.message-error {
|
||||
color: #C53030;
|
||||
background-color: #FFF5F5;
|
||||
border-color: #E53E3E;
|
||||
}
|
||||
.text-valid {
|
||||
color: #276749;
|
||||
}
|
||||
.text-warning {
|
||||
color: #C05621;
|
||||
}
|
||||
.text-error {
|
||||
color: #C53030;
|
||||
}
|
||||
fieldset {
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
fieldset > legend {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 7px;
|
||||
padding-bottom: 7px;
|
||||
width: 100%;
|
||||
color: #3C3C3C;
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid #D2D2D2;
|
||||
}
|
||||
.module-selection-banner img {
|
||||
max-height: 48px;
|
||||
}
|
||||
.module-selection-body {
|
||||
height: 28em;
|
||||
overflow: auto;
|
||||
box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06) !important;
|
||||
background-color: #F7FAFC;
|
||||
padding: 10px;
|
||||
}
|
||||
.module-selection-body .wiz-choice:checked ~ .description #itop-ticket-mgmt-simple-ticket-enhanced-portal:not(:checked) ~ .description::after, .module-selection-body .wiz-choice:checked ~ .description #itop-ticket-mgmt-itil-enhanced-portal:not(:checked) ~ .description::after {
|
||||
content: "Legacy portal is no longer part of iTop, by leaving this option unchecked your portal users won't be able to access iTop anymore.";
|
||||
display: block;
|
||||
margin-top: 0.5em;
|
||||
font-weight: bold;
|
||||
color: #e60000b8;
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
/* integrityCheck: begin (do not remove/edit) */
|
||||
|
||||
/////////
|
||||
// Colors
|
||||
$content-border-color: #CBD2D9 !default;
|
||||
@@ -314,3 +316,4 @@ fieldset{
|
||||
}
|
||||
}
|
||||
|
||||
/* integrityCheck: end (do not remove/edit) */
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'CAS:Error:UserNotAllowed' => 'Usuário não permitido',
|
||||
'CAS:Login:SignIn' => 'Autenticar com CAS',
|
||||
'CAS:Login:SignInTooltip' => 'Clique aqui para se autenticar no servidor CAS',
|
||||
));
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Localized data
|
||||
*
|
||||
* @copyright Copyright (C) 2013 XXXXX
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
|
||||
'CAS:Error:UserNotAllowed' => 'User not allowed~~',
|
||||
'CAS:Login:SignIn' => 'Sign in with CAS~~',
|
||||
'CAS:Login:SignInTooltip' => 'Click here to authenticate yourself with the CAS server~~',
|
||||
));
|
||||
@@ -496,7 +496,7 @@ class CASUserProvisioning
|
||||
}
|
||||
|
||||
// Now synchronize the profiles
|
||||
LoginWebPage::SynchroniseProfiles($oUser, $aProfiles, 'CAS/LDAP Synchro');
|
||||
LoginWebPage::SynchronizeProfiles($oUser, $aProfiles, 'CAS/LDAP Synchro');
|
||||
|
||||
phpCAS::log("Info: the user '".$oUser->GetName()."' (id=".$oUser->GetKey().") now has the following profiles: '".implode("', '", $aProfiles)."'.");
|
||||
if ($oUser->IsModified())
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
/**
|
||||
* @author Hirofumi Kosaka <kosaka@rworks.jp>
|
||||
* @author Hirofumi Kosaka <kosaka@rworks.jp>
|
||||
* @copyright Copyright (C) 2010-2012 Combodo SARL
|
||||
* @licence http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
0
datamodels/2.x/authent-ldap/cs.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/cs.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/cs.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/cs.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/de.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/de.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/de.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/de.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/en.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/en.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/en.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/en.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/fr.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/fr.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/fr.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/fr.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/hu.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/hu.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/hu.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/hu.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/it.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/it.dict.authent-ldap.php
Executable file → Normal file
0
datamodels/2.x/authent-ldap/it.dict.authent-ldap.php → datamodels/2.x/authent-ldap/dictionaries/it.dict.authent-ldap.php
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user