Index: openacs-4/packages/imsld/tcl/imsld-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/tcl/imsld-procs.tcl,v diff -u -N -r1.39 -r1.40 --- openacs-4/packages/imsld/tcl/imsld-procs.tcl 10 Mar 2006 12:20:12 -0000 1.39 +++ openacs-4/packages/imsld/tcl/imsld-procs.tcl 13 Mar 2006 17:43:59 -0000 1.40 @@ -78,7 +78,10 @@ }] { set stucture_id [lindex $la_structure_list 0] set leaf_id [lindex $la_structure_list 1] - lappend role_part_list [imsld::get_role_part_from_activity -activity_type structure -leaf_id $leaf_id] + set referencer_list [imsld::get_role_part_from_activity -activity_type structure -leaf_id $leaf_id] + if { [llength $referencer_list] } { + lappend role_part_list $referencer_list + } } return $role_part_list } @@ -90,16 +93,24 @@ }] } { return $role_part_id } - # the support activity is referenced by an activity structure... digg more - db_1row get_sa_activity_structure { + set role_part_list [list] + # the learning activity is referenced by some activity structures... digg more + foreach sa_structure_list [db_list_of_lists get_sa_activity_structures { select ias.structure_id, ias.item_id as leaf_id - from imsld_activity_structuresi ias, acs_rels ar, imsld_learning_activitiesi sa + from imsld_activity_structuresi ias, acs_rels ar, imsld_support_activitiesi sa where ar.object_id_one = ias.item_id and ar.object_id_two = sa.item_id and content_revision__is_live(ias.structure_id) = 't' - and la.item_id = :leaf_id + and sa.item_id = :leaf_id + }] { + set stucture_id [lindex $sa_structure_list 0] + set leaf_id [lindex $sa_structure_list 1] + set referencer_list [imsld::get_role_part_from_activity -activity_type structure -leaf_id $leaf_id] + if { [llength $referencer_list] } { + lappend role_part_list $referencer_list + } } - return [imsld::get_role_part_from_activity -activity_type structure -leaf_id $leaf_id] + return $role_part_list } structure { if { [db_0or1row directly_mapped { @@ -690,15 +701,14 @@ } { set user_id [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] if { !$code_call_p } { - # get the url for parse it and get the info + # get the url to parse it and get the info set url [ns_conn url] regexp {finish-component-element-([0-9]+)-([0-9]+)-([0-9]+)-([a-z]+).imsld$} $url match imsld_id role_part_id element_id type regsub {/finish-component-element.*} $url "" return_url } # now that we have the necessary info, mark the finished element completed and return db_dml insert_element_entry { *SQL* } - switch $type { learning { set table_name "imsld_learning_activities" @@ -724,24 +734,19 @@ if { [info exists table_name] } { if { [db_0or1row get_related_on_completion_id ""] } { - db_1row get_related_resource_id {} + db_1row get_related_resource_id { *SQL* } imsld::grant_permissions -resources_activities_list $related_resource -user_id $user_id } } if { [string eq $type "learning"] || [string eq $type "support"] || [string eq $type "structure"] } { - foreach referencer_structure_list [db_list_of_lists referencer_structure { - select ias.structure_id, - ias.item_id as structure_item_id - from acs_rels ar, imsld_activity_structuresi ias, cr_items cri - where ar.object_id_one = ias.item_id - and ar.object_id_two = cri.item_id - and cri.live_revision = :element_id - }] { + foreach referencer_structure_list [db_list_of_lists referencer_structure { *SQL* }] { set structure_id [lindex $referencer_structure_list 0] set structure_item_id [lindex $referencer_structure_list 1] + set number_to_select [lindex $referencer_structure_list 2] # if this activity is part of an activity structure, let's check if the rest of referenced # activities are finished too, so we can mark finished the activity structure as well set scturcture_finished_p 1 + set total_completed 0 db_foreach referenced_activity { select content_item__get_live_revision(ar.object_id_two) as activity_id from acs_rels ar @@ -751,8 +756,12 @@ if { ![db_string completed_p { *SQL* }] } { # there is at leas one no-completed activity, so we can't mark this activity structure yet set scturcture_finished_p 0 + } else { + incr total_completed } } + # FIX ME: when the tree wokrs fine, change the if condition for thisone + # if { $scturcture_finished_p || (![string eq $number_to_select ""] && ($total_completed >= $number_to_select)) } {} if { $scturcture_finished_p } { imsld::finish_component_element -imsld_id $imsld_id \ -role_part_id $role_part_id \ @@ -898,7 +907,7 @@ if { !$code_call_p } { ad_returnredirect "${return_url}" } -} +} ad_proc -public imsld::structure_next_activity { -activity_structure_id:required @@ -950,15 +959,13 @@ foreach referenced_activity [db_list_of_lists struct_referenced_activities { *SQL* }] { set object_id_two [lindex $referenced_activity 0] set rel_type [lindex $referenced_activity 1] + set rel_id [lindex $referenced_activity 2] switch $rel_type { imsld_as_la_rel { # find out if is the next one - db_1row get_la_info { - select sort_order, - activity_id as learning_activity_id - from imsld_learning_activitiesi - where item_id = :object_id_two - and content_revision__is_live(activity_id) = 't' + db_1row get_la_info { *SQL* } + db_1row get_sort_order { + select sort_order from imsld_as_la_rels where rel_id = :rel_id } if { ![db_string completed_p_from_la { *SQL* }] && ( [string eq "" $min_sort_order] || $sort_order < $min_sort_order ) } { set min_sort_order $sort_order @@ -975,6 +982,9 @@ where item_id = :object_id_two and content_revision__is_live(activity_id) = 't' } + db_1row get_sort_order { + select sort_order from imsld_as_sa_rels where rel_id = :rel_id + } if { ![db_string completed_p_from_sa { *SQL* }] && ( [string eq "" $min_sort_order] || $sort_order < $min_sort_order ) } { set min_sort_order $sort_order set next_activity_id $support_activity_id @@ -984,6 +994,9 @@ imsld_as_as_rel { # recursive call? db_1row get_as_info { *SQL* } + db_1row get_sort_order { + select sort_order from imsld_as_as_rels where rel_id = :rel_id + } if { ![db_string completed_p { *SQL* }] && ( [string eq "" $min_sort_order] || $sort_order < $min_sort_order ) } { set min_sort_order $sort_order set next_activity_id $structure_id @@ -1010,6 +1023,64 @@ return [list $next_activity_id $next_activity_type $environment_list $structures_names] } +ad_proc -public imsld::structure_finished_p { + -structure_id:required + {-user_id ""} +} { + @param structure_id + @option user_id + + @return 0 if the any activity referenced from the activity structure hasn't been finished. 1 otherwise +} { + set user_id [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] + + set all_completed 1 + foreach referenced_activity [db_list_of_lists struct_referenced_activities { + select ar.object_id_two, + ar.rel_type + from acs_rels ar, imsld_activity_structuresi ias + where ar.object_id_one = ias.item_id + and ias.structure_id = :structure_id + order by ar.object_id_two + }] { + # get all the directly referenced activities (from the activity structure) + set object_id_two [lindex $referenced_activity 0] + set rel_type [lindex $referenced_activity 1] + switch $rel_type { + imsld_as_la_rel - + imsld_as_sa_rel { + # is the activity finished ? + if { ![db_0or1row completed_p { + select 1 from imsld_status_user + where related_id = content_item__get_live_revision(:object_id_two) and user_id = :user_id and status = 'finished' + }] } { + set all_completed 0 + } + } + imsld_as_as_rel { + # search recursively trough the referenced + db_1row get_activity_structure_info { + select structure_id + from imsld_activity_structuresi + where item_id = :object_id_two + and content_revision__is_live(structure_id) = 't' + } + # is the activity finished ? + if { ![db_0or1row completed_p { + select 1 from imsld_status_user + where related_id = :structure_id and user_id = :user_id and status = 'finished' + }] } { + set all_completed 0 + } + if { ![imsld::structure_finished_p -structure_id $structure_id -user_id $user_id] } { + set all_completed 0 + } + } + } + } + return $all_completed +} + ad_proc -public imsld::role_part_finished_p { -role_part_id:required {-user_id ""} @@ -1019,12 +1090,7 @@ @return 0 if the role part hasn't been finished. 1 otherwise } { set user_id [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] - if { [db_0or1row already_marked_p { - select 1 - from imsld_status_user - where completed_id = :role_part_id - and user_id = :user_id - }] } { + if { [db_0or1row already_marked_p { *SQL* }] } { # simple case, already marked as finished return 1 } @@ -1065,13 +1131,12 @@ } } structure { - if { [db_string completed_from_as { - select count(*) from imsld_status_user - where completed_id = content_item__get_live_revision(:activity_structure_id) - and user_id = :user_id - }] } { - return 1 + db_1row get_sa_info { + select structure_id + from imsld_activity_structuresi + where item_id = :activity_structure_id } + return [imsld::structure_finished_p -structure_id $structure_id -user_id $user_id] } none { return 1 @@ -1208,10 +1273,7 @@ } send-mail { -#escoger los destinatarios: all-in-role. Hasta que no esten los roles soportados, nada se puede hacer. -#escoger los destinatarios: selected. Hasta que no esten los roles soportados, nada se puede hacer. - -#montar el enlace a "spam" con los destinatarios elegidos y devolverlo + # FIX ME: when roles be supported, fix it so the mail is sent to the propper role set image_path [imsld::object_type_image_path -object_type $service_type] set services_list "\"Send-Mail" set resource_item_list "" @@ -1891,13 +1953,7 @@ } { # get environments set environments_list [list] - set associated_environments_list [db_list sa_associated_environments { - select ar.object_id_two as environment_item_id - from acs_rels ar - where ar.object_id_one = :structure_item_id - and ar.rel_type = 'imsld_as_env_rel' - order by ar.object_id_two - }] + set associated_environments_list [db_list sa_associated_environments { *SQL* }] foreach environment_item_id $associated_environments_list { if { [llength $environments_list] } { set environments_list [concat [list $environments_list] \ @@ -1909,12 +1965,254 @@ if { [string eq "t" $resource_mode] } { #put in order the environments_id(s) set environments_ids [concat [lindex [lindex $environments_list 1] [expr [llength [lindex $environments_list 1] ] - 1 ]] \ - [lindex [lindex $environments_list 2] [expr [llength [lindex $environments_list 2] ] - 1 ]] ] + [lindex [lindex $environments_list 2] [expr [llength [lindex $environments_list 2] ] - 1 ]]] } - + return $environments_list } +ad_proc -public imsld::generate_structure_activities_list { + -imsld_id + -structure_item_id + -user_id + -role_part_id + {-next_activity_id ""} + -dom_node + -dom_doc +} { + @param imsld_id + @param structure_item_id + @param user_id + + @return A list of lists of the activities referenced from the activity structure +} { + # auxiliary list to store the activities + set completed_list [list] + # get the structure info + db_1row structure_info { *SQL* } + # get the referenced activities which are referenced from the structure + foreach referenced_activity [db_list_of_lists struct_referenced_activities { *SQL* }] { + # get all the directly referenced activities (from the activity structure) + set object_id_two [lindex $referenced_activity 0] + set rel_type [lindex $referenced_activity 1] + set rel_id [lindex $referenced_activity 2] + switch $rel_type { + imsld_as_la_rel { + # add the activiti to the TCL list + db_1row get_learning_activity_info { *SQL* } + db_1row get_sort_order { + select sort_order from imsld_as_la_rels where rel_id = :rel_id + } + set completed_p [db_0or1row completed_p { *SQL* }] + # show the activity only if: + # 1. it has been already completed + # 2. if the structure-type is "selection" + # 3. if it is the next activity to be done (and structure-type is "sequence") + if { $completed_p || [string eq $complete_act_id ""] || [string eq $structure_type "selection"] || ([string eq $is_visible_p "t"] && [string eq $next_activity_id $activity_id]) } { + set activity_node [$dom_doc createElement li] + $activity_node setAttribute class "liOpen" + + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/[export_vars -base "activity-frame" -url {activity_id}]" + set text [$dom_doc createTextNode "$activity_title"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set text [$dom_doc createTextNode " "] + $activity_node appendChild $text + + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/finish-component-element-${imsld_id}-${role_part_id}-${activity_id}-learning.imsld" + set text [$dom_doc createTextNode "(finish)"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set completed_list [linsert $completed_list $sort_order [$activity_node asList]] + } + } + imsld_as_sa_rel { + # add the activiti to the TCL list + db_1row get_support_activity_info { *SQL* } + db_1row get_sort_order { + select sort_order from imsld_as_sa_rels where rel_id = :rel_id + } + set completed_p [db_0or1row completed_p { *SQL* }] + # show the activity only if: + # 1. it has been already completed + # 2. if the structure-type is "selection" + # 3. if it is the next activity to be done (and structure-type is "sequence") + if { $completed_p || [string eq $complete_act_id ""] || [string eq $is_visible_p "t"] || [string eq $structure_type "selection"] || [string eq $next_activity_id $activity_id] } { + set activity_node [$dom_doc createElement li] + $activity_node setAttribute class "liOpen" + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/[export_vars -base "activity-frame" -url {activity_id}]" + set text [$dom_doc createTextNode "$activity_title"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set text [$dom_doc createTextNode " "] + $activity_node appendChild $text + + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/finish-component-element-${imsld_id}-${role_part_id}-${activity_id}-support.imsld" + set text [$dom_doc createTextNode "(finish)"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set completed_list [linsert $completed_list $sort_order [$activity_node asList]] + } + } + imsld_as_as_rel { + # add the structure to the list only if: + # 1. the structure has already been started or finished + # 2. the referencer structure-type is "selection" + # (if it is the next activity to be done then it should had been marked as started + # in the "structure_next_activity" function. which is the case when structure-type is "sequence") + db_1row get_activity_structure_info { *SQL* } + db_1row get_sort_order { + select sort_order from imsld_as_as_rels where rel_id = :rel_id + } + set started_p [db_0or1row as_completed_p { *SQL* }] + if { $started_p || [string eq $structure_type "selection"] } { + set structure_node [$dom_doc createElement li] + $structure_node setAttribute class "liOpen" + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/[export_vars -base "activity-frame" -url {structure_id}]" + set text [$dom_doc createTextNode "$activity_title"] + $a_node appendChild $text + $structure_node appendChild $a_node + + set nested_activities_list [imsld::generate_structure_activities_list -imsld_id $imsld_id \ + -structure_item_id $structure_item_id \ + -user_id $user_id \ + -next_activity_id $next_activity_id \ + -role_part_id $role_part_id \ + -dom_node $structure_node \ + -dom_doc $dom_doc] + set ul_node [$dom_doc createElement ul] + foreach nested_activity $nested_activities_list { + $ul_node appendFromList $nested_activity + } + $structure_node appendChild $ul_node + set completed_list [linsert $completed_list $sort_order [$structure_node asList]] + } + } + } + } + return $completed_list +} + +ad_proc -public imsld::generate_activities_tree { + -imsld_id:required + -user_id + {-next_activity_id ""} + -dom_node + -dom_doc +} { + @param imsld_id + @param user_id + + @return A list of lists of the activities +} { + # start with the role parts + foreach role_part_list [db_list_of_lists referenced_role_parts { *SQL* }] { + set type [lindex $role_part_list 0] + set activity_id [lindex $role_part_list 1] + set role_part_id [lindex $role_part_list 2] + switch $type { + learning { + # add the learning activity to the tree + db_1row get_learning_activity_info { *SQL* } + set completed_activity_p [db_0or1row already_completed { + select 1 from imsld_status_user where related_id = :activity_id and user_id = :user_id + }] + if { [string eq $complete_act_id ""] || [string eq $is_visible_p "t"] || $completed_activity_p || $activity_id == $next_activity_id } { + set activity_node [$dom_doc createElement li] + $activity_node setAttribute class "liOpen" + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/[export_vars -base "activity-frame" -url {activity_id}]" + set text [$dom_doc createTextNode "$activity_title"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set text [$dom_doc createTextNode " "] + $activity_node appendChild $text + + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/finish-component-element-${imsld_id}-${role_part_id}-${activity_id}-learning.imsld" + set text [$dom_doc createTextNode "(finish)"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set completed_list [linsert $completed_list $sort_order [$activity_node asList]] + $dom_node appendChild $activity_node + } + } + support { + # add the support activity to the tree + db_1row get_support_activity_info { *SQL* } + set completed_activity_p [db_0or1row already_completed { + select 1 from imsld_status_user where related_id = :activity_id and user_id = :user_id + }] + if { [string eq $complete_act_id ""] || [string eq $is_visible_p "t"] || $completed_activity_p || $activity_id == $next_activity_id } { + set activity_node [$dom_doc createElement li] + $activity_node setAttribute class "liOpen" + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/[export_vars -base "activity-frame" -url {activity_id}]" + set text [$dom_doc createTextNode "$activity_title"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set text [$dom_doc createTextNode " "] + $activity_node appendChild $text + + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/finish-component-element-${imsld_id}-${role_part_id}-${activity_id}-support.imsld" + set text [$dom_doc createTextNode "(finish)"] + $a_node appendChild $text + $activity_node appendChild $a_node + + set completed_list [linsert $completed_list $sort_order [$activity_node asList]] + $dom_node appendChild $activity_node + } + } + structure { + # this is a special case since there are some conditions to check + # in order to determine if the referenced activities have to be shown + # because of that the proc generate_structure_activities_list is called, + # which returns a tcl list in tDOM format. + + # anyway, we add the structure to the tree only if: + # 1. the structure has already been started or finished + # 2. the referencer structure-type is "selection" + # (if it is the next activity to be done then it should had been marked as started + # in the "structure_next_activity" function. which is the case when structure-type is "sequence") + db_1row get_activity_structure_info { *SQL* } + set started_p [db_0or1row as_completed_p { *SQL* }] + if { $started_p || [string eq $structure_type "selection"] } { + set structure_node [$dom_doc createElement li] + $structure_node setAttribute class "liOpen" + set a_node [$dom_doc createElement a] + $a_node setAttribute href "[ad_conn url]/[export_vars -base "activity-frame" -url {structure_id}]" + set text [$dom_doc createTextNode "$activity_title"] + $a_node appendChild $text + $structure_node appendChild $a_node + set nested_list [imsld::generate_structure_activities_list -imsld_id $imsld_id \ + -structure_item_id $structure_item_id \ + -user_id $user_id \ + -next_activity_id $next_activity_id \ + -role_part_id $role_part_id \ + -dom_doc $dom_doc \ + -dom_node $dom_node] + # the nested finished activities are returned as a tcl list in tDOM format + $structure_node appendFromList [list ul [list] [concat [list] $nested_list]] + $dom_node appendChild $structure_node + } + } + } + } +} + ad_proc -public imsld::next_activity { -imsld_item_id:required {-user_id ""} @@ -1950,9 +2248,8 @@ and content_revision__is_live(imsld_id) = 't' } set user_id [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] - + # global prerequisites and learning objectives - set prerequisites_list_temp [imsld::process_prerequisite -imsld_item_id $imsld_item_id -resource_mode "t"] set prerequisites_list [list [lindex $prerequisites_list_temp 0] [lindex $prerequisites_list_temp 1]] set prerequisites_list_ids [lindex $prerequisites_list_temp 2] @@ -2114,7 +2411,7 @@ } } } - + # the last completed is now stored in completed_id, let's find out the next role_part_id that the user has to work on. # Procedure (knowing that the info of the last role_part are stored in the last iteration vars): # 0. check if all the activities referenced by the current role_part_id are finished @@ -2187,6 +2484,7 @@ # 1. if it is a learning or support activity, no problem, find the associated files and return the lists # 2. if it is an activity structure we have verify which activities are already completed and return the next # activity in the activity structure, handling the case when the next activity is also an activity structure + db_1row get_role_part_activity { select case when learning_activity_id is not null @@ -2242,6 +2540,7 @@ incr tab_structures } } + set environments "" if { [llength $environment_list] } { foreach environment $environment_list { @@ -2251,7 +2550,6 @@ append environments "[join [lindex $environment 3] " "]
" } } - # learning activity if { [string eq $activity_type learning] } { db_1row learning_activity { *SQL* } @@ -2321,11 +2619,179 @@ {} \ $status } - # first parameter: activity name return [template::multirow size imsld_multirow] } +ad_proc -public imsld::get_next_activity { + -imsld_item_id:required + {-user_id ""} + {-community_id ""} +} { + @param imsld_item_id + @option user_id default [ad_conn user_id] + @option community_id + + @return The activity_id of the next activity to be done by the user_id +} { + # get the imsld info + db_1row get_ismld_info { + select imsld_id + from imsld_imsldsi + where item_id = :imsld_item_id + and content_revision__is_live(imsld_id) = 't' + } + set user_id [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] + + if { ![db_string get_last_entry { + select count(*) + from imsld_status_user + where user_id = :user_id + and imsld_id = :imsld_id + and type in ('learning','support','structure') + }] } { + # special case: the user has no entry, the ims-ld hasn't started yet for that user + set first_p 1 + db_1row get_first_role_part { + select irp.role_part_id, ia.act_id, ip.play_id + from cr_items cr0, cr_items cr1, cr_items cr2, imsld_methods im, imsld_plays ip, imsld_acts ia, imsld_role_parts irp + where im.imsld_id = :imsld_item_id + and ip.method_id = cr0.item_id + and cr0.live_revision = im.method_id + and ia.play_id = cr1.item_id + and cr1.live_revision = ip.play_id + and irp.act_id = cr2.item_id + and cr2.live_revision = ia.act_id + and content_revision__is_live(irp.role_part_id) = 't' + and ip.sort_order = (select min(ip2.sort_order) from imsld_plays ip2 where ip2.method_id = cr0.item_id) + and ia.sort_order = (select min(ia2.sort_order) from imsld_acts ia2 where ia2.play_id = cr1.item_id) + and irp.sort_order = (select min(irp2.sort_order) from imsld_role_parts irp2 where irp2.act_id = cr2.item_id) + } + } else { + # get the last role_part_id of the last completed activity + + db_1row get_last_completed { + select stat.related_id, + stat.role_part_id, + stat.type, + rp.sort_order, + rp.act_id, + stat.status + from imsld_status_user stat, imsld_role_parts rp + where stat.imsld_id = :imsld_id + and stat.user_id = :user_id + and stat.role_part_id = rp.role_part_id + and stat.type in ('learning','support','structure') + order by stat.status_date desc + limit 1 + } + + # now let's find out the next role_part_id that the user has to work on. + # Procedure (knowing that the info of the last role_part are stored in the last iteration vars): + # 0. check if all the activities referenced by the current role_part_id are finished + # 0.1 if all of them are not finished yet, skip this section and preserve the last role_part_id, otherwise, continue + # 1. get the next role_part from imsld_role_parts according to sort_number, first + # search in the current act_id, then in the current play_id, then in the next play_id and so on... + # 1.1 if there are no more role_parts then this is the last one + # 1.2 if we find a "next role_part", it will be treated latter, we just have to set the next role_part_id var + + if { [imsld::role_part_finished_p -role_part_id $role_part_id -user_id $user_id] } { + # search in the current act_id + if { ![db_0or1row search_current_act { + select role_part_id + from imsld_role_parts + where sort_order = :sort_order + 1 + and act_id = :act_id + }] } { + # get current act_id's sort_order and search in the next act in the current play_id + db_1row get_current_play_id { + select ip.item_id as play_item_id, + ip.play_id, + ia.sort_order as act_sort_order + from imsld_playsi ip, imsld_acts ia, cr_items cr + where ip.item_id = ia.play_id + and ia.act_id = cr.live_revision + and cr.item_id = :act_id + } + if { ![db_0or1row search_current_play { + select rp.role_part_id + from imsld_role_parts rp, imsld_actsi ia + where ia.play_id = :play_item_id + and ia.sort_order = :act_sort_order + 1 + and rp.act_id = ia.item_id + and content_revision__is_live(rp.role_part_id) = 't' + and content_revision__is_live(ia.act_id) = 't' + and rp.sort_order = (select min(irp2.sort_order) from imsld_role_parts irp2 where irp2.act_id = rp.act_id) + }] } { + # get the current play_id's sort_order and sarch in the next play in the current method_id + db_1row get_current_method { + select im.item_id as method_item_id, + ip.sort_order as play_sort_order + from imsld_methodsi im, imsld_plays ip + where im.item_id = ip.method_id + and ip.play_id = :play_id + } + if { ![db_0or1row search_current_method { + select rp.role_part_id + from imsld_role_parts rp, imsld_actsi ia, imsld_playsi ip + where ip.method_id = :method_item_id + and ia.play_id = ip.item_id + and rp.act_id = ia.item_id + and ip.sort_order = :play_sort_order + 1 + and content_revision__is_live(rp.role_part_id) = 't' + and content_revision__is_live(ia.act_id) = 't' + and content_revision__is_live(ip.play_id) = 't' + and ia.sort_order = (select min(ia2.sort_order) from imsld_acts ia2 where ia2.play_id = ip.item_id) + and rp.sort_order = (select min(irp2.sort_order) from imsld_role_parts irp2 where irp2.act_id = ia.item_id) + }] } { + # there is no more to search, we reached the end of the unit of learning + return "" + } + } + } + } + } + + # find the next activity referenced by the role_part + # (learning_activity, support_activity, activity_structure) + # 1. if it is a learning or support activity, no problem, find the associated files and return the lists + # 2. if it is an activity structure we have verify which activities are already completed and return the next + # activity in the activity structure, handling the case when the next activity is also an activity structure + + db_1row get_role_part_activity { + select case + when learning_activity_id is not null + then 'learning' + when support_activity_id is not null + then 'support' + when activity_structure_id is not null + then 'structure' + else 'none' + end as activity_type, + case + when learning_activity_id is not null + then content_item__get_live_revision(learning_activity_id) + when support_activity_id is not null + then content_item__get_live_revision(support_activity_id) + when activity_structure_id is not null + then content_item__get_live_revision(activity_structure_id) + else content_item__get_live_revision(environment_id) + end as next_activity_id, + environment_id as rp_environment_item_id + from imsld_role_parts + where role_part_id = :role_part_id + } + # activity structure + if { [string eq $activity_type structure] } { + # activity structure. we have to look for the next learning or support activity + set activity_list [imsld::structure_next_activity -activity_structure_id $next_activity_id -imsld_id $imsld_id -role_part_id $role_part_id] + set next_activity_id [lindex $activity_list 0] + } + + # return the next_activity_id + return $next_activity_id +} + ad_proc -public imsld::get_activity_from_environment { -environment_item_id