# # # The util.bak version contains the original report generation subroutines! # # # # # profile_setup - util / utilities used by profile_setup.cfv # # # # is_basic_session_reports_support() # is_page_session_reports_support() # # check_database_fields_integrity() # check_log_fields_integrity() # add_report_fields() # capitalize_field_labels() # # set_report_variable() # set_report_element_variable() # place_report() # add_simple_report_element() # add_nonnumerical_column_to_table() # add_numerical_column_to_table() # add_numerical_column_to_table() # # add_table_report_element() # add_entry_exit_pages_report() # add_session_pages_report() # add_session_users_report() # add_individual_sessions_report() # add_session_reports() # add_log_detail_report() # add_custom_table_report_element() # add_single_page_summary() # # # # # is_basic_session_reports_support() # # Purpose: This checks if basic session reports (none page session reports) are supported # # Parameters: profile: the profile # subroutine(is_basic_session_reports_support(node profile), ( bool show_session_reports = !node_exists(profile . ".not_supported.sessions") or !$(profile . ".not_supported.sessions"); # If the session_visitor_id_field is not defined at all, don't display session information if (!node_exists(profile . ".log.field_options.sessions_visitor_id_field") or (node_value(profile . ".log.field_options.sessions_visitor_id_field") eq "none")) then ( debug_message("Disabling session reports because visitor_id field does not exist\n"); show_session_reports = false; ) # Don't show session reports if the sessions visitor_id field doesn't exist in the database fields list else if (!node_exists(profile . '.database.fields.' . node_value(profile . ".log.field_options.sessions_visitor_id_field"))) then ( debug_message("Disabling session reports because visitor_id field does not exist in db fields\n"); show_session_reports = false; ); # If the session_event_field is not defined at all, don't display session information if (!node_exists(profile . ".log.field_options.sessions_event_field") or (node_value(profile . ".log.field_options.sessions_event_field") eq "none")) then ( debug_message("Disabling session reports because event field does not exist\n"); show_session_reports = false; ) # Don't show session reports if the sessions event field doesn't exist in the database fields list else if (!node_exists(profile . '.database.fields.' . node_value(profile . ".log.field_options.sessions_event_field"))) then ( debug_message("Disabling session reports because event field does not exist in db fields\n"); show_session_reports = false; ); debug_message("6: show_session_reports: $show_session_reports...\n"); show_session_reports; )); # # is_page_session_reports_support() # # Purpose: This checks if page session reports are supported # # Parameters: profile: the profile # subroutine(is_page_session_reports_support(node profile), ( bool show_session_pages_reports = !node_exists(profile . ".not_supported.sessionpages") or !$(profile . ".not_supported.sessionpages"); # If the session_page_field is not defined at all, don't display session information if (!node_exists(profile . ".log.field_options.sessions_page_field") or (node_value(profile . ".log.field_options.sessions_page_field") eq "none")) then ( show_session_pages_reports = false; ) # Don't show session reports if the sessions page field doesn't exist in the database fields list else if (!node_exists(profile . '.database.fields.' . node_value(profile . ".log.field_options.sessions_page_field"))) then ( show_session_pages_reports = false; ); show_session_pages_reports; )); # # check_database_fields_integrity() # # Purpose: This checks database fields and its parameters to be complete before adding any report # # Parameters: profile: the profile # subroutine(check_database_fields_integrity(node profile), ( # Add labels to any database fields that don't have them node dbfield; string dbfield_label; foreach dbfield (profile . ".database.fields") ( if (!(dbfield?{"label"})) then ( if (node_exists("lang_stats.field_labels." . node_name(dbfield))) then ( (dbfield . ".label") = "$lang_stats.field_labels." . node_name(dbfield); debug_message("defaulting dbfield label for " . node_name(dbfield) . " to '" . $(dbfield . ".label") . "'\n"); ) else if (node_exists(profile . ".log.fields." . node_name(dbfield) . ".label")) then ( (dbfield . ".label") = node_value(profile . ".log.fields." . node_name(dbfield) . ".label"); debug_message("getting dbfield label for " . node_name(dbfield) . " from log field label '" . $(dbfield . ".label") . "'\n"); ) else ( if (!node_exists('v.found_undefined_field')) then ( debug_message("####\n"); debug_message("#### WARNING: lang_stats.field_labels." . node_name(dbfield) . " not found\n"); debug_message("#### using node name (" . node_name(dbfield) . ") as label.\n"); debug_message("#### Suggestions for lang_stats entries for this and any other undefined fields:\n"); debug_message("####\n"); v.found_undefined_field = true; ); debug_message(" " . node_name(dbfield) . " = \"" . replace_all(node_name(dbfield), '_', ' ') . "\"\n"); (dbfield . ".label") = capitalize(node_name(dbfield)); ); ); # if there is no log_field specified, assume the log field is the same as the database field if (!subnode_exists(dbfield, "log_field")) then ( (dbfield . ".log_field") = node_name(dbfield); ); # If there is no type field specified, default to "string" if (!subnode_exists(dbfield, "type")) then ( (dbfield . ".type") = "string"; ); # Set default suppress_top and suppress_bottom if (!subnode_exists(dbfield, "suppress_top")) then ( (dbfield . ".suppress_top") = "0"; ); if (!subnode_exists(dbfield, "suppress_bottom")) then ( if (node_name(dbfield) eq "date_time") then ( (dbfield . ".suppress_bottom") = "3"; ) else ( (dbfield . ".suppress_bottom") = "2"; ); ); ); # for database fields )); #### check_database_fields_integrity() #### # # check_log_fields_integrity() # # Purpose: This checks log fields and its parameters to be complete before adding any report # # Parameters: profile: the profile # subroutine(check_log_fields_integrity(node profile), ( # If there is no type specified for a log field, default to "flat" node logfield; foreach logfield (profile . ".log.fields") ( if (!subnode_exists(logfield, "type")) then ( if (node_name(logfield) eq "date") then (logfield . ".type") = "date"; else if (node_name(logfield) eq "time") then (logfield . ".type") = "time"; else (logfield . ".type") = "flat"; ); # Use lang_stats.field_labels for label if none exists if (!subnode_exists(logfield, "label")) then ( if (node_exists("lang_stats.field_labels." . node_name(logfield))) then ( (logfield . ".label") = "$lang_stats.field_labels." . node_name(logfield); ) # If lang_stats.field_labels value doesn't exist, use node name else ( if (!node_exists('v.found_undefined_field')) then ( debug_message("####\n"); debug_message("#### WARNING: lang_stats.field_labels." . node_name(logfield) . " not found\n"); debug_message("#### using node name (" . node_name(logfield) . ") as label.\n"); debug_message("#### Suggestions for lang_stats entries for this and any other undefined fields:\n"); debug_message("####\n"); v.found_undefined_field = true; ); debug_message(" " . node_name(logfield) . " = \"" . replace_all(node_name(logfield), '_', ' ') . "\"\n"); (logfield . ".label") = capitalize(node_name(logfield)); ) ); ); # for log fields )); # # add_report_fields() # # Purpose: This adds the report_fields to the profile # # Parameters: profile: the profile # subroutine(add_report_fields(node profile), ( subroutine(add_predefined_report_fields_group(node profile, string report_field_group_name), ( node report_field_group_node = "lib.profile_setup.report_field_groups." . report_field_group_name; node report_field_item; foreach report_field_item report_field_group_node ( clone_node(report_field_item, profile . ".statistics.report_fields." . node_name(report_field_item)); ); )); node dbfield; string column_label; string dbfield_name; string dbfield_type; string field_path; string report_field_label; string report_field_type; string display_format_type; string log_field_name; string log_field_type; bool is_subitems_level_support; # # Add report_fields # foreach dbfield (profile . ".database.fields") ( dbfield_name = node_name(dbfield); dbfield_type = @dbfield{"type"}; report_field_label = @dbfield{"label"}; # report_field_name = dbfield_name is_subitems_level_support = false; # log_field_type = @(profile . log.fields); # display_format_type = @dbfield{"display_format_type"}; # # check if the db_field supports subitems_level # if (dbfield_type eq "string") then ( if (dbfield?{"log_field"}) then ( log_field_name = @dbfield{"log_field"}; log_field_type = @(profile . ".log.fields." . log_field_name . ".type"); if (log_field_type ne "flat" and log_field_type ne "agent") then ( is_subitems_level_support = true; ); ); ); if (is_subitems_level_support and dbfield_name eq "date_time") then ( add_predefined_report_fields_group(profile, "date_time"); ) else if (is_subitems_level_support and dbfield_name eq "page") then ( add_predefined_report_fields_group(profile, "page"); ) else if (is_subitems_level_support and dbfield_name eq "location") then ( add_predefined_report_fields_group(profile, "location"); ) else ( # # Assemble the report_field here # field_path = profile . ".statistics.report_fields." . dbfield_name; field_path . ".label" = report_field_label; field_path . ".column_label" = ""; field_path . ".column_info" = ""; # GET COLUMN INFO FROM LANG_STATS --> ToDo field_path . ".database_field" = dbfield_name; # Handle type and display format type if (dbfield_name eq "date_time" or dbfield_name eq "day_of_week" or dbfield_name eq "hour_of_day" or dbfield_name eq "day_of_year" or dbfield_name eq "week_of_year") then ( report_field_type = dbfield_name; display_format_type = dbfield_name; ) else ( report_field_type = if (dbfield_type ne "unique") then (dbfield_type) else ("int"); if (dbfield?{"display_format_type"} and (@dbfield{"display_format_type"} ne "")) then ( # fetch the display_format_type as defined in the database field display_format_type = @dbfield{"display_format_type"}; ) else ( if (report_field_type eq "int") then ( display_format_type = "integer"; ) else if (report_field_type eq "float") then ( display_format_type = "float"; ) else ( display_format_type = "string"; ); ); ); field_path . ".type" = report_field_type; field_path . ".display_format_type" = display_format_type; if (is_subitems_level_support) then ( field_path . ".subitems_level" = "-1"; ); ); ); # # Add session fields # if (is_basic_session_reports_support(profile)) then ( add_predefined_report_fields_group(profile, "basic_session_fields"); if (is_page_session_reports_support(profile)) then ( add_predefined_report_fields_group(profile, "page_session_fields"); ); ); )); #### add_report_fields() #### # # capitalize_field_labels() # # Purpose: This capitalizes all field labels (db_fields, log_fields and report_fields) which are based on a language variable. # # Parameters: profile: the profile # subroutine(capitalize_field_labels(node profile), ( subroutine(update_label(node label_node), ( string label = @label_node; if (starts_with(label, "$lang_stats")) then ( string new_label = "{=capitalize(expand(" . replace_first(label, "$lang_stats", "lang_stats") . "))=}"; set_node_value(label_node, new_label); ); )); node item; foreach item (profile . ".log.fields") ( update_label(item{"label"}); ); foreach item (profile . ".database.fields") ( update_label(item{"label"}); ); foreach item (profile . ".statistics.report_fields") ( update_label(item{"label"}); ); )); # # set_report_variable() # # Purpose: This sets a single variable in a report # # Parameters: profile: the profile # report_name: the name of the report # varname: the name of the variable # varvalue: the value to set varname to # subroutine(set_report_variable(node profile, node report, string varname, string varvalue), ( # Get the full report nodename (report . "." . varname) = varvalue; )); #### set_report_variable() #### # # set_report_element_variable() # # Purpose: This sets a single variable in a report element # # Parameters: profile: the profile # report_name: the name of the report (and of the report element) # varname: the name of the variable to set # varvalue: the value to set varname to # #subroutine(set_report_element_variable(node profile, string report_name, string report_element_name, string varname, string varvalue), ( subroutine(set_report_element_variable(node profile, node report_element, string varname, string varvalue), ( # Get the full report nodename # string reports = profile . ".statistics.reports"; # string report = reports . "." . report_name; # string report_element = report . ".report_elements." . report_element_name; (report_element . "." . varname) = varvalue; )); #### set_report_element_variable() #### # # place_report() # # Purpose: This puts a report in the proper group in statistics.reports_menu # # Parameters: profile: the profile # report_name: the name of the report # report_label: the label of the report # report_groups: the report group information to use # reports_menu_label: the label of the report in the reports menu # subroutine(place_report(node profile, string report_name, string report_label, node report_groups, string reports_menu_label), ( # Get the root of the report name (strip off suffix) string report_name_root = report_name; if (ends_with(report_name, "_bottom_level_items")) then ( report_name_root = substr(report_name, 0, length(report_name) - length("_bottom_level_items")); ); # Look through all report groups for a place to put this report bool placed_report; node group; foreach group report_groups ( # Of this report is part of this group, put it there if (node_exists(group . "." . report_name_root)) then ( # If this report is "false" in the group, don't include it in rhe reports_menu if ($(group . "." . report_name_root) ne "false") then ( string group_name = node_name(group); string group_node = profile . ".statistics.reports_menu." . group_name; (group_node . ".type") = "group"; if (!subnode_exists(group_node, "label")) then (group_node . ".label") = "$lang_stats.menu.groups." . group_name; string report_node = group_node . ".items." . report_name; (report_node . ".type") = "view"; (report_node . ".label") = report_label; (report_node . ".view_name") = report_name; ); # if report present placed_report = true; ); # if report is in this group # Check in the "items" node to see if it's there (manual report menu layout) else if (node_exists(group . ".items." . report_name_root)) then ( string group_name = node_name(group); string group_node = profile . ".statistics.reports_menu." . group_name; (group_node . ".type") = "group"; if (!subnode_exists(group_node, "label")) then (group_node . ".label") = "$lang_stats.menu.groups." . group_name; string report_node = group_node . ".items." . report_name; (report_node . ".type") = "view"; (report_node . ".label") = reports_menu_label; (report_node . ".view_name") = report_name; placed_report = true; ); # if report is in this group ); # foreach group # Return whether we placed a report or not placed_report; )); #### place_report() #### # # add_simple_report_element() # # Purpose: This adds a report element to a profile # # Parameters: profile: the profile # report_name: the name of the report # report_label: the label of the report # report_element_name: the name of the report element # report_element_label: the label of the report element # type: the report type # reports_menu_label: the label of the report in the reports menu # subroutine(add_simple_report_element(node profile, string report_name, string report_label, string report_element_name, string report_element_label, string type, string reports_menu_label), ( # Don't place subreports of the single-page summary if ((report_name eq report_element_name) or ((report_name eq "single_page_summary") and (report_element_name eq "overview"))) then ( # Find the report group this belongs in, and add this item to the group if we find one bool found_in_group = false; # If there is a report_groups node in the plug-in, use it node report_groups; bool placed = false; if (node_exists(profile . ".create_profile_wizard_options.report_groups")) then ( placed = place_report(profile, report_name, report_label, profile . ".create_profile_wizard_options.report_groups", reports_menu_label); ); # Otherwise, use the default report groups node if (!placed) then placed = place_report(profile, report_name, report_label, "lib.profile_setup.report_groups", reports_menu_label); # If we didn't find a group to put the report in, put it at the top level if (!placed) then ( string report_node = profile . ".statistics.reports_menu." . report_name; (report_node . ".type") = "view"; (report_node . ".label") = report_label; (report_node . ".view_name") = report_name; ); # if !found_in_group ); # if not single-page summary (profile . ".statistics.reports." . report_name . ".report_elements." . report_element_name) = ""; node report = profile . ".statistics.reports." . report_name; node report_element = report . ".report_elements." . report_element_name; # Set the label of the report set_report_variable(profile, report, "label", report_label); # Set the label of the report element set_report_element_variable(profile, report_element, "label", report_element_label); # Set the type set_report_element_variable(profile, report_element, "type", type); )); #### add_simple_report_element() #### # # add_nonnumerical_column_to_table() # # Purpose: This adds a non-numerical column to a table in a report element # # Parameters: profile: the profile # report_name: the name of the report # report_element: the name of the report element # columnname: the name of the column to add # dbfield: the node of the database field to add a column for # subitems_level: the level to show subitems at; 0 for no value # # Add a non-numerical column to a report element table subroutine(add_nonnumerical_column_to_table(node profile, node report_element, string columnname, string dbfieldname, int subitems_level), ( string columnnode = "columns." . columnname . "."; set_report_element_variable(profile, report_element, columnnode . "type", "string"); set_report_element_variable(profile, report_element, columnnode . "visible", "true"); set_report_element_variable(profile, report_element, columnnode . "field_name", dbfieldname); set_report_element_variable(profile, report_element, columnnode . "data_type", "string"); if (subitems_level != 0) then set_report_element_variable(profile, report_element, columnnode . "subitems_level", subitems_level); string header_label; if (node_exists(profile . ".database.fields." . dbfieldname . ".label")) then header_label = "{=capitalize(database.fields." . dbfieldname . ".label)=}"; else if (node_exists("lang_stats.field_labels." . dbfieldname)) then header_label = "$lang_stats.field_labels." . dbfieldname; else header_label = dbfieldname; string display_format_type_node = profile . ".database.fields." . dbfieldname . ".display_format_type"; string display_format_type; if (node_exists(display_format_type_node)) then display_format_type = $display_format_type_node; else if ((dbfieldname eq "start_time") or (dbfieldname eq "end_time")) then ( display_format_type = "date/time"; header_label = "$lang_stats.individual_sessions." . dbfieldname; ) else display_format_type = "string"; if (dbfieldname eq "user") then header_label = "$lang_stats.individual_sessions." . dbfieldname; set_report_element_variable(profile, report_element, columnnode . "header_label", header_label); set_report_element_variable(profile, report_element, columnnode . "display_format_type", display_format_type); set_report_element_variable(profile, report_element, columnnode . "main_column", "true"); )); #### add_nonnumerical_column_to_table() #### # # add_numerical_column_to_table() # # Purpose: This adds a numerical column to a table in a report element # # Parameters: profile: the profile # report_name: the name of the report # report_element: the name of the report element # columnname: the name of the column to add # dbfield: the name of the database field to add a column for # sort_dbfield: the name of main numerical database field (the default sort field) # add_graph: true if a graph for the main numerical database field should be shown # karl # subroutine(add_numerical_column_to_table(node profile, node report_element, string columnname, string dbfield, string sort_dbfieldname, bool add_graph), ( string columnnode = "columns." . columnname . "."; # Compute the data type and display format type for this column. string data_type; string display_format_type; string numerical_field_name; string header_label; if ((dbfield eq "sessions") or (dbfield eq "events")) then ( data_type = "int"; display_format_type = "integer"; numerical_field_name = dbfield; header_label = "$lang_stats.field_labels." . numerical_field_name; ) else if (dbfield eq "time_spent") then ( data_type = "int"; display_format_type = "duration_compact"; numerical_field_name = dbfield; header_label = "$lang_stats.field_labels." . numerical_field_name; ) else ( data_type = $(dbfield . ".type"); display_format_type = $(dbfield . ".display_format_type"); numerical_field_name = node_name(dbfield); header_label = "{=capitalize(database.fields." . numerical_field_name . ".label)=}"; ); # Set the columns variables set_report_element_variable(profile, report_element, columnnode . "header_label", header_label); set_report_element_variable(profile, report_element, columnnode . "type", "number"); set_report_element_variable(profile, report_element, columnnode . "show_number_column", "true"); set_report_element_variable(profile, report_element, columnnode . "show_percent_column", (numerical_field_name eq sort_dbfieldname)); set_report_element_variable(profile, report_element, columnnode . "show_bar_column", (numerical_field_name eq sort_dbfieldname)); set_report_element_variable(profile, report_element, columnnode . "visible", "true"); set_report_element_variable(profile, report_element, columnnode . "field_name", numerical_field_name); set_report_element_variable(profile, report_element, columnnode . "data_type", data_type); set_report_element_variable(profile, report_element, columnnode . "display_format_type", display_format_type); if (add_graph) then ( set_report_element_variable(profile, report_element, columnnode . "show_graph", "true"); ); )); #### add_numerical_column_to_table() #### # # add_table_report_element() # # Purpose: This adds a standard table report (based on a database field) to a profile. # # Parameters: profile: the profile # report_name: the name of the report to add # report_label: the label of the report to add # report_element_name: the name of the report element to add # report_element_label: the label of the report element to add # dbfieldname: the name of the database field to base the table on # second_column_dbfieldname: name of a dbfield for a second column; "" if none # main_numerical_dbfieldname: the main numerical database field # sort_dbfield: the name of main numerical database field (the default sort field) # sort_direction: the direction of sorting # only_bottom_level_items: true of the table should show bottom-level items only (false for hierarchical) # subroutine(add_table_report_element(node profile, string report_name, string report_label, string report_element_name, string report_element_label, string dbfieldname, string second_column_dbfieldname, string main_numerical_dbfieldname, string sort_dbfieldname, string sort_direction, bool only_bottom_level_items), ( add_simple_report_element(profile, report_name, report_label, report_element_name, report_element_label, "table", report_label); # Get the full report nodename node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_element_name; # Set the general variables set_report_element_variable(profile, report_element, "database_field_name", dbfieldname); set_report_element_variable(profile, report_element, "sort_by", sort_dbfieldname); set_report_element_variable(profile, report_element, "sort_direction", sort_direction); set_report_element_variable(profile, report_element, "show_omitted_items_row", "true"); set_report_element_variable(profile, report_element, "omit_parenthesized_items", "true"); set_report_element_variable(profile, report_element, "show_totals_row", "true"); set_report_element_variable(profile, report_element, "starting_row", 1); # Set ending_row based on the report type if (report_element_name eq "day_of_week") then set_report_element_variable(profile, report_element, "ending_row", 7); else if (report_element_name eq "hour_of_day") then set_report_element_variable(profile, report_element, "ending_row", 24); else set_report_element_variable(profile, report_element, "ending_row", 10); # set_report_element_variable(profile, report_element, "only_bottom_level_items", only_bottom_level_items); # Turn on graphing, if appropriate bool show_graph = ((dbfieldname eq "date_time") or (dbfieldname eq "day_of_week") or (dbfieldname eq "hour_of_day")); # Since version 7.0.11 "show_graph = true" needs to be added into the report elements columns node, # the same way as i.e. show_bar_column = true # set_report_element_variable(profile, report_element, "show_graph", show_graph); # if (show_graph) then ( # set_report_element_variable(profile, report_element, "graph.numerical_fields." . main_numerical_dbfieldname, true); # ); # Add the non-numerical column int columnnum = 0; int subitems_level = (if (only_bottom_level_items) then -1 else 0); add_nonnumerical_column_to_table(profile, report_element, columnnum, dbfieldname, subitems_level); columnnum++; # Add the second non-numerical column, if any if (second_column_dbfieldname ne "") then ( # Add the column add_nonnumerical_column_to_table(profile, report_element, columnnum, second_column_dbfieldname, subitems_level); columnnum++; # Add the subtable options set_report_element_variable(profile, report_element, "sub_table.ending_row", 10); set_report_element_variable(profile, report_element, "sub_table.omit_parenthesized_items", true); set_report_element_variable(profile, report_element, "sub_table.show_omitted_items_row", true); set_report_element_variable(profile, report_element, "sub_table.show_averages_row", false); set_report_element_variable(profile, report_element, "sub_table.show_totals_row", true); ); # if second column debug_message("Adding numerical columns to '" . report_element . "'\n"); # Add all numerical columns bool add_graph; node dbfield; foreach dbfield (profile . ".database.fields") ( if (node_value(subnode_by_name(dbfield, "type")) ne "string") then ( # If this field is in the field associations list for the main database field, # or if there is no field associations list, include it in the table. if (!node_exists(profile . '.create_profile_wizard_options.database_field_associations.' . dbfieldname) or node_exists(profile . '.create_profile_wizard_options.database_field_associations.' . dbfieldname . '.' . node_name(dbfield))) then ( add_graph = false; # debug_message("@@@@ @@@@ dbfield: " . node_name(dbfield) . "\n"); # debug_message("@@@@ @@@@ main_numerical_dbfieldname: " . main_numerical_dbfieldname . "\n\n"); debug_message(" Adding numerical column '" . node_name(dbfield) . "'\n"); if (show_graph and (node_name(dbfield) eq main_numerical_dbfieldname)) then (add_graph = true;); add_numerical_column_to_table(profile, report_element, columnnum, dbfield, sort_dbfieldname, add_graph); columnnum++; ); # if field associated else ( debug_message(" Not adding column '" . node_name(dbfield) . "' (not in field associations)\n"); # If this is the sort field, and it's not being put in the table, then we need to sort by something else; # use the first field if (node_name(dbfield) eq sort_dbfieldname) then ( debug_message(" ... Uh oh, that's the default sort field; we need to find another field to sort on.\n"); sort_dbfieldname = node_name(subnode_by_number(profile . '.create_profile_wizard_options.database_field_associations.' . dbfieldname, 0)); set_report_element_variable(profile, report_element, "sort_by", sort_dbfieldname); debug_message(" ... sorting on '" . sort_dbfieldname . "'\n"); ); # if sort field ); # if field not associated ); # if numerical ); # for dbfields )); #### add_table_report_element() #### # # add_entry_exit_pages_report() # # Purpose: This adds an entry_pages or exit_pages report to a profile # # Parameters: profile: the profile # report_name: "entry_pages" or "exit_pages" # subroutine(add_entry_exit_pages_report(node profile, string report_name), ( string report_label = "$lang_stats." . report_name . ".label"; add_simple_report_element(profile, report_name, report_label, report_name, report_label, report_name, report_label); # Get the full report nodename string reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_name; set_report_element_variable(profile, report_element, "sort_by", "sessions"); set_report_element_variable(profile, report_element, "sort_direction", "descending"); set_report_element_variable(profile, report_element, "show_omitted_items_row", "true"); set_report_element_variable(profile, report_element, "show_totals_row", "true"); set_report_element_variable(profile, report_element, "show_graph", "false"); # Add the table columns column add_nonnumerical_column_to_table(profile, report_element, 0, "page", 0); add_numerical_column_to_table(profile, report_element, 1, "sessions", "sessions", false); )); #### add_entry_exit_pages_report() #### # # add_session_pages_report() # # Purpose: This adds a session_pages report to a profile # # Parameters: profile: the profile to add the report to # subroutine(add_session_pages_report(node profile), ( string report_name = "session_pages"; string report_label = "$lang_stats." . report_name . ".label"; add_simple_report_element(profile, report_name, report_label, report_name, report_label, report_name, report_label); # Get the full report nodename node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_name; set_report_element_variable(profile, report_element, "sort_by", "sessions"); set_report_element_variable(profile, report_element, "sort_direction", "descending"); set_report_element_variable(profile, report_element, "show_omitted_items_row", "true"); set_report_element_variable(profile, report_element, "show_totals_row", "true"); set_report_element_variable(profile, report_element, "show_graph", "false"); # Add the table columns column add_nonnumerical_column_to_table(profile, report_element, 0, "page", 0); add_numerical_column_to_table(profile, report_element, 1, "sessions", "sessions", false); add_numerical_column_to_table(profile, report_element, 2, "events", "events", false); add_numerical_column_to_table(profile, report_element, 3, "time_spent", "time_spent", false); )); #### add_session_pages_report() #### # # add_session_users_report() # # Purpose: This adds a session_users report to a profile # # Parameters: profile: the profile to add the report to # subroutine(add_session_users_report(node profile), ( string report_name = "session_users"; string report_label = "$lang_stats." . report_name . ".label"; add_simple_report_element(profile, report_name, report_label, report_name, report_label, report_name, report_label); # Get the full report nodename node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_name; set_report_element_variable(profile, report_element, "sort_by", "sessions"); set_report_element_variable(profile, report_element, "sort_direction", "descending"); set_report_element_variable(profile, report_element, "show_omitted_items_row", "true"); set_report_element_variable(profile, report_element, "show_totals_row", "true"); set_report_element_variable(profile, report_element, "show_graph", "false"); # Add the table columns column add_nonnumerical_column_to_table(profile, report_element, 0, "user", 0); add_numerical_column_to_table(profile, report_element, 1, "sessions", "sessions", false); add_numerical_column_to_table(profile, report_element, 2, "events", "events", false); add_numerical_column_to_table(profile, report_element, 3, "time_spent", "time_spent", false); )); #### add_session_users_report() #### # # add_individual_sessions_report() # # Purpose: This adds an individual_sessions report to a profile # # Parameters: profile: the profile to add the report to # subroutine(add_individual_sessions_report(node profile), ( string report_name = "individual_sessions"; string report_label = "$lang_stats." . report_name . ".label"; add_simple_report_element(profile, report_name, report_label, report_name, report_label, report_name, report_label); # Get the full report nodename node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_name; set_report_element_variable(profile, report_element, "sort_by", "events"); set_report_element_variable(profile, report_element, "sort_direction", "descending"); set_report_element_variable(profile, report_element, "show_omitted_items_row", "true"); set_report_element_variable(profile, report_element, "show_totals_row", "true"); set_report_element_variable(profile, report_element, "show_graph", "false"); # Add the table columns column add_nonnumerical_column_to_table(profile, report_element, 0, "session_id", 0); add_nonnumerical_column_to_table(profile, report_element, 1, "user", 0); add_numerical_column_to_table(profile, report_element, 2, "events", "events", false); add_nonnumerical_column_to_table(profile, report_element, 3, "start_time", 0); add_nonnumerical_column_to_table(profile, report_element, 4, "end_time", 0); add_numerical_column_to_table(profile, report_element, 5, "time_spent", "time_spent", false); )); #### add_individual_sessions_report() #### # # add_session_reports() # # Purpose: This adds all the standard session reports to a profile # # Parameters: profile: the profile to add the reports to # subroutine(add_session_reports(node profile), ( # We already checked the report fields for session report support, so we only need to check if the report fields exists to # determine if session reports are supported. bool show_session_reports = if (?(profile . ".statistics.report_fields._session_id")) then (true) else (false); bool show_session_pages_reports = if (show_session_reports and ?(profile . ".statistics.report_fields._session_page")) then (true) else (false); if (show_session_reports) then ( string report_label = "$lang_stats.sessions_overview.label"; add_simple_report_element(profile, "sessions_overview", report_label, "sessions_overview", report_label, "sessions_overview", report_label); if (show_session_pages_reports) then ( add_entry_exit_pages_report(profile, "entry_pages"); add_entry_exit_pages_report(profile, "exit_pages"); add_simple_report_element(profile, "session_page_paths", "$lang_stats.session_page_paths.label", "session_page_paths", "$lang_stats.session_page_paths.label", "session_page_paths", report_label); add_simple_report_element(profile, "session_paths", "$lang_stats.session_paths.label", "session_paths", "$lang_stats.session_paths.label", "session_paths", report_label); add_session_pages_report(profile); ); add_session_users_report(profile); add_individual_sessions_report(profile); ); # if show session report )); #### add_session_reports() #### # # add_log_detail_report() # # Purpose: This adds a log_detail report to a profile # # Parameters: profile: the profile to add the report to # subroutine(add_log_detail_report(node profile), ( string report_name = "log_detail"; string report_label = "$lang_stats." . report_name . ".label"; add_simple_report_element(profile, report_name, report_label, report_name, report_label, report_name, report_label); # Get the full report nodename node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_name; set_report_element_variable(profile, report_element, "sort_by", ""); set_report_element_variable(profile, report_element, "sort_direction", "descending"); set_report_element_variable(profile, report_element, "show_omitted_items_row", "false"); set_report_element_variable(profile, report_element, "show_totals_row", "false"); set_report_element_variable(profile, report_element, "starting_row", 0); set_report_element_variable(profile, report_element, "ending_row", 50); set_report_element_variable(profile, report_element, "show_graph", "false"); # Add database fields as columns node dbfield; foreach dbfield (profile . ".database.fields") ( string dbfieldname = node_name(dbfield); # If this is a numerical field, add it if ((node_value(subnode_by_name(dbfield, "type")) eq "int") or (node_value(subnode_by_name(dbfield, "type")) eq "float")) then ( # Don't add a column for the entries field if (node_exists(dbfield . ".entries_field") and ($(dbfield . ".entries_field"))) then ( ) else ( add_numerical_column_to_table(profile, report_element, dbfieldname, dbfield, "", false); ) ) # if numerical # If this is a non-numerical field, add it else if (node_value(subnode_by_name(dbfield, "type")) eq "string") then ( add_nonnumerical_column_to_table(profile, report_element, dbfieldname, node_name(dbfield), 0); ); # If the log field exists for this database field, and it's derived, hide it, # unless it's date_time (derived from date and time). string log_field_name = if (subnode_exists(dbfield, "log_field")) then node_value(subnode_by_name(dbfield, "log_field")) else node_name(dbfield); if (node_exists(profile . ".log.fields." . log_field_name)) then ( node logfield = profile . ".log.fields." . log_field_name; if ((log_field_name ne "date_time") and node_exists(logfield . ".derived_from_1")) then ( (report_element . ".columns." . dbfieldname . ".visible") = false; ); ) ); # for dbfields )); #### add_log_detail_report() #### # # add_custom_table_report_element() # # Purpose: This adds a custom table report (based on a plug-in report group node) to a profile. # # Parameters: profile: the profile # description: the node describing the report # sort_dbfield: the name of main numerical database field (the default sort field) # subroutine(add_custom_table_report_element(node profile, node description, string sort_dbfieldname), ( string report_name = node_name(description); string report_element_name = report_name; # If this is an entry or exit pages report, add it here if ((report_name eq "entry_pages") or (report_name eq "exit_pages")) then add_entry_exit_pages_report(profile, report_name); # If this is an entry or exit pages report, add it here else if (report_name eq "session_pages") then ( add_session_pages_report(profile); ); # If this is a session_users report, add it here else if (report_name eq "session_users") then ( add_session_users_report(profile); ); # If this is a individual_sessions report, add it here else if (report_name eq "individual_sessions") then ( add_individual_sessions_report(profile); ); # If it's a normal table report, add it. else ( string report_label; if (subnode_exists(description, 'label')) then report_label = node_value(subnode_by_name(description, 'label')); else if (subnode_exists(profile . ".database.fields", report_name)) then report_label = "{=capitalize(pluralize(print(database.fields." . report_name . ".label)))=}"; else if (subnode_exists('lang_stats.menu.reports', report_name)) then report_label = '$lang_stats.menu.reports.' . report_name; else if (subnode_exists('lang_stats.field_labels', report_name)) then report_label = '$lang_stats.field_labels.' . report_name; else report_label = report_name; string report_element_label = report_label; # Get the label for the menu string reports_menu_label; if (subnode_exists(description, 'reports_menu_label')) then reports_menu_label = node_value(subnode_by_name(description, 'reports_menu_label')); else reports_menu_label = report_label; debug_message("Adding custom report $report_name: '$report_label'\n"); # Get the type of the report; default to table string report_type = "table"; if (subnode_exists(description, "type")) then report_type = node_value(subnode_by_name(description, "type")); add_simple_report_element(profile, report_name, report_label, report_element_name, report_element_label, report_type, reports_menu_label); # Get the full report element nodename node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_element_name; # Add a filter if one was specified if (subnode_exists(description, 'filter')) then ( string filter = node_value(subnode_by_name(description, 'filter')); set_report_element_variable(profile, report_element, "filter.expression", filter); ); # If this is a table report, set it up. if (report_type eq "table") then ( # Default to descending sort string sort_direction = "descending"; # Set the general variables set_report_element_variable(profile, report_element, "sort_direction", sort_direction); set_report_element_variable(profile, report_element, "show_omitted_items_row", "true"); set_report_element_variable(profile, report_element, "omit_parenthesized_items", "true"); set_report_element_variable(profile, report_element, "show_totals_row", "true"); set_report_element_variable(profile, report_element, "starting_row", 1); # Set ending_row based on the report type if (report_element_name eq "day_of_week") then set_report_element_variable(profile, report_element, "ending_row", 7); else if (report_element_name eq "hour_of_day") then set_report_element_variable(profile, report_element, "ending_row", 24); else set_report_element_variable(profile, report_element, "ending_row", 10); # Default to only bottom-level items bool only_bottom_level_items = !subnode_exists(description, 'reports_menu_label') or node_value(subnode_by_name(description, 'reports_menu_label')); set_report_element_variable(profile, report_element, "only_bottom_level_items", only_bottom_level_items); # Add the non-numerical columns; use the columns node if it exists bool found_numerical_field = false; bool found_sort_field = false; string first_numerical_field_found; bool add_graph = false; int columnnum = 0; string database_field_name = "undefined"; if (subnode_exists(description, 'columns')) then ( node column; node columns = subnode_by_name(description, 'columns'); foreach column columns ( string dbfieldname = node_value(subnode_by_name(column, 'field_name')); string dbfieldnodename = profile . ".database.fields." . dbfieldname; if (node_exists(dbfieldnodename)) then ( node dbfield = dbfieldnodename; if (node_value(subnode_by_name(dbfield, 'type')) ne 'string') then ( if (!found_numerical_field) then first_numerical_field_found = dbfieldname; found_numerical_field = true; if (dbfieldname eq sort_dbfieldname) then found_sort_field = true; ); ); # if dbfield exists ); # for columns if (!found_sort_field) then sort_dbfieldname = first_numerical_field_found; int subitems_level = (if (only_bottom_level_items) then -1 else 0); # Add the non-numerical columns bool add_graph; foreach column columns ( string dbfieldname = node_value(subnode_by_name(column, 'field_name')); string dbfieldnodename = profile . ".database.fields." . dbfieldname; if (node_exists(dbfieldnodename)) then ( node dbfield = profile . ".database.fields." . dbfieldname; if (columnnum == 0) then ( set_report_element_variable(profile, report_element, "database_field_name", dbfieldname); database_field_name = dbfieldname; ); if (node_value(subnode_by_name(dbfield, 'type')) eq 'string') then add_nonnumerical_column_to_table(profile, report_element, columnnum, dbfieldname, subitems_level); else ( # If graph_field is specified in the description, and it's this field, show a graph add_graph = (subnode_exists(description, "graph_field") and (node_value(subnode_by_name(description, "graph_field")) eq node_name(dbfield))); add_numerical_column_to_table(profile, report_element, columnnum, dbfield, sort_dbfieldname, add_graph); ); # Put in any custom values specified in the column node node column_parameter; foreach column_parameter column ( (report_element . '.columns.' . columnnum . '.' . node_name(column_parameter)) = node_value(column_parameter); ); # Go to next column columnnum++; ); # if dbfield exists ); # for columns ); # if columns node exists # If there is no columns node, add just one non-numerical field else ( if (subnode_exists(description, 'database_field_name')) then database_field_name = node_value(subnode_by_name(description, 'database_field_name')); else if (node_exists(profile . '.database.fields.' . report_name)) then ( database_field_name = node_name(subnode_by_name(profile . ".database.fields", report_name)); ) else ( error("Cannot determine database_field_name for table report " . report_name . "\n"); ); # dbfieldname = database_field_name; set_report_element_variable(profile, report_element, "database_field_name", database_field_name); add_nonnumerical_column_to_table(profile, report_element, columnnum, database_field_name, subitems_level); columnnum++; ); # if no columns node # Sort by the main sort field, or by the first numerical field if the main field isn't in this table set_report_element_variable(profile, report_element, "sort_by", sort_dbfieldname); # Use subtable format if requested if (subnode_exists(description, 'subtable') and node_value(subnode_by_name(description, 'subtable'))) then ( # Add the subtable options set_report_element_variable(profile, report_element, "sub_table.ending_row", 10); set_report_element_variable(profile, report_element, "sub_table.omit_parenthesized_items", true); set_report_element_variable(profile, report_element, "sub_table.show_omitted_items_row", true); set_report_element_variable(profile, report_element, "sub_table.show_averages_row", false); set_report_element_variable(profile, report_element, "sub_table.show_totals_row", true); ); # if subtable # If no numerical fields were listed in the report, add all numerical columns if (!found_numerical_field) then ( bool add_graph; node dbfield; foreach dbfield (profile . ".database.fields") ( if (node_value(subnode_by_name(dbfield, "type")) ne "string") then ( # If this field is in the field associations list for the main database field, # or if there is no field associations list, include it in the table. if (!node_exists(profile . '.create_profile_wizard_options.database_field_associations.' . database_field_name) or node_exists(profile . '.create_profile_wizard_options.database_field_associations.' . database_field_name . '.' . node_name(dbfield))) then ( # If graph_field is specified in the description, and it's this field, show a graph add_graph = (subnode_exists(description, "graph_field") and (node_value(subnode_by_name(description, "graph_field")) eq node_name(dbfield))); debug_message("adding column '" . node_name(dbfield) . "' to '" . report_element . "'\n"); add_numerical_column_to_table(profile, report_element, columnnum, dbfield, sort_dbfieldname, add_graph); columnnum++; ); # if field associated else ( debug_message("NOT adding column '" . node_name(dbfield) . "' to '" . report_element . "'\n"); # If this is the sort field, and it's not being put in the table, then we need to sort by something else; # use the first field if (node_name(dbfield) eq sort_dbfieldname) then ( debug_message(" ... Uh oh, that's the default sort field; we need to find another field to sort on.\n"); sort_dbfieldname = node_name(subnode_by_number(profile . '.create_profile_wizard_options.database_field_associations.' . database_field_name, 0)); set_report_element_variable(profile, report_element, "sort_by", sort_dbfieldname); debug_message(" ... sorting on '" . sort_dbfieldname . "'\n"); ); # if sort field ); # if field not associated ); # if numerical ); # for dbfields ); # if no numerical fields listed ); # if table report ); # if normal table report # Copy the description parameter values to the report node description_parameter; node reports = profile . ".statistics.reports"; node report = reports . "." . report_name; node report_element = report . ".report_elements." . report_element_name; foreach description_parameter description ( string description_parameter_name = node_name(description_parameter); if ((node_name(description_parameter) ne "columns") and (node_name(description_parameter) ne "filter") and (node_name(description_parameter) ne "graph_field")) then ( # string description_parameter_value = node_value(description_parameter); string report_element_parameter_nodepath = report_element . "." . node_name(description_parameter); clone_node(description_parameter, report_element_parameter_nodepath); # set_subnode_value(report_element, description_parameter_name, description_parameter_value); debug_message(" Set parameter " . description_parameter_name . "=" . node_as_string(description_parameter) . "\n"); ); ); # foreach description_parameter )); #### add_custom_table_report_element() #### # # add_single_page_summary() # # Purpose: This adds a single page summary report to a profile # # Parameters: profile: the profile to add the report to # subroutine(add_single_page_summary(node profile), ( string report_name = "single_page_summary"; # Add the single-page summary report and overview string report_label = "$lang_stats.single_page_summary.label"; string report_element_label = "$lang_stats.overview.label"; add_simple_report_element(profile, report_name, report_label, "overview", report_element_label, "overview", report_label); node reports = profile . ".statistics.reports"; node report; foreach report (reports) ( string report_name = node_name(report); if (report_name ne "single_page_summary") then ( node report_elements = subnode_by_name(report, 'report_elements'); node report_element = subnode_by_number(report_elements, 0); string report_element_type = node_value(subnode_by_name(report_element, 'type')); if ((report_element_type eq 'session_paths') or (report_element_type eq 'session_page_paths') or (report_element_type eq 'individual_sessions') or (report_element_type eq 'log_detail')) then () else ( string report_element_name = node_name(report_element); string sss_report_element_path = reports . ".single_page_summary.report_elements." . report_element_name; clone_node(report_element, sss_report_element_path); (sss_report_element_path . ".show_header_bar") = true; # debug_message("Cloned report '" . report_element_name . "' to single-page summary\n"); # debug_message("Cloned report: " . node_as_string(report_element) . "\n"); ); ); ); #debug_message("Now single-page summary: " . node_as_string(reports . ".single_page_summary") . "\n"); )); #### add_single_page_summary() ####