Index: openacs-4/packages/curriculum/tcl/apm-callback-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/curriculum/tcl/apm-callback-procs.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/curriculum/tcl/apm-callback-procs.tcl 3 Jun 2003 10:28:20 -0000 1.1
@@ -0,0 +1,218 @@
+ad_library {
+
+ APM callback procedures.
+
+ @creation-date 2003-06-03
+ @author Ola Hansson (ola@polyxena.net)
+ @cvs-id $Id: apm-callback-procs.tcl,v 1.1 2003/06/03 10:28:20 olah Exp $
+
+}
+
+namespace eval curriculum::apm {}
+
+
+####
+#
+# APM callbacks.
+#
+####
+
+
+ad_proc -private curriculum::apm::after_install {} {
+ Package installation callback proc.
+} {
+ db_transaction {
+ curriculum::apm::register_implementations
+ curriculum::workflow_create
+ }
+}
+
+
+ad_proc -private curriculum::apm::before_uninstall {} {
+ Package un-installation callback proc.
+} {
+ db_transaction {
+ curriculum::workflow_delete
+ curriculum::apm::unregister_implementations
+ }
+}
+
+
+ad_proc -private curriculum::apm::after_instantiate {
+ {-package_id:required}
+} {
+ Package instantiation callback proc.
+} {
+ curriculum::instance_workflow_create -package_id $package_id
+
+ ###
+ # FIXME. We just set this up for convenience during development.
+ ###
+
+ db_transaction {
+
+ set subsite_url [curriculum::conn subsite_url]
+
+ # Create a curriculum.
+ set curriculum_id [curriculum::new \
+ -name "Demo Curriculum A" \
+ -description Description \
+ -package_id $package_id]
+
+ # Add some elements.
+ foreach { url label } [list ${subsite_url}api-doc/ "API Documentation" ${subsite_url} "Home" ${subsite_url}doc/ "Package Documentation"] {
+ curriculum::element::new \
+ -curriculum_id $curriculum_id \
+ -name $label \
+ -description "Description of $label." \
+ -desc_format "text/html" \
+ -url $url
+ }
+
+ # Create a curriculum.
+ set curriculum_id [curriculum::new \
+ -name "Demo Curriculum B" \
+ -description Description \
+ -package_id $package_id]
+
+ # Add some elements.
+ foreach { url label } [list ${subsite_url}admin/ "Admin" ${subsite_url}acs-service-contract/ "Service Contracts" http://openacs.org "OpenACS Website"] {
+ curriculum::element::new \
+ -curriculum_id $curriculum_id \
+ -name $label \
+ -description "Description of $label." \
+ -desc_format "text/fixed-width" \
+ -url $url
+ }
+
+ }
+
+ curriculum::elements_flush
+
+}
+
+
+ad_proc -private curriculum::apm::before_uninstantiate {
+ {-package_id:required}
+} {
+ Package un-instantiation callback proc.
+} {
+ db_transaction {
+ # Deletes the curriculum(s) in a package instance including
+ # their data and associated workflow cases.
+ curriculum::delete_instance -package_id $package_id
+
+ curriculum::instance_workflow_delete -package_id $package_id
+ }
+}
+
+
+#####
+#
+# Service contract implementations.
+#
+#####
+
+
+ad_proc -private curriculum::apm::register_implementations {} {
+ db_transaction {
+ #curriculum::apm::register_capture_resolution_code_impl
+ curriculum::apm::register_curriculum_owner_impl
+ curriculum::apm::register_format_log_title_impl
+ curriculum::apm::register_curriculum_notification_info_impl
+ }
+}
+
+
+ad_proc -private curriculum::apm::unregister_implementations {} {
+ db_transaction {
+
+ #acs_sc::impl::delete \
+ -contract_name [workflow::service_contract::action_side_effect] \
+ -impl_name "CurriculumCaptureResolutionCode"
+
+ acs_sc::impl::delete \
+ -contract_name [workflow::service_contract::role_default_assignees] \
+ -impl_name "CurriculumOwner"
+
+ acs_sc::impl::delete \
+ -contract_name [workflow::service_contract::activity_log_format_title] \
+ -impl_name "CurriculumFormatLogTitle"
+
+ acs_sc::impl::delete \
+ -contract_name [workflow::service_contract::notification_info] \
+ -impl_name "CurriculumNotificationInfo"
+ }
+}
+
+
+#ad_proc -private curriculum::apm::register_capture_resolution_code_impl {} {
+#
+# set spec {
+# name "CurriculumCaptureResolutionCode"
+# aliases {
+# GetObjectType curriculum::object_type
+# GetPrettyName curriculum::capture_resolution_code::pretty_name
+# DoSideEffect curriculum::capture_resolution_code::do_side_effect
+# }
+# }
+#
+# lappend spec contract_name [workflow::service_contract::action_side_effect]
+# lappend spec owner [curriculum::package_key]
+#
+# acs_sc::impl::new_from_spec -spec $spec
+#}
+
+
+ad_proc -private curriculum::apm::register_curriculum_owner_impl {} {
+
+ set spec {
+ name "CurriculumOwner"
+ aliases {
+ GetObjectType curriculum::object_type
+ GetPrettyName curriculum::owner::pretty_name
+ GetAssignees curriculum::owner::get_assignees
+ }
+ }
+
+ lappend spec contract_name [workflow::service_contract::role_default_assignees]
+ lappend spec owner [curriculum::package_key]
+
+ acs_sc::impl::new_from_spec -spec $spec
+}
+
+
+ad_proc -private curriculum::apm::register_format_log_title_impl {} {
+
+ set spec {
+ name "CurriculumFormatLogTitle"
+ aliases {
+ GetObjectType curriculum::object_type
+ GetPrettyName curriculum::format_log_title::pretty_name
+ GetTitle curriculum::format_log_title::format_log_title
+ }
+ }
+
+ lappend spec contract_name [workflow::service_contract::activity_log_format_title]
+ lappend spec owner [curriculum::package_key]
+
+ acs_sc::impl::new_from_spec -spec $spec
+}
+
+
+ad_proc -private curriculum::apm::register_curriculum_notification_info_impl {} {
+
+ set spec {
+ name "CurriculumNotificationInfo"
+ aliases {
+ GetObjectType curriculum::object_type
+ GetPrettyName curriculum::notification_info::pretty_name
+ GetNotificationInfo curriculum::notification_info::get_notification_info
+ }
+ }
+
+ lappend spec contract_name [workflow::service_contract::notification_info]
+ lappend spec owner [curriculum::package_key]
+
+ acs_sc::impl::new_from_spec -spec $spec
+}
Index: openacs-4/packages/curriculum/tcl/curriculum-init.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/curriculum/tcl/curriculum-init.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/curriculum/tcl/curriculum-init.tcl 3 Jun 2003 10:28:20 -0000 1.1
@@ -0,0 +1,30 @@
+ad_library {
+
+ Curriculum Initialization
+
+ @creation-date 2003-06-02
+ @author Ola Hansson (ola@polyxena.net)
+ @cvs-id $Id: curriculum-init.tcl,v 1.1 2003/06/03 10:28:20 olah Exp $
+
+}
+
+# FIXME. Most likely we should only get the package_ids that have
+# curriculums which are published.
+set package_ids [db_list get_all_curriculum_package_ids {*SQL*}]
+
+foreach package_id $package_ids {
+
+ # Register the filter that keeps track of which elements the user has seen.
+ # If no "UrlPatternsToFilter" parameter is detected we register
+ # this filter for all urls in this curriculum instance.
+
+ set url_patterns [parameter::get -package_id $package_id \
+ -parameter UrlPatternsToFilter \
+ -default *]
+
+ foreach url_pattern [split [string trim $url_patterns]] {
+ ns_log Notice "Installing curriculum filter for $url_pattern in package_id $package_id"
+ ad_register_filter postauth GET $url_pattern curriculum::curriculum_filter
+ }
+
+}
Index: openacs-4/packages/curriculum/tcl/curriculum-init.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/curriculum/tcl/curriculum-init.xql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/curriculum/tcl/curriculum-init.xql 3 Jun 2003 10:28:20 -0000 1.1
@@ -0,0 +1,11 @@
+
+
curriculum_id, name, description, desc_format, owner_id, package_id, sort_key
+ + @param curriculum_id The id of the curriculum to retrieve information about. + @param array The name of the array in the callers scope where the information will + be stored. + + @return The return value from db_0or1row. If more than one row is returned, throws an error. + + @author Ola Hansson (ola@polyxena.net) + +} { + upvar $array row + + if { ![db_0or1row get_curriculum_data {*SQL*} -column_array row] } { + # Query did not return a row. We should probably return an error instead. + return 0 + ad_script_abort + } + + # Get the case ID, so we can get state information. + set case_id [workflow::case::get_id \ + -object_id $curriculum_id \ + -workflow_short_name [workflow_short_name]] + + # Get state information. + workflow::case::fsm::get -case_id $case_id -array case -action_id $action_id + + set row(pretty_state) $case(pretty_state) + set row(state_short_name) $case(state_short_name) + set row(hide_fields) $case(state_hide_fields) + set row(entry_id) $case(entry_id) + + return 1 +} + + +ad_proc -public curriculum::delete { + -curriculum_id:required +} { + + Delete a curriculum. + + @param curriculum_id The object-id of the curriculum which should be deleted. + + @return Nothing. + + @author Ola Hansson (ola@polyxena.net) + +} { + db_transaction { + + # Get the case ID. + set case_id [workflow::case::get_id \ + -object_id $curriculum_id \ + -workflow_short_name [workflow_short_name]] + + # FIXME. There should be a Tcl wrapper for this in workflow but there + # isn't yet (at least not on MAIN). + #workflow::case::delete -case_id $case_id + db_exec_plsql delete_workflow_case {*SQL*} + + db_exec_plsql delete_curriculum {*SQL*} + + } +} + + +ad_proc -private curriculum::delete_instance { + -package_id:required +} { + + Deletes curriculums in a package instance (and their data). + We thus avoid having orphan curriculum data in the database. + + @param package_id The package_id of the curriculum instance which should be deleted. + + @return Nothing. + + @author Ola Hansson (ola@polyxena.net) + +} { + # Get a list of all curriculums in this package instance. + set curriculum_ids [conn -nocache curriculum_ids] + + db_transaction { + + foreach curriculum_id $curriculum_ids { + ns_log Notice "curriculum::delete_instance - deleting curriculum $curriculum_id in package_id $package_id" + delete -curriculum_id $curriculum_id + } + + } +} + +#### +# +# Workflow procs. +# +#### + + +ad_proc -private curriculum::workflow_create {} { + Create the 'curriculum' workflow for curriculum. +} { + set spec { + curriculum { + pretty_name "Curriculum" + package_key "curriculum" + object_type "cu_curriculum" + callbacks { + curriculum.CurriculumNotificationInfo + } + roles { + author { + pretty_name "Author" + callbacks { + workflow.Role_DefaultAssignees_CreationUser + } + } + editor { + pretty_name "Editor" + } + publisher { + pretty_name "Publisher" + callbacks { + curriculum.CurriculumOwner + workflow.Role_PickList_CurrentAssignees + workflow.Role_AssigneeSubquery_RegisteredUsers + } + } + } + states { + authored { + pretty_name "Created" + hide_fields {} + } + edited { + pretty_name "Edited" + } + refused { + pretty_name "Refused" + } + published { + pretty_name "Published" + } + archived { + pretty_name "Archived" + } + } + actions { + create { + pretty_name "Create" + pretty_past_tense "Created" + new_state "authored" + initial_action_p t + } + comment { + pretty_name "Comment" + pretty_past_tense "Commented" + allowed_roles { author editor publisher } + privileges { read write } + always_enabled_p t + edit_fields { + description + } + } + edit { + pretty_name "Edit" + pretty_past_tense "Edited" + new_state "edited" + allowed_roles { author editor publisher } + privileges { write } + always_enabled_p t + edit_fields { + name + description + } + } + publish { + pretty_name "Publish" + pretty_past_tense "Published" + assigned_role "publisher" + enabled_states { authored edited } + assigned_states { edited } + new_state "published" + privileges { write } + edit_fields { } + } + archive { + pretty_name "Archive" + pretty_past_tense "Archived" + assigned_role "publisher" + assigned_states { published } + new_state "archived" + privileges { write } + edit_fields { } + } + } + } + } + set workflow_id [workflow::fsm::new_from_spec -spec $spec] + + return $workflow_id +} + + +ad_proc -public curriculum::workflow_short_name {} { + Get the short name of the workflow for curriculums. +} { + return "curriculum" +} + + +ad_proc -public curriculum::object_type {} { + Get the object_type of curriculum. +} { + return "cu_curriculum" +} + + +ad_proc -private curriculum::workflow_delete {} { + Delete the 'curriculum' workflow for curriculum. +} { + set workflow_id [get_package_workflow_id] + if { ![empty_string_p $workflow_id] } { + workflow::delete -workflow_id $workflow_id + } +} + + +ad_proc -public curriculum::get_package_workflow_id {} { + Return the workflow_id for the package (not instance) workflow. +} { + return [workflow::get_id \ + -short_name [workflow_short_name] \ + -package_key [package_key]] + +} + + +ad_proc -public curriculum::get_instance_workflow_id { + {-package_id {}} +} { + Return the workflow_id for the instance (not package) workflow. +} { + if { [empty_string_p $package_id] } { + set package_id [conn package_id] + } + + return [workflow::get_id \ + -short_name [workflow_short_name] \ + -object_id $package_id] +} + + +ad_proc -private curriculum::instance_workflow_create { + -package_id:required +} { + Creates a clone of the default curriculum package workflow for a + specific package instance. +} { + set workflow_id [workflow::fsm::clone \ + -workflow_id [get_package_workflow_id] \ + -object_id $package_id] + + return $workflow_id +} + + +ad_proc -private curriculum::instance_workflow_delete { + -package_id:required +} { + Deletes the instance workflow. +} { + workflow::delete -workflow_id [get_instance_workflow_id -package_id $package_id] +} + + +#### +# +# Curriculum owner. +# +#### + + +ad_proc -private curriculum::owner::pretty_name {} { + return "Curriculum owner" +} + + +ad_proc -private curriculum::owner::get_assignees { + case_id + object_id + role_id +} { + return [db_string select_curriculum_owner {*SQL*} -default {}] +} + + +#### +# +# Capture resolution code. (Useful if we need to perform side effects but not being used right now.) +# +#### + + +# FIXME +ad_proc -private curriculum::capture_resolution_code::pretty_name {} { + return "Capture resolution code in the case activity log" +} + + +ad_proc -private curriculum::capture_resolution_code::do_side_effect { + case_id + object_id + action_id + entry_id +} { + db_dml insert_resolution_code {*NOT WRITTEN YET*} +} + + +#### +# +# Format log title. +# +#### + + +ad_proc -private curriculum::format_log_title::pretty_name {} { + return "Add resolution code to log title" +} + + +ad_proc -private curriculum::format_log_title::format_log_title { + case_id + object_id + action_id + entry_id + data_arraylist +} { + array set data $data_arraylist + + if { [info exists data(resolution)] } { + return [resolution_pretty $data(resolution)] + } else { + return {WHAT?!} + } +} + + +# FIXME. Resolution ???? +ad_proc -private curriculum::resolution_get_options {} { + + return { + fixed "Fixed" + bydesign "By Design" + wontfix "Won't Fix" + postponed "Postponed" + duplicate "Duplicate" + norepro "Not Reproducable" + needinfo "Need Info" + } + +} + + +ad_proc -private curriculum::resolution_pretty { + resolution +} { + array set resolution_codes [resolution_get_options] + + if { [info exists resolution_codes($resolution)] } { + return $resolution_codes($resolution) + } else { + return {} + } +} + + +#### +# +# Notification info. +# +#### + + +ad_proc -private curriculum::notification_info::pretty_name {} { + return "Curriculum info" +} + + +# FIXME. +ad_proc -private curriculum::notification_info::get_notification_info { + case_id + object_id +} { +#### + return [list /my/test/url one_line {details_list testing} notification_subject_tag] + ad_script_abort +#### + + + bug_tracker::bug::get -bug_id $object_id -array bug + + set url "[ad_url][apm_package_url_from_id $bug(project_id)]bug?[export_vars { { bug_number $bug(bug_number) } }]" + + bug_tracker::get_pretty_names -array pretty_names + + set notification_subject_tag [db_string select_notification_tag {} -default {}] + + set one_line "$pretty_names(Bug) #$bug(bug_number): $bug(summary)" + + # Build up data structures with the form labels and values + # (Note, this is something that the metadata system should be able to do for us) + + array set label { + summary "Summary" + status "Status" + found_in_version "Found in version" + fix_for_version "Fix for version" + fixed_in_version "Fixed in version" + } + + set label(bug_number) "$pretty_names(Bug) #" + set label(component) "$pretty_names(Component)" + + set fields { + bug_number + component + } + + # keywords + foreach { category_id category_name } [bug_tracker::category_types] { + lappend fields $category_id + set value($category_id) [bug_tracker::category_heading \ + -keyword_id [cr::keyword::item_get_assigned -item_id $bug(bug_id) -parent_id $category_id] \ + -package_id $bug(project_id)] + set label($category_id) $category_name + } + + lappend fields summary status + + if { [bug_tracker::versions_p -package_id $bug(project_id)] } { + lappend fields found_in_version fix_for_version fixed_in_version + } + + set value(bug_number) $bug(bug_number) + set value(component) $bug(component_name) + set value(summary) $bug(summary) + set value(status) $bug(pretty_state) + set value(found_in_version) [ad_decode $bug(found_in_version_name) "" "Unknown" $bug(found_in_version_name)] + set value(fix_for_version) [ad_decode $bug(fix_for_version_name) "" "Undecided" $bug(fix_for_version_name)] + set value(fixed_in_version) [ad_decode $bug(fixed_in_version_name) "" "Unknown" $bug(fixed_in_version_name)] + + # Remove fields that should be hidden in this state + foreach field $bug(hide_fields) { + set index [lsearch -exact $fields $field] + if { $index != -1 } { + set fields [lreplace $fields $index $index] + } + } + + # Build up the details list + set details_list [list] + foreach field $fields { + lappend details_list $label($field) $value($field) + } + + return [list $url $one_line $details_list $notification_subject_tag] +} + + +ad_proc -public curriculum::get_watch_link { + {-curriculum_id:required} +} { + Get link for watching a curriculum. + @return 3-tuple of url, label and title. +} { + set user_id [ad_conn user_id] + set return_url [util_get_current_url] + + # Get the type id + set type "workflow_case" + set type_id [notification::type::get_type_id -short_name $type] + + # Check if subscribed + set request_id [notification::request::get_request_id \ + -type_id $type_id \ + -object_id $curriculum_id \ + -user_id $user_id] + + set subscribed_p [expr ![empty_string_p $request_id]] + + if { !$subscribed_p } { + set url [notification::display::subscribe_url \ + -type $type \ + -object_id $curriculum_id \ + -url $return_url \ + -user_id $user_id \ + -pretty_name "this curriculum"] + set label "Watch this curriculum" + set title "Request notifications for all activity on this curriculum" + } else { + set url [notification::display::unsubscribe_url -request_id $request_id -url $return_url] + set label "Stop watching this curriculum" + set title "Unsubscribe to notifications for activity on this curriculum" + } + return [list $url $label $title] +} + + +ad_proc -private curriculum::security_violation { + -user_id:required + -curriculum_id:required + -action:required +} { + ns_log Notice "$user_id doesn't have permission to '$action' on curriculum $curriculum_id" + ad_return_forbidden \ + "Security Violation" \ + "+ You don't have permission to '$action' on this curriculum. +" + ad_script_abort +} Index: openacs-4/packages/curriculum/tcl/curriculum-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/curriculum/tcl/curriculum-procs.xql,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/curriculum/tcl/curriculum-procs.xql 3 Jun 2003 10:28:20 -0000 1.1 @@ -0,0 +1,39 @@ + +
+ This incident has been logged. +
curriculum_id, name, url, description, desc_format, sort_key
+ + @param element_id The id of the element to retrieve information about. + @param array The name of the array in the callers scope where the information will + be stored. + + @return The return value from db_0or1row. If more than one row is returned, throws an error. + + @author Ola Hansson (ola@polyxena.net) + +} { + upvar $array row + + if { ![db_0or1row get_element_data {*SQL*} -column_array row] } { + # Query did not return a row. We should probably return an error instead. + return 0 + ad_script_abort + } + +# # Get the case ID, so we can get state information. +# set case_id [workflow::case::get_id \ +# -object_id $curriculum_id \ +# -workflow_short_name [workflow_short_name]] +# +# # Get state information. +# workflow::case::fsm::get -case_id $case_id -array case -action_id $action_id +# +# set row(pretty_state) $case(pretty_state) +# set row(state_short_name) $case(state_short_name) +# set row(hide_fields) $case(state_hide_fields) +# set row(entry_id) $case(entry_id) + + return 1 +} + + +ad_proc -public curriculum::element::delete { + {-element_id:required} +} { + + Delete a curriculum element. + + @param element_id The object-id of the element to delete. + + @return Nothing. + + @author Ola Hansson (ola@polyxena.net) + +} { + db_exec_plsql delete_element {*SQL*} +} Index: openacs-4/packages/curriculum/tcl/element-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/curriculum/tcl/element-procs.xql,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/curriculum/tcl/element-procs.xql 3 Jun 2003 10:28:20 -0000 1.1 @@ -0,0 +1,39 @@ + ++Here is what the database said: +
+$errmsg"
+ ad_script_abort
+
+ } else {
+
+ return $package_id
+ }
+}
+
+
+#####
+#
+# Cached curriculum info procs
+#
+#####
+
+
+ad_proc -private curriculum::get_curriculum_info {
+ {-package_id ""}
+} {
+ if { [empty_string_p $package_id] } {
+ set package_id [conn package_id]
+ }
+
+ return [db_list_of_ns_sets curriculum_info {*SQL*}]
+}
+
+
+#####
+#
+# Cached curriculum stats procs
+#
+#####
+
+
+ad_proc -private curriculum::get_curriculum_stats {
+ {-package_id ""}
+} {
+ if { [empty_string_p $package_id] } {
+ set package_id [conn package_id]
+ }
+
+ db_1row curriculum_stats {*SQL*} -column_array stats
+
+ return [array get stats]
+}
+
+
+#####
+#
+# Cached objective progress info procs
+#
+#####
+
+# FIXME. Not used.
+ad_proc -private curriculum::get_table_info {
+ -table:required
+} {
+ set user_id [ad_conn user_id]
+
+ db_multirow -local info table_info "
+ select *
+ from $table
+ where user_id = :user_id
+ " {} if_no_rows {
+
+ # Ack! No rows returned. Don't worry, we'll fall back on the defaults.
+ # If this query, too, returns nothing the "curriculum::conn ???"
+ # call we originated from will simply return an empty list.
+
+ set magic_user_id [magic_user]
+
+ db_0or1row info_fallback "
+ select *
+ from $table
+ where user_id = :magic_user_id
+ " -column_array info_fallback
+
+ return -code return [array get info_fallback]
+ }
+
+ # We have something. Convert it to array-settable list and then return it.
+ return [multirow_to_list_of_attrib_lists -var_name info]
+}
+
+
+#####
+#
+# Curriculum bar procs
+#
+#####
+
+
+ad_proc -public curriculum::enabled_elements_memoized {
+ {-package_id ""}
+} {
+ # "ad_conn package_id" can't be used because occasionally our proc gets
+ # called from a filter, and filters don't seem to handle such calls. :(
+
+ if { [empty_string_p $package_id] } {
+ set package_id [conn package_id]
+ }
+
+ set user_id [ad_conn user_id]
+
+ # Cache the bar per curriculum instance and user.
+ return [util_memoize [list curriculum::enabled_elements -package_id $package_id -user_id $user_id]]
+}
+
+
+ad_proc -private curriculum::enabled_elements {
+ {-package_id ""}
+ -user_id:required
+} {
+ This is designed to be called within a memoization proc.
+} {
+
+ # The list this proc returns will be cached and used for (at least)
+ # two purposes: A) To produce the curriculum bar multirow. B) To check
+ # elements against a cookie value to be able to mark if an element has
+ # been visited. Either way we only keep elements from curriculums in
+ # workflow state "published" in the list.
+
+ # "workflow::state::fsm::get_id" doesn't return the id of state "published" if there
+ # is no workflow, and there isn't one in "/"... That is why we feed this proc the
+ # package_id "curriculum::conn" gave us, which is the package_id of the curriculum
+ # instance in this subsite, regardless of what node we requested within the subsite.
+
+ if { ![empty_string_p $package_id] } {
+
+ # During normal operation, when a curriculum instance is mounted under the current
+ # subsite, the given package_id should be trustworthy ...
+
+ set workflow_id [curriculum::get_instance_workflow_id -package_id $package_id]
+
+ set state_id [workflow::state::fsm::get_id \
+ -workflow_id $workflow_id \
+ -short_name published]
+
+ } else {
+
+ # State id "0" does not exist, hence our query won't return any rows. Just what
+ # we want if there's no curriculum mounted in the subsite (as indicated by the
+ # empty package_id).
+
+ set state_id 0
+ }
+
+ # If the user is logged in, the "cu_user_curriculum_map" will give an indication
+ # as to which curriculums are UNWANTED by the user. If the user is not logged in
+ # we're showing all (published) curriculums in the instance (there should be no
+ # user_id "0" in the mapping table).
+
+ # FIXME. The PG version ought to look more like the Oracle version.
+ set ns_sets [db_list_of_ns_sets element_ns_set_list {*SQL*}]
+
+ return [util_list_of_ns_sets_to_list_of_lists -list_of_ns_sets $ns_sets]
+}
+
+
+# FIXME. Integrate with "enabled_elements" above?
+ad_proc -private curriculum::user_elements {
+} {
+ Not meant to be cached.
+} {
+ set package_id [conn package_id]
+
+ set workflow_id [curriculum::get_instance_workflow_id -package_id $package_id]
+
+ # We need to get elements of published curriculums.
+ set state_id [workflow::state::fsm::get_id \
+ -workflow_id $workflow_id \
+ -short_name published]
+
+ # We need user_id to join against the mapping table that holds information
+ # on what curriculums (in the package instance) the user care about.
+ set user_id [ad_conn user_id]
+
+ # FIXME. Add patameter.
+ set truncation_length 12
+
+ set ns_sets [db_list_of_ns_sets user_element_ns_set_list {*SQL*}]
+
+ return [util_list_of_ns_sets_to_list_of_lists -list_of_ns_sets $ns_sets]
+}
+
+
+ad_proc -public curriculum::elements_flush {
+ {-package_id ""}
+} {
+ Flushes the memoized proc that gets the element_id, url and name for the curriculum bar(s).
+ Should be run upon ceation, enabling, disabling or deletion of a curriculum or an element.
+} {
+ if { [empty_string_p $package_id] } {
+ set package_id [conn package_id]
+ }
+
+ # Only bother to flush the cache if the bar is going to be displayed.
+ if { ![parameter::get -package_id $package_id -parameter ShowCurriculumBarP -default 1] } {
+ return {}
+ }
+
+ set user_id [ad_conn user_id]
+
+ util_memoize_flush "curriculum::enabled_elements -package_id $package_id -user_id $user_id"
+}
+
+
+ad_proc -public curriculum::get_bar {
+ -bar_p:required
+} {
+ Returns a string containing the HTML for a curriculum bar that shows the amount of progress a user has made on a curriculum.
+} {
+ set package_id [conn package_id]
+
+ # Is the curriculum bar even activated? If not, return the empty string.
+ if { $bar_p && ![parameter::get -package_id $package_id -parameter ShowCurriculumBarP -default 1] } {
+ return {}
+ }
+
+ # Check cookie to make sure this person isn't finished.
+ set input_cookie [ad_get_cookie [get_cookie_name]]
+
+ if { $bar_p && [empty_string_p $input_cookie] } {
+ # No cookie; this person is either brand new or the browser is rejecting cookies.
+ # Let's not uglify all their pages with a bar that they can't use.
+ #return {}
+ }
+
+ # We have a cookie.
+ if { $bar_p && [string equal "finished" $input_cookie] } {
+ # User has completed curriculum, don't bother showing the bar.
+ #return {}
+ }
+
+ # Compare what the user has seen to what is in the full curriculum(s)
+ # to put in checkboxes; we check the output headers first and then
+ # the input headers, in case there is going to be a newer value.
+ set output_cookie [get_output_cookie]
+
+ if { [empty_string_p $output_cookie] } {
+ get_bar_internal -bar_p $bar_p $input_cookie
+ } else {
+ get_bar_internal -bar_p $bar_p $output_cookie
+ }
+}
+
+
+ad_proc -private curriculum::get_bar_internal {
+ -bar_p:required
+ cookie_value
+} {
+ if { $bar_p } {
+
+ # Get the cached curriculum list for the bar.
+ set rows [enabled_elements_memoized]
+
+ } else {
+
+ # Get the NOT cached curriculum list for index page use.
+ set rows [user_elements]
+
+ }
+
+ # If the user is logged in the "cu_user_curriculum_map" will be checked
+ # for unwanted curriculums. OTOH, if the user is not logged in, we're
+ # showing all (published) curriculums.
+ # See "curriculum::enabled_elements" (the non-cached variant).
+
+ if { [llength $rows] == 0 } {
+ # Publisher hasn't published any curriculum.
+ return {}
+ }
+
+ set manipulated_rows {}
+
+ foreach row $rows {
+ array set element_info $row
+
+ # Check in cookie whether the element has been visited or not.
+ if { [lsearch -exact $cookie_value $element_info(element_id)] != -1 } {
+ set row [concat $row checked_p 1]
+ } else {
+ set row [concat $row checked_p 0]
+ }
+
+ # FIXME. Should be performed by the db!
+ # Check for external URLs.
+ if { [string equal -length 7 "http://" $element_info(url) ] } {
+ set row [concat $row external_p 1]
+ } else {
+ set row [concat $row external_p 0]
+ }
+
+ lappend manipulated_rows $row
+ }
+
+ # DEBUG.
+# if {!$bar_p} {doc_return 200 text/plain "$cookie_value"}
+
+ # Let's turn this list into a multirow datasource in the
+ col1 {row1 row2 ...} col2 {row1 row2 ...} col3 {row1 row2 ...} ...
+
+
+ @param -var_name The name of the multirow to convert
+
+ @author Ola Hansson (ola@polyxena.net)
+ @creation-date January 07, 2003
+} {
+ upvar $var_name:rowcount rowcount $var_name:columns columns i i
+
+ for { set i 1 } { $i <= $rowcount } { incr i } {
+ upvar $var_name:$i row
+ foreach column [set columns] {
+ lappend $column $row($column)
+ }
+ }
+
+ foreach column $columns {
+ lappend result $column [set $column]
+ }
+
+ return $result
+}
+
+
+# FIXME. Not used.
+ad_proc -private curriculum::magic_user {
+} {
+ # Magic user_id.
+ return [db_exec_plsql get_magic_user_id {select cu_magic_user()}]
+}
Index: openacs-4/packages/curriculum/tcl/misc-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/curriculum/tcl/misc-procs.xql,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/curriculum/tcl/misc-procs.xql 3 Jun 2003 10:28:20 -0000 1.1
@@ -0,0 +1,31 @@
+
+