Index: openacs-4/packages/assessment/tcl/as-list-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/assessment/tcl/as-list-procs.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/packages/assessment/tcl/as-list-procs.tcl 7 Oct 2007 22:36:54 -0000 1.5 +++ openacs-4/packages/assessment/tcl/as-list-procs.tcl 29 Aug 2008 18:58:14 -0000 1.6 @@ -11,320 +11,7 @@ } namespace eval as::list { - - ad_proc -public filters { - -assessments - } { - Generate filters per question - - @author Roel Canicula (roel@solutiongrove.com) - @creation-date 2006-05-11 - - @param assessment_ids List of lists of title, assessment_id pairs - - @return - - @error - } { - - set assessment_search_options [list] - set search_js_array "" - set list_filters [list] - - foreach param [params] { - upvar $param $param - } - - foreach assessment $assessments { - set option_assessment_title [lindex $assessment 0] - set option_assessment_id [lindex $assessment 1] - lappend assessment_ids $option_assessment_id - } - - - # we just want the questions that are in all the assessments we received - if {[llength $assessments] > 1} { - set multiple_assessment_where "where exists (select null from (select m.assessment_id, m.section_id from as_assessment_section_map m where m.assessment_id in ([template::util::tcl_to_sql_list $assessment_ids])) s2 where s1.section_id=s2.section_id and s1.assessment_id <> s2.assessment_id)" - } else { - set multiple_assessment_where "" - } - set section_ids [db_list section_ids "select distinct section_id from (select m.assessment_id, m.section_id from as_assessment_section_map m where m.assessment_id in ([template::util::tcl_to_sql_list $assessment_ids])) s1 $multiple_assessment_where"] - if {![llength $section_ids]} { - # no sections are common to all assessments - return [list list_filters {} assessment_search_options {} search_js_array {}] - } - # don't query the same item more than one - array set visited_items [list] - foreach section [db_list_of_lists sections " - select cr.title as option_section_title, s.section_id as option_section_id - from as_sections s, cr_revisions cr, cr_items ci --, as_assessment_section_map asm - where ci.item_id = cr.item_id - and cr.revision_id = s.section_id - and s.section_id in ([template::util::tcl_to_sql_list $section_ids]) - "] { - set option_section_title [lindex $section 0] - set option_section_id [lindex $section 1] - db_foreach items { - select ci.item_id as option_item_id, cr.title as option_item_title, ir.revision_id as option_revision_id - - from as_items i, cr_revisions cr, cr_items ci, as_item_section_map ism, cr_revisions ir - - where ci.item_id = cr.item_id - and ir.revision_id = ci.latest_revision - and cr.revision_id = i.as_item_id - and i.as_item_id = ism.as_item_id - and ism.section_id = :option_section_id - - order by ism.sort_order - } { - if {![info exists visited_items($option_item_id)]} { - set visited_items($option_item_id) $option_item_id - if { ! [exists_and_not_null assessment_id] } { - lappend assessment_search_options [list "...... $option_item_title" $option_item_id] - } else { - lappend assessment_search_options [list "... $option_item_title" $option_item_id] - } - - set one_item_type [db_string get_item_type { - select oi.object_type - from cr_items i, as_item_rels it, as_item_rels dt, acs_objects oi - where dt.item_rev_id = it.item_rev_id - and it.rel_type = 'as_item_type_rel' - and dt.rel_type = 'as_item_display_rel' - and oi.object_id = it.target_rev_id - and i.latest_revision = it.item_rev_id - and i.item_id = :option_item_id - }] - - set one_item_choices [db_list_of_lists item_choices { - select r.title, c.choice_id - - from cr_revisions r, as_item_choices c - left outer join cr_revisions r2 on (c.content_value = r2.revision_id) - - where r.revision_id = c.choice_id - and c.mc_id = (select max(t.as_item_type_id) - from as_item_type_mc t, cr_revisions c, as_item_rels r - where t.as_item_type_id = r.target_rev_id - and r.item_rev_id = :option_revision_id - and r.rel_type = 'as_item_type_rel' - and c.revision_id = t.as_item_type_id - group by c.title, t.increasing_p, t.allow_negative_p, - t.num_correct_answers, t.num_answers) - - order by c.sort_order - }] - - append search_js_array "searchItems\['$option_item_id'\] = '$one_item_type'\n" - ##### - - if { $one_item_type eq "as_item_type_mc" } { - set values $one_item_choices - set search_clause [subst { - exists (select 1 - from as_item_data_choices dc - where dd.item_data_id = dc.item_data_id - and dc.choice_id = :as_item_id_$option_item_id) - }] - } else { - set values ""; #[set as_item_id_$option_item_id] - set search_clause "lower(dd.text_answer) like '%'||lower(:as_item_id_$option_item_id)||'%' " - } - - lappend list_filters "as_item_id_$option_item_id" \ - [list \ - label $option_item_title \ - values $values \ - where_clause [subst { - (:as_item_id_$option_item_id is null - or - exists (select 1 - from as_items ii, as_item_data dd, - (select oi.object_type, it.item_rev_id as as_item_id - from as_item_rels it, as_item_rels dt, acs_objects oi - where dt.item_rev_id = it.item_rev_id - and it.rel_type = 'as_item_type_rel' - and dt.rel_type = 'as_item_display_rel' - and oi.object_id = it.target_rev_id) tt, - cr_items ci - - where ci.item_id = $option_item_id - and ii.as_item_id = dd.as_item_id - and ii.as_item_id = tt.as_item_id - and dd.session_id = m.session_id - and ii.as_item_id = ci.latest_revision - and $search_clause - )) - }]] - } - } - } - return [list list_filters $list_filters assessment_search_options $assessment_search_options search_js_array $search_js_array] - } - - - ad_proc -public filters_old { - -assessment_id - } { - Generate filters per question - - @author Roel Canicula (roel@solutiongrove.com) - @creation-date 2006-05-11 - - @param assessment_id - - @return - - @error - } { - set assessment_search_options [list] - set search_js_array "" - set list_filters [list] - - foreach param [params] { - upvar $param $param - } - - if { [exists_and_not_null assessment_id] } { - set as_clause { and a.assessment_id = :assessment_id } - } else { - set as_clause "" - } - - set assessments [db_list_of_lists assessments [subst { - select distinct a.title, a.assessment_id - from dotlrn_ecommerce_section s, dotlrn_catalogi c, as_assessmentsi a, cr_items i - where s.course_id = c.item_id - and c.assessment_id = a.item_id - and a.assessment_id = i.latest_revision - $as_clause - }]] - - foreach assessment $assessments { - set option_assessment_title [lindex $assessment 0] - set option_assessment_id [lindex $assessment 1] - if { ! [exists_and_not_null assessment_id] } { - lappend assessment_search_options [list "ASSESSMENT: $option_assessment_title" "$option_assessment_id"] - } - append search_js_array "searchItems\['$option_assessment_id'\] = 'assessment'\n" - - foreach section [db_list_of_lists sections { - select cr.title as option_section_title, s.section_id as option_section_id - from as_sections s, cr_revisions cr, cr_items ci, as_assessment_section_map asm - where ci.item_id = cr.item_id - and cr.revision_id = s.section_id - and s.section_id = asm.section_id - and asm.assessment_id = :option_assessment_id - order by asm.sort_order - }] { - set option_section_title [lindex $section 0] - set option_section_id [lindex $section 1] - if { ! [exists_and_not_null assessment_id] } { - lappend assessment_search_options [list "... SECTION: $option_section_title" "$option_section_id"] - } else { - lappend assessment_search_options [list "SECTION: $option_section_title" "$option_section_id"] - } - append search_js_array "searchItems\['$option_section_id'\] = 'section'\n" - - db_foreach items { - select ci.item_id as option_item_id, cr.title as option_item_title, cr.revision_id as option_revision_id - - from as_items i, cr_revisions cr, cr_items ci, as_item_section_map ism, cr_revisions asr - - where ci.item_id = cr.item_id - and cr.revision_id = i.as_item_id - and i.as_item_id = ism.as_item_id - and ism.section_id = :option_section_id - and asr.revision_id = i.as_item_id - - order by ism.sort_order - } { - if { ! [exists_and_not_null assessment_id] } { - lappend assessment_search_options [list "...... $option_item_title" $option_item_id] - } else { - lappend assessment_search_options [list "... $option_item_title" $option_item_id] - } - - set one_item_type [db_string get_item_type { - select oi.object_type - from cr_items i, as_item_rels it, as_item_rels dt, acs_objects oi - where dt.item_rev_id = it.item_rev_id - and it.rel_type = 'as_item_type_rel' - and dt.rel_type = 'as_item_display_rel' - and oi.object_id = it.target_rev_id - and i.latest_revision = it.item_rev_id - and i.item_id = :option_item_id - }] - - set one_item_choices [db_list_of_lists item_choices { - select r.title, c.choice_id - - from cr_revisions r, as_item_choices c - left outer join cr_revisions r2 on (c.content_value = r2.revision_id) - - where r.revision_id = c.choice_id - and c.mc_id = (select max(t.as_item_type_id) - from as_item_type_mc t, cr_revisions c, as_item_rels r - where t.as_item_type_id = r.target_rev_id - and r.item_rev_id = :option_revision_id - and r.rel_type = 'as_item_type_rel' - and c.revision_id = t.as_item_type_id - group by c.title, t.increasing_p, t.allow_negative_p, - t.num_correct_answers, t.num_answers) - - order by c.sort_order - }] - - append search_js_array "searchItems\['$option_item_id'\] = '$one_item_type'\n" - - if { [lsearch [as::list::as_items] $option_item_id] != -1 } { - if { $one_item_type eq "as_item_type_mc" } { - set values $one_item_choices - set search_clause [subst { - exists (select 1 - from as_item_data_choices dc - where dd.item_data_id = dc.item_data_id - and dc.choice_id = :as_item_id_$option_item_id) - }] - } else { - set values [set as_item_id_$option_item_id] - set search_clause "lower(dd.text_answer) like '%'||lower(:as_item_id_$option_item_id)||'%' " - } - - lappend list_filters "as_item_id_$option_item_id" \ - [list \ - label $option_item_title \ - values $values \ - where_clause [subst { - (:as_item_id_$option_item_id is null - or - exists (select 1 - from as_items ii, as_item_data dd, - (select oi.object_type, it.item_rev_id as as_item_id - from as_item_rels it, as_item_rels dt, acs_objects oi - where dt.item_rev_id = it.item_rev_id - and it.rel_type = 'as_item_type_rel' - and dt.rel_type = 'as_item_display_rel' - and oi.object_id = it.target_rev_id) tt, - cr_items ci - - where ci.item_id = $option_item_id - and ii.as_item_id = dd.as_item_id - and ii.as_item_id = tt.as_item_id - and dd.session_id = m.session_id - and ii.as_item_id = ci.latest_revision - and $search_clause - )) - }]] - } - } - } - } - - return [list list_filters $list_filters assessment_search_options $assessment_search_options search_js_array $search_js_array] - } - ad_proc -public params { } { Check form vars for assessment item submits @@ -344,7 +31,7 @@ foreach param [array names formarr] { if { [regexp -nocase {^as_item_id_(\d+)$} $param match one_item_id] } { - lappend paramlist $param + lappend paramlist ${param}:multiple } } } @@ -376,4 +63,326 @@ } return $as_item_ids } +} + + +ad_proc as::list::set_elements_property { + {-list_name:required} + {-element_names:required} + {-property:required} + {-value:required} +} { + Sets a property on multiple list elements + + @param list_name Name of the list + @param element_names List of element names + @param property Which property to set + @param value Value to set, all elements in element_names get this value + +} { + foreach name $element_names { + template::element::set_property \ + -list_name $list_name \ + -element_name $name \ + -property $property \ + -value $value + } +} + +ad_proc as::list::add_columns { + {-assessment_ids:required} + {-list_name:required} + {-show_columns {}} + {-element_select 1} + {-element_from 1} +} { + Add columns to the list for assessment questions + All columns will be hidden + + @param assessment_ids List of IDs of the assessments to get the items from + +} { + set elements [list] + + set multirow __as_list_$list_name + as::list::get_items_multirow \ + -assessment_ids $assessment_ids \ + -multirow $multirow + + # don't query the same item more than one + array set visited_items [list] + template::multirow foreach $multirow { + if {![info exists visited_items($item_id)] && $as_item_id == $latest_revision} { + set visited_items($item_id) $item_id + set title "[regsub -all {<.*?>} $title {}]" + lappend elements \ + as_item_id_$item_id [as::list::column_element_spec \ + -as_item_id $as_item_id \ + -cr_item_id $item_id \ + -item_title $title \ + -hide_p [expr {[lsearch $show_columns as_item_id_$item_id] < 0}] \ + -element_select $element_select \ + -element_from $element_from] + } + } + return $elements +} + +ad_proc as::list::column_element_spec { + -as_item_id + -item_title + -cr_item_id + {-hide_p 0} + {-element_select 1} + {-element_from 1} +} { + set item_type [db_string get_item_type {}] + if {$item_type eq "as_item_type_mc"} { + # MC + set select_clause "as_item_id_${cr_item_id}.choice_value as as_item_id_${cr_item_id}" + } else { + # Default + set select_clause "as_item_id_${cr_item_id}.text_answer as as_item_id_${cr_item_id}" + } + set from_clause "left join (select dd.* from as_item_data dd where dd.as_item_cr_item_id = $cr_item_id) as_item_id_$cr_item_id on as_item_id_$cr_item_id.session_id = m.session_id" + + set where_clause " as_item_id_$cr_item_id.session_id = m.session_id" + set spec [list \ + hide_p $hide_p \ + label $item_title \ + where_clause ""] + if {$element_select} { + lappend spec select_clause $select_clause + } + if {$element_from} { + lappend spec from_clause $from_clause + } + if {$element_select || $element_from} { + lappend spec aggregate none + } + return $spec +} + + +ad_proc as::list::get_filters { + {-assessment_ids:required} + {-list_name:required} +} { + Add assessment items as filters + + @param assessment_ids list of assessment_ids to get the items from + We only get a question once, if its used in more than one of the assessments + @param list_name Name of the list + +} { + + foreach param [params] { + upvar $param $param + } + + #get all the items + + set filters [list] + + # we just want the questions that are in all the assessments we received + set multirow __as_list_$list_name + as::list::get_items_multirow \ + -assessment_ids $assessment_ids \ + -multirow $multirow + + # don't query the same item more than one + array set visited_items [list] + template::multirow foreach $multirow { + if {![info exists visited_items($item_id)]} { + set visited_items($item_id) $item_id + set title "[regsub -all {<.*?>} $title {}]" + lappend filters as_item_id_$item_id \ + [as::list::filter_spec \ + -as_item_id $as_item_id \ + -cr_item_id $item_id \ + -item_title $title] + } + } + return $filters +} + +ad_proc as::list::filter_spec { + {-as_item_id:required} + {-cr_item_id:required} + {-item_title:required} +} { + Generate list builder filter spec from one assessment question + + @param as_item_id Revision_id of hte question + @param item_type Type of question + @param item_title What we display for the filter label for the question +} { + + set item_type [db_string get_item_type {}] + set type "singleval" + + set spec \ + [list \ + label "'$item_title'"] + if { $item_type eq "as_item_type_mc" } { + lappend spec type "multival" + set values [concat [list [list "--" ""]] [db_list_of_lists item_choices {}]] + set i 0 + foreach l $values { + if {[string length [lindex $l 0]] > 21} { + set values [lreplace $values $i $i [list "[string range [lindex $l 0] 0 21]..." [lindex $l 1]]] + } + incr i + } + lappend spec values $values + lappend spec null_where_clause " 1=1 " + lappend spec where_clause_eval "subst \"( ( :as_item_id_$cr_item_id is null and coalesce(trim( from as_item_id_${cr_item_id}.choice_value),'') = '' ) or (:as_item_id_${cr_item_id} is not null and btrim(as_item_id_${cr_item_id}.choice_value) in (\[template::util::tcl_to_sql_list \$as_item_id_${cr_item_id}\]) ) ) and as_item_id_$cr_item_id.session_id = m.session_id\"" + # FIXME Check elements list for this + + lappend spec form_element_properties [list widget ajax_list_select options $values] + lappend spec select_clause "as_item_id_${cr_item_id}.choice_value as as_item_id_${cr_item_id}" + } else { + lappend spec values ""; #[set as_item_id_$cr_item_id] + lappend spec where_clause "lower(as_item_id_${cr_item_id}.text_answer) like '%'||lower(:as_item_id_$cr_item_id)||'%' and as_item_id_$cr_item_id.session_id = m.session_id" + # FIXME Check elements list for this + lappend spec select_clause "as_item_id_${cr_item_id}.text_answer as as_item_id_${cr_item_id}" + } + + lappend from_clause "left join (select dd.* from as_item_data dd where dd.as_item_cr_item_id = $cr_item_id) as_item_id_$cr_item_id on as_item_id_$cr_item_id.session_id = m.session_id " + return $spec +} + +ad_proc as::list::get_items_multirow { + -assessment_ids:required + -multirow +} { + Creates a multirow of all the items from assessments + This will only query once per request. + + @param assessment_ids List of assessment ids + @param multirow name of multirow to create +} { + if {[template::multirow exists $multirow]} { + return + } + if {[llength $assessment_ids] > 1} { +# set multiple_assessment_where "where exists (select null from (select m.assessment_id, m.section_id from as_assessment_section_map m where m.assessment_id in ([template::util::tcl_to_sql_list $assessment_ids])) s2 where s1.section_id=s2.section_id and s1.assessment_id <> s2.assessment_id)" + set multiple_assessment_where "" + } else { + set multiple_assessment_where "" + } + array set visited_sections [list] + foreach section [db_list_of_lists sections {}] { + set option_section_title [lindex $section 0] + set option_section_id [lindex $section 1] + if {![info exists visited_sections($option_section_id)]} { + db_multirow -append $multirow items {} + set visited_sections($option_section_id) $option_section_id + } + } +} + +ad_proc as::list::get_groupbys { + -assessment_ids:required + -list_name:required +} { + Create values spec for grouping on assessment question columns +} { + + foreach param [params] { + upvar $param $param + } + + #get all the items + + set groupbys [list] + + # we just want the questions that are in all the assessments we received + set multirow __as_list_$list_name + as::list::get_items_multirow \ + -assessment_ids $assessment_ids \ + -multirow $multirow + + # don't query the same item more than one + array set visited_items [list] + template::multirow foreach $multirow { + if {![info exists visited_items($item_id)]} { + set visited_items($item_id) $item_id + lappend groupbys \ + [as::list::groupby_spec \ + -as_item_id $as_item_id \ + -cr_item_id $item_id \ + -item_title $title] + } + } + return $groupbys +} + +ad_proc as::list::get_orderbys { + -assessment_ids:required + -list_name:required +} { + Create values spec for ordering on assessment question columns +} { + + foreach param [params] { + upvar $param $param + } + + #get all the items + + set orderbys [list] + + # we just want the questions that are in all the assessments we received + set multirow __as_list_$list_name + as::list::get_items_multirow \ + -assessment_ids $assessment_ids \ + -multirow $multirow + + # don't query the same item more than one + array set visited_items [list] + template::multirow foreach $multirow { + if {![info exists visited_items($item_id)]} { + set visited_items($item_id) $item_id + lappend orderbys as_item_id_$item_id \ + [as::list::orderby_spec \ + -as_item_id $as_item_id \ + -cr_item_id $item_id \ + -item_title $title] + } + } + + return $orderbys +} + + +ad_proc as::list::groupby_spec { + {-as_item_id:required} + {-cr_item_id:required} + {-item_title:required} +} { + Generate list builder groupby filter spec from one assessment question + + @param as_item_id Revision_id of hte question + @param item_type Type of question + @param item_title What we display for the filter label for the question +} { + + set item_ref as_item_id_$cr_item_id + return [list $item_title [list [list groupby $item_ref] [list orderby $item_ref]]] +} + +ad_proc as::list::orderby_spec { + {-as_item_id:required} + {-cr_item_id:required} + {-item_title:required} +} { + Generate list builder orderby filter spec from one assessment question + + @param as_item_id Revision_id of hte question + @param item_type Type of question + @param item_title What we display for the filter label for the question +} { + set item_ref as_item_id_$cr_item_id + return [list orderby ${item_ref}.choice_value] } \ No newline at end of file