Index: openacs-4/packages/xowf/lib/online-exam-answer.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/online-exam-answer.wf,v diff -u -r1.1 -r1.2 --- openacs-4/packages/xowf/lib/online-exam-answer.wf 28 Aug 2014 08:24:56 -0000 1.1 +++ openacs-4/packages/xowf/lib/online-exam-answer.wf 14 Sep 2017 09:22:22 -0000 1.2 @@ -13,15 +13,15 @@ # Template variables: # @wfTitle@ # @wfQuestionNames@ +# @wfQuestionTitles@ # @wfID@ my set autoname 1 my set debug 1 -set object [my set object] -set package_id [$object package_id] set pages [list @wfQuestionNames@] +set titles [list @wfQuestionTitles@] ######################################################################## # @@ -37,18 +37,29 @@ ######################################################################## Property pages -default $pages +Property titles -default $titles Property position -default 0 -allow_query_parameter true Property return_url -default "" -allow_query_parameter true Property try_out_mode -default 0 -allow_query_parameter true Property current_form -default "" Property ip -default [expr {[ns_conn isconnected] ? [ad_conn peeraddr] : "nowhere"}] Condition more_ahead \ - -expr {[my property position] < [llength [my property pages]]-1} + -expr {[$obj property position] < [llength [$obj property pages]]-1} Condition more_before \ - -expr {[my property position] > 0} + -expr {[$obj property position] > 0} +set page_count 1 +set page_actions {} +foreach page $pages { + Action $page_count \ + -next_state working \ + -label "$page_count" \ + -proc activate {obj} [list my goto_page [expr {$page_count -1}]] + lappend page_actions $page_count + incr page_count +} ######################################################################## # # Action definitions @@ -59,13 +70,13 @@ #my msg "allocate $obj" # Called, when we try to create or use a workflow instance # via a workflow definition ($obj is a workflow definition) - my set_new_property name ___[::xo::cc set untrusted_user_id] + $obj set_property -new 1 name ___[::xo::cc set untrusted_user_id] } Action initialize -proc activate {obj} { # called, after workflow instance was created - my set_new_property _title "@wfTitle@" + $obj set_property -new 1 _title "@wfTitle@" set parent_id [$obj parent_id] set package_id [$obj package_id] @@ -78,9 +89,9 @@ # is not published (e.g. trial mode, or closed) or when try-out-mode # is not set # - if {$parent_state ne "published" && [my property try_out_mode 0] == 0} { + if {$parent_state ne "published" && [$obj property try_out_mode 0] == 0} { #my msg "LOCKED" - set current_state [my property _state] + set current_state [$obj property _state] set lockin_state [expr {$current_state eq "initial" ? "initial" : "done"}] set lockin_msg(initial) "Die Prüfung ist von der Aufsicht nicht freigegeben!" set lockin_msg(done) "Die Prüfungszeit ist abgelaufen!" @@ -96,6 +107,11 @@ } } +Action instproc goto_page {position} { + set pages [my property pages] + my set_property position $position + my set_property current_form [lindex $pages $position] +} Action instproc set_page {increment} { set pages [my property pages] set position [my property position 0] @@ -130,29 +146,29 @@ -label "Prüfung verlassen" \ -proc activate {obj} { set pid [$obj package_id] - set try_out_mode [my property try_out_mode 0] - set return_url [my property return_url .] + set try_out_mode [$obj property try_out_mode 0] + set return_url [$obj property return_url .] #my msg "tryout $try_out_mode return_url $return_url" if {$try_out_mode} { - ad_returnredirect $return_url + ad_returnredirect $return_url } else { - ::xo::cc set_parameter return_url /register/logout?return_url=$return_url + ::xo::cc set_parameter return_url /register/logout?return_url=$return_url } } Action start \ -next_state working \ -label Beginnen \ -proc activate {obj} { - my set_property position 0 - my set_property current_form [lindex [my property pages] 0] + $obj set_property position 0 + $obj set_property current_form [lindex [$obj property pages] 0] } Action start_again \ -label "Erste Frage" \ -next_state working -proc activate {obj} { - my set_property position 0 - my set_property current_form [lindex [my property pages] 0] + $obj set_property position 0 + $obj set_property current_form [lindex [$obj property pages] 0] } ######################################################################## @@ -170,10 +186,12 @@ ../file:seal.js?m=download }}} -State working -form [my property current_form] +State working +working set page_actions $page_actions working proc actions {} { set actions "" if {[more_before]} {lappend actions prev} + set actions [concat $actions [my set page_actions]] if {[more_ahead]} {lappend actions next} lappend actions save abgabe } @@ -182,91 +200,105 @@ -actions {start logout} \ -form "../en:exam-start" +set done_actions [concat $page_actions {start_again logout}] State done \ - -actions {start_again logout} \ + -actions $done_actions \ -form "../en:exam-done" \ -form_loader summary_form -######################################################################## -# -# Helper methods for the workflow context -# -######################################################################## +:object-specific { + set ctx [:wf_context] + set working_state_object [$ctx wf_definition_object working] + $working_state_object set form [:property current_form] + # fallback if the current_form isn't set + if {[$working_state_object set form] eq ""} { + $working_state_object set form [lindex [:property pages] 0] + } -# -# Overload default form loader to rename the input fields -# to avoid name clashes -# -my proc default_form_loader {form_name} { - #my msg "renaming_form_loader $form_name" - set form_id [next] - ::xo::db::CrClass get_instance_from_db -item_id $form_id + ######################################################################## + # + # Helper methods for the workflow context + # + ######################################################################## - set form [$form_id get_property -name form] - set prefix [lindex [split [$form_id name] :] end]-a - set counter 0 - set fc [my get_form_constraints] - dom parse -simple -html $form doc - $doc documentElement root - if {$root ne ""} { - foreach node [$root selectNodes "//textarea|//input"] { - set newName $prefix[incr counter] - $node setAttribute name $newName - #lappend fc $newName:richtext,editor=xinha,slim=true + # + # Overload default form loader to rename the input fields + # to avoid name clashes + # + $ctx proc default_load_form_id {form_name} { + #my msg "renaming_form_loader $form_name" + set form_id [next] + ::xo::db::CrClass get_instance_from_db -item_id $form_id + + set form [$form_id get_property -name form] + set prefix [lindex [split [$form_id name] :] end]-a + set counter 0 + set fc [my get_form_constraints] + lappend fc @cr_fields:hidden + dom parse -simple -html $form doc + $doc documentElement root + if {$root ne ""} { + $root setAttribute id "online-exam-answer" + foreach node [$root selectNodes "//textarea|//input"] { + set newName $prefix[incr counter] + $node setAttribute name $newName + #lappend fc $newName:richtext,editor=xinha,slim=true + } + $form_id set_property form [$root asHTML] } - $form_id set_property form [$root asHTML] + # Currently, the computation and setting of the form_constraints has + # no effect, when the input field is provided raw in the form + # (e.g. as a handcoded textarea). We set it anyhow here for future + # use + $form_id set_property -new 1 form_constraints $fc + my set_title -question 1 + return $form_id } - # Currently, the computation and setting of the form_constraints has - # no effect, when the input field is provided raw in the form - # (e.g. as a handcoded textarea). We set it anyhow here for future - # use - $form_id set_property -new 1 form_constraints $fc - my set_title -question 1 - return $form_id -} -# -# set title with question and user information -# -my proc set_title {{-question 1}} { - set t [list ] - set object [my object] - set state [$object state] - if {$question && $state eq "working"} {lappend title "Frage [expr {[my property position] + 1}]"} - lappend title \ - "@wfTitle@" \ - "IP: [$object property ip]" + # + # set title with question and user information + # + $ctx proc set_title {{-question 1}} { + set t [list ] + set state [${:object} state] + set position [${:object} property position] + if {$question && $state eq "working"} {lappend title "Frage [expr {$position + 1}] [lindex [${:object} property titles] $position]"} + lappend title \ + "@wfTitle@" \ + "IP: [${:object} property ip]" - $object title [join $title " / "] -} + ${:object} title [join $title " / "] + } -# -# Form loader for summary -# -my proc summary_form {form_title} { - #my msg "summary_form_loader $form_title" + # + # Form loader for summary + # + $ctx proc summary_form {form_title} { + #my msg "summary_form_loader $form_title" - my set_title -question 0 - set state [my property _state] + my set_title -question 0 + set state [${:object} property _state] - set summary_form "" - set counter 0 - foreach form_name [my property pages] { - set form_id [my default_form_loader $form_name] - append summary_form

