# # # # assemble_report_page_util.cfv # # # get_date_filter_decomposition_dat() # get_date_filter_info_dat() # set_report_info_variable() # # # get_is_customize_report_in_config_permission() # # get_calendar_file_id() # get_report_forms_file_id() # get_profile_javascript_file_id() # # add_profile_specific_javascript_file() # # get_dynamic_report_elements_dat() # # get_macros_dat() # # # # # # include "templates.util.encoding"; include "templates.util.get_web_server_root_path"; include "templates.statistics.util.profile_javascript"; # # # # # get_date_filter_decomposition_dat() # # # # subroutine(get_date_filter_decomposition_dat( node decomposition), ( # Note, the decomposition node only contains component nodes which are part of the date filter, # so we have to check for node existsence. int year = if (decomposition?{"year"}) then (@decomposition{"year"}) else (-1); int quarter = if (decomposition?{"quarter"}) then (@decomposition{"quarter"}) else (-1); int month = if (decomposition?{"month"}) then (@decomposition{"month"}) else (-1); int day = if (decomposition?{"day"}) then (@decomposition{"day"}) else (-1); # int hour = if (decomposition?{"hour"}) then (@decomposition{"hour"}) else (-1); # int minute = if (decomposition?{"minute"}) then (@decomposition{"minute"}) else (-1); # int second = if (decomposition?{"minute"}) then (@decomposition{"second"}) else (-1); # Fix the year if there is year with 2 digits only if (year > -1 and year < 100) then ( if (year < 90) then ( year += 2000; ) else ( year += 1900; ); ); # Convert Salang month to javascript month if (month > -1) then ( month -= 1; ); string dat = "{"; dat .= add_json("year", year, "int"); dat .= add_json("quarter", quarter, "int"); dat .= add_json("month", month, "int"); dat .= add_json("day", day, "int"); # dat .= add_json("hour", hour, "int"); # dat .= add_json("minute", minute, "int"); # dat .= add_json("second", second, "int"); dat = close_json(dat); dat; )); # # # # # get_date_filter_info_js_dat() # # # # subroutine(get_date_filter_info_js_dat( node report_job_date_filter), ( bool is_global_date_filter = @report_job_date_filter{"is_global_date_filter"}; bool is_fixed_date = @report_job_date_filter{"is_fixed_date"}; bool is_valid_date_filter_syntax = false; bool is_out_of_range = false; bool is_relative_date_filter = false; debug_message("#### get_date_filter_info_js_dat() - date_filter_info:\n" . node_as_string(report_job_date_filter) . "\n"); string dat = "{"; dat .= add_json("isGlobalDateFilter", is_global_date_filter, "bool"); if (is_global_date_filter) then ( node df_info = report_job_date_filter{"global_date_filter_info"}; is_valid_date_filter_syntax = @df_info{"is_valid_date_filter_syntax"}; is_out_of_range = @df_info{"is_out_of_range"}; is_relative_date_filter = @df_info{"is_relative_date_filter"}; if (is_valid_date_filter_syntax and !is_relative_date_filter and !is_out_of_range) then ( string date_type = @df_info{"date_type"}; dat .= add_json("dateType", date_type, "string"); if (date_type ne "multiple_dates") then ( # Add the date filter decomposition v.empty_decomposition = ""; node decomposition = if (df_info?{"decomposition_1"}) then (df_info{"decomposition_1"}) else ("v.empty_decomposition"); string decomposition_dat = get_date_filter_decomposition_dat(decomposition); dat .= add_json("decomposition1", decomposition_dat, "obj"); if (date_type eq "date_range") then ( decomposition = if (df_info?{"decomposition_2"}) then (df_info{"decomposition_2"}) else ("v.empty_decomposition"); decomposition_dat = get_date_filter_decomposition_dat(decomposition); dat .= add_json("decomposition2", decomposition_dat, "obj"); ); ); ); ); dat .= add_json("isValidDateFilterSyntax", is_valid_date_filter_syntax, "bool"); dat .= add_json("isOutOfRange", is_out_of_range, "bool"); dat .= add_json("isRelativeDateFilter", is_relative_date_filter, "bool"); dat .= add_json("isFixedDate", is_fixed_date, "bool"); dat = close_json(dat); dat; )); # # # # # set_report_info_variable() # # # # subroutine(set_report_info_variable( string item_name, string item_value, string type), ( # type as used in JSON encoding/escaping, it is: string, int, float, bool or obj. # For security reasons we also encode int, float and bool. Item values of type obj # are already encoded, they must not be encoded again! string quotes = ""; if (type ne "obj") then ( if (type eq "string") then ( # Add quotes for item value quotes = '"'; ); # Encode item value. item_value = encode_json(item_value); ); 'reportInfo.' . item_name . ' = ' . quotes . item_value . quotes . ';\n'; )); # # # # # get_is_customize_report_in_config_permission() # # # # subroutine(get_is_customize_report_in_config_permission( string licensing_features, bool is_root_admin, node super_role), ( bool is_customize_report_in_config_permission = false; if (licensing_features ne "lite") then ( if (is_root_admin) then ( is_customize_report_in_config_permission = true; ) else ( # We give customize_report_in_config_permission if the user # has access and edit permission for config/reports if (super_role?{"config"}) then ( node super_role_config = super_role{"config"}; if (?(super_role_config . ".reports.view")) then ( node feature_permissions = super_role_config{"reports"}; if (feature_permissions?{"edit"}) then ( is_customize_report_in_config_permission = true; ); ); ); ); ); is_customize_report_in_config_permission; )); # # # # # get_calendar_file_id() # # # # subroutine(get_calendar_file_id( node report_job), ( # Returns an up to date calendar file id (name) # Note, we use the earliest_log_date and latest_log_date to ensure # that we don't include any time value. This ensures that the calendar file # isn't re-created upon each time change when real time processing is enabled. node basic_ids = report_job{"basic_ids"}; node db_state = report_job . ".report_state.database"; string s = @basic_ids{"product_build_id"}; s .= @basic_ids{"lang_stats_checksum"}; s .= @report_job{"first_weekday"}; s .= @report_job{"marked_weekday"}; s .= @db_state{"earliest_log_date"}; s .= @db_state{"latest_log_date"}; string calendar_file_id = "calendar_" . md5_digest(s); calendar_file_id; )); # # # # # get_report_forms_file_id() # # # # subroutine(get_report_forms_file_id( node report_job), ( # Returns an up to date report_forms file id (name) node basic_ids = report_job{"basic_ids"}; string s = @basic_ids{"product_build_id"}; s .= @basic_ids{"lang_stats_checksum"}; string report_forms_file_id = "report_forms_" . md5_digest(s); report_forms_file_id; )); # # # # # get_profile_javascript_file_id() # # # # subroutine(get_profile_javascript_file_id( string session_id, string profile_name, node report_job, bool is_date_time_support), ( # Returns an up to date profile javascript file id (name) # This file is created per user session because it may contain # user specific RBAC data. node basic_ids = report_job{"basic_ids"}; string s = @basic_ids{"product_build_id"}; s .= @basic_ids{"lang_stats_checksum"}; s .= @basic_ids{"extended_profile_dat_id"}; s .= @basic_ids{"reports_menu_checksum"}; s .= @report_job{"html_formatting"}{"current_language"}; s .= @report_job{"enable_calendar_in_reports_menu"}; s .= @report_job{"first_weekday"}; s .= @report_job{"marked_weekday"}; string profile_javascript_file_id = "profile_" . md5_digest(s); profile_javascript_file_id; )); # # # # # add_profile_specific_javascript_file() # # # # subroutine(add_profile_specific_javascript_file( string session_id, string profile_name, node report_job, node super_role_reports, bool is_root_admin, bool is_date_time_support), ( # 2009-01-26 - GMF - Changed this to compute web_server_root_dir directly as LOGANALYSISINFO_DIRECTORY . "WebServerRoot". # Previously, it was calling get_web_server_root_path(), but that won't work when we want to *write* a file-- # fileref() looks for the file in LogAnalysisInfo/WebServerRoot, and copies it to the temporary_directory if # necessary. So, this code doesn't need to concern itself with temporary_directory; it can just write to # the local LOGANALYSISINFO_DIRECTORY . "WebServerRoot", and fileref() will handle the rest. # string web_server_root_dir = get_web_server_root_path(); string web_server_root_dir = LOGANALYSISINFO_DIRECTORY . "WebServerRoot" . "/"; string js_file_name = get_profile_javascript_file_id(session_id, profile_name, report_job, is_date_time_support); string js_file_path = web_server_root_dir . "session_files/" . js_file_name . ".js"; if (!file_exists(js_file_path)) then ( string js_text = build_profile_javascript(session_id, is_root_admin, super_role_reports, profile_name, is_date_time_support); int js_file_handle = open_file(js_file_path, "w"); write_string_to_file(js_file_handle, js_text); close_file(js_file_handle); ); string js_fileref_path = "session_files/" . js_file_name . ".js"; '\n'; )); # # # # # get_dynamic_report_elements_dat() # # # # subroutine(get_dynamic_report_elements_dat( node report_job_report_elements, node raw_report_elements), ( debug_message("\n\n" . node_as_string(report_job_report_elements) . "\n\n"); node report_element; string report_element_id; string short_report_element_id; node pivot_table; node raw_report_element; string construction_type; string report_element_name; string report_element_type; bool is_report_element_filter; # We use string for all row numbers to check whether or not they are empty; string starting_row; string ending_row; string number_of_rows; string total_rows; string total_rows_of_flat_table; string report_element_item_dat; bool is_pivot_table; string pivot_table_dat; string pivot_report_field; int pivot_number_of_rows; string pivot_sort_by; string pivot_sort_direction; bool pivot_show_averages_row; string report_elements_dat = "["; foreach report_element report_job_report_elements ( report_element_id = @report_element{"report_element_id"}; short_report_element_id = @report_element{"short_report_element_id"}; # get data from raw_report_elements raw_report_element = raw_report_elements{report_element_id}; report_element_name = @raw_report_element{"report_element_name"}; report_element_type = @raw_report_element{"report_element_type"}; construction_type = @raw_report_element{"construction_type"}; is_report_element_filter = @raw_report_element{"is_report_element_filter"}; report_element_item_dat = "{"; report_element_item_dat .= add_json("id", report_element_id, "string"); report_element_item_dat .= add_json("sid", short_report_element_id, "string"); report_element_item_dat .= add_json("name", report_element_name, "string"); report_element_item_dat .= add_json("reportElementType", report_element_type, "string"); report_element_item_dat .= add_json("constructionType", construction_type, "string"); report_element_item_dat .= add_json("isReportElementFilter", is_report_element_filter, "bool"); if (construction_type eq "standard") then ( is_pivot_table = @raw_report_element{"is_pivot_table"}; report_element_item_dat .= add_json("isPivotTable", is_pivot_table, "bool"); if (report_element_type eq "table") then ( report_element_item_dat .= add_json("reportField", @raw_report_element{"report_field"}, "string"); ); report_element_item_dat .= add_json("sortBy", @raw_report_element{"sort_by"}, "string"); report_element_item_dat .= add_json("sortDirection", @raw_report_element{"sort_direction"}, "string"); starting_row = if (@raw_report_element{"starting_row"} ne "") then (@raw_report_element{"starting_row"}) else ("1"); ending_row = if (@raw_report_element{"ending_row"} ne "") then (@raw_report_element{"ending_row"}) else ("10"); report_element_item_dat .= add_json("startingRow", starting_row, "int"); report_element_item_dat .= add_json("endingRow", ending_row, "int"); # We require the default number_of_rows independently from starting_row and ending_row # because the number_of_rows could be "200" but ending_row is actually "199"! # number_of_rows only exists in report_element node of report job and not in raw_report_element node! number_of_rows = if (@report_element{"number_of_rows"} ne "") then (@report_element{"number_of_rows"}) else ("10"); total_rows = if (@raw_report_element{"total_rows"} ne "") then (@raw_report_element{"total_rows"}) else ("0"); report_element_item_dat .= add_json("numberOfRows", number_of_rows, "int"); report_element_item_dat .= add_json("totalRows", total_rows, "int"); if (is_pivot_table) then ( # 31/Mar/2009 Add total_rows_of_flat_table # Note, we have to check for existence of total_rows_of_flat_table because it may not exist # in cached report elements of production releases. if (raw_report_element?{"total_rows_of_flat_table"}) then ( total_rows_of_flat_table = @raw_report_element{"total_rows_of_flat_table"}; ) else ( total_rows_of_flat_table = total_rows; ); report_element_item_dat .= add_json("totalRowsOfFlatTable", total_rows_of_flat_table, "int"); ); # # Check for pivot_table data (Used to pre-set the pivot table form) # if (report_element?{"pivot_table"}) then ( # Note, the pivot table property is only added if the pivot table is active pivot_table = report_element{"pivot_table"}; if (pivot_table?{"report_field"} and (@pivot_table{"report_field"} ne "")) then ( pivot_report_field = @pivot_table{"report_field"}; pivot_number_of_rows = if (pivot_table?{"number_of_rows"}) then (@pivot_table{"number_of_rows"}) else (10); pivot_sort_by = if (pivot_table?{"sort_by"}) then (@pivot_table{"sort_by"}) else (""); pivot_sort_direction = if (pivot_table?{"sort_direction"}) then (@pivot_table{"sort_direction"}) else (""); pivot_show_averages_row = if (pivot_table?{"show_averages_row"} and @pivot_table{"show_averages_row"}) then (true) else (false); pivot_table_dat = "{"; pivot_table_dat .= add_json("reportField", pivot_report_field, "string"); pivot_table_dat .= add_json("numberOfRows", pivot_number_of_rows, "int"); pivot_table_dat .= add_json("sortBy", pivot_sort_by, "string"); pivot_table_dat .= add_json("sortDirection", pivot_sort_direction, "string"); pivot_table_dat .= add_json("showAveragesRow", pivot_show_averages_row, "bool"); pivot_table_dat = close_json(pivot_table_dat); report_element_item_dat .= add_json("pivotTable", pivot_table_dat, "obj"); ); ); ) else if (construction_type eq "session_page_paths") then ( report_element_item_dat .= add_json("endingRow", @raw_report_element{"ending_row"}, "int"); report_element_item_dat .= add_json("totalRows", @raw_report_element{"total_rows"}, "int"); ) else if (construction_type eq "session_paths") then ( report_element_item_dat .= add_json("numberOfRows", @raw_report_element{"number_of_rows"}, "int"); ); report_element_item_dat = close_json(report_element_item_dat); report_elements_dat .= report_element_item_dat . ","; ); if (report_elements_dat ne "[") then ( report_elements_dat = replace_last(report_elements_dat, ",", "]"); ) else ( # there were no report elements, use empty []. report_elements_dat .= "]"; ); report_elements_dat; )); # # # # # get_macros_dat() # # # # subroutine(get_macros_dat( string session_id, string profile_name), ( string user_node_name = node_name(volatile.authenticated_user_node_path); string macros_dat = "["; if (?("users_cache." . user_node_name . ".profiles." . profile_name . ".preferences.macros")) then ( node macros = "users_cache." . user_node_name . ".profiles." . profile_name . ".preferences.macros"; node item; string item_dat; foreach item macros ( item_dat = "{"; item_dat .= add_json("name", node_name(item), "string"); item_dat .= add_json("label", @item{"label"}, "string"); if (item?{"rn"}) then ( item_dat .= add_json("rn", @item{"rn"}, "string"); ); if (item?{"df"}) then ( item_dat .= add_json("df", @item{"df"}, "string"); ); if (item?{"fi"}) then ( item_dat .= add_json("fi", @item{"fi"}, "string"); item_dat .= add_json("f", @item{"f"}, "string"); item_dat .= add_json("fc", @item{"fc"}, "string"); ); item_dat = close_json(item_dat); macros_dat .= item_dat . ","; ); ); if (macros_dat ne "[") then ( macros_dat = replace_last(macros_dat, ",", "]"); ) else ( macros_dat .= "]"; ); macros_dat; ));