Frage [incr counter]

\n - append summary_form [$form_id property form] \n
\n - } - - # disable all input fields and remove wrapping form - regsub -all {|} $answer {

} answer + regsub -all {
} $answer {} answer + regsub -all {IP\: (.*)} $title "$ia(ip)" title + append HTML "

$title

$text$answer
" + } } + if {$HTML ne ""} { + ns_return 200 text/html " + + + + + $HTML + + " + } else { + util_user_message -html -message "No answer data available" + ad_returnredirect [::xo::cc url] + } } - if {$HTML ne ""} { - ns_return 200 text/html $HTML - } else { - util_user_message -html -message "No answer data available" - ad_returnredirect [::xo::cc url] + + ######################################################################## + # answer: answer the exam; this is a conveniance routine to shorten + # the published URL; make sure, that no-one trys to start the answer + # workflow in a state different to "published" + # + :proc www-answer {} { + if {[my property _state] ne "published"} { + util_user_message -html -message "Cannot start answer workflow in this state" + } else { + set ctx [::xowf::Context require [self]] + set wf [[$ctx wf_container] get_answer_wf [self]] + $wf www-create-or-use -parent_id [my item_id] + } } -} -######################################################################## -# answer: answer the exam; this is a conveniance routine to shorten -# the published URL; make sure, that no-one trys to start the answer -# workflow in a state different to "published" -# -[my object] proc answer {} { - if {[my property _state] ne "published"} { - util_user_message -html -message "Cannot start answer workflow in this state" - } else { - set ctx [::xowf::Context require [self]] - set wf [$ctx get_answer_wf [self]] - $wf create-or-use + :proc -deprecated answer {args} { + ad_log warning "????? who is calling me?" + :www-answer {*}$args } + + ######################################################################## + # + # Helper methods for the workflow context + # + ######################################################################## + + set ctx [:wf_context] + + ######################################################################## + # form loader: create dynamically a form containing the disabled + # questions and the survey results (the results can be refreshed) + # + $ctx proc load_form {title} { + set state [my property _state] + + set questions [my get_questions] + set counter 0 + set fullQuestionForm "" + foreach q $questions { + append fullQuestionForm \ + "

Frage [incr counter]

\n" \ + [$q property form] + } + + # disable fields, remove wrapping form + regsub -all {]*>} $fullQuestionForm {} fullQuestionForm + + set text "

$title

" + set obj ${:object} + + set wf [[:wf_container] get_answer_wf $obj] + if {$wf eq ""} { + my msg "cannot get current workflow for [$obj name]" + set lLink "." + set tLink "." + set aLink "." + set pLink "." + set menu "" + } else { + set wf_pretty_link [$wf pretty_link] + set tLink "$wf_pretty_link?m=create-new&p.return_url=[::xo::cc url]&p.try_out_mode=1" + set lLink "$wf_pretty_link?m=list" + set aLink "[$obj pretty_link]?m=answer" + set pLink "[$obj pretty_link]?m=print-answers" + #util_user_message -html -message "$survey is available as $pLink" + set menu "\[refresh,\ + listing,\ + print\]" + } + + set extraAction "" + switch [my property _state] { + "created" {set extraAction "
Do you want to try out the exam?"} + "published" {set extraAction "
Students can now answer via $aLink"} + } + append text "$menu $extraAction\n" + + set style "background: #cccccc; padding: 10px; margin:10px;" + set report "" + set wfName [my property wfName] + if {$wfName ne ""} {set report "{{form-stats -parent_id [$obj item_id] -form $wfName}}\n"} + append report "
$menu" + + set f [::xowiki::Form new \ + -set name en:quesiton \ + -form [subst {
$text
$fullQuestionForm
$report
text/html}] \ + -text {} \ + -anon_instances t \ + -form_constraints {@cr_fields:hidden} \ + ] + } + + ######################################################################## + # get_question: load and initialize the interaction forms + # + $ctx proc get_questions {} { + set questionNames [join [my property question] |] + set questionForms [::xowiki::Weblog instantiate_forms \ + -parent_id [${:object} parent_id] -package_id [${:object} package_id] \ + -default_lang [${:object} lang] \ + -forms $questionNames] + if {[llength $questionForms] < 1} {error "unknown form $questionNames"} + #my msg "questionNames '$questionNames', questionForms 'questionForms'" + return $questionForms + } } #