Index: openacs-4/packages/xowf/lib/online-exam.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/online-exam.wf,v diff -u -r1.6.2.4 -r1.6.2.5 --- openacs-4/packages/xowf/lib/online-exam.wf 9 Aug 2019 20:19:04 -0000 1.6.2.4 +++ openacs-4/packages/xowf/lib/online-exam.wf 15 Oct 2019 21:41:45 -0000 1.6.2.5 @@ -1,57 +1,72 @@ # -*- Tcl -*- ######################################################################## # Online-Exam workflow, designed similar to mobile-clicker +# ======================================================== # # This workflow lets a teacher choose from a predefined set of exam -# questions, which are typically open text questions. The user -# selects one ore several exam question via drag and drop The teacher +# questions, which are typically open text questions. The teacher +# selects one or several exam question via drag and drop. The teacher # can test the exam by entering test answers. The results are provided # in form of a table. # -# When the teacher has finished testing of the exam, the exam can be +# When the teacher is satisfied for the exam, the exam can be # published. In this step, all answers of the testing phase are # deleted. In the process of publishing, the link to start the exam is # offered to the user. When the exam is published, the teacher can # see the incoming answers in the report by refreshing the page. When # the exam is done, it is unpublished. The workflow offers the teacher # to see a summary of the results in form of a table (an to download -# the results via csv), or he can produce a printer friendly version -# of the answers. +# the results via csv), or the teacher can produce a printer friendly +# version of the answers. # +# You might with to add the following entries to the folder to ease +# creation of exercises and exams +# +# OLD HTML variant +# {entry -name New.App.Frage -label TextQuestion -form en:Frage.form} +# +# NEW question types +# +# {entry -name New.App.TextInteraction -label "Text Interaction" -form en:TestItemText.form} +# {entry -name New.App.TextEntryInteraction -label "Text Entry Interaction" -form en:TestItemTextEntry.form} +# {entry -name New.App.MCInteraction -label "MC Interaction" -form en:TestItemMC.form} +# {entry -name New.App.Exam -label Exam -form en:online-exam.wf} +# # Gustaf Neumann, Feb 2012 ######################################################################## set :autoname 1 set :debug 1 -set :masterWorkflow //xowf/de:workflow.wf +#set :masterWorkflow //xowf/de:workflow.wf +set :masterWorkflow en:Workflow.form -Action select -next_state created -label {Erstelle Prüfung} -Action publish -next_state published -label {Schalte Prüfung frei} -Action unpublish -next_state done -label {Schließe Prüfung} -Action republish -next_state published -label {Schalte Prüfung nochmals frei} -Action restart -next_state initial +Action select -next_state created -label #xowf.online-exam-select# +Action publish -next_state published -label #xowf.online-exam-publish# +Action unpublish -next_state done -label #xowf.online-exam-unpublish# +Action republish -next_state published -label #xowf.online-exam-republish# +Action restart -next_state initial -label #xowf.restart# -State initial -actions {select} -form en:select_question.form -view_method edit +State initial -actions {select} -form en:select_question.form -view_method edit State created -actions {publish restart} -form_loader load_form -view_method edit \ - -form "Prüfungsentwurf (Prüfung nicht freigeschaltet)" + -form "#xowf.online-exam-draft_exam#" State published -actions {unpublish} -form_loader load_form -view_method edit \ - -form "Prüfung ist freigeschaltet" + -form "#xowf.online-exam-open#" State done -actions {republish restart} -form_loader load_form -view_method edit \ - -form "Die Prüfung ist geschlossen." + -form "#xowf.online-exam-closed#" ######################################################################## # Activate action select: After the teacher has selected the # exercises, the answer workflow is created. # select proc activate {obj} { - [[:wf_context] wf_container] create_answer_workflow $obj + [[$obj wf_context] wf_container] create_answer_workflow $obj } ######################################################################## # Activate action publish: delete all responses for the workflow and # publish user participation link. # publish proc activate {obj} { - [[:wf_context] wf_container] delete_all_answer_data $obj + [[$obj wf_context] wf_container] delete_all_answer_data $obj :publish_link $obj } @@ -76,8 +91,8 @@ # students. The name of the workflow is derived from the wokflow # instance and recorded in the formfield "wfName". # -my proc create_answer_workflow {obj} { - :log "create_answer_workflow $obj" +:proc create_answer_workflow {obj} { + #:log "create_answer_workflow $obj" # first delete workflow and data, when it exists if {[$obj property wfName] ne ""} { @@ -91,7 +106,7 @@ set wfMaster ${:masterWorkflow} set wfTitle [$obj property _title] - set questionObjs [[:wf_context] get_questions] + set questionObjs [[$obj wf_context] get_questions] set wfQuestionNames {} set wfQuestionTitles {} set attributeNames {} @@ -102,8 +117,8 @@ $doc documentElement root if {$root ne ""} { foreach node [$root selectNodes "//textarea|//input"] { - set newName $prefix[incr counter] - lappend attributeNames $newName + set newName $prefix[incr counter] + lappend attributeNames $newName } } lappend wfQuestionNames ../[$q name] @@ -120,27 +135,28 @@ }] set attributeNames [join $attributeNames ,] + #:log "create workflow by filling out form '$wfMaster'" set WF [::xowiki::Weblog instantiate_forms \ - -parent_id [$obj parent_id] -package_id [$obj package_id] \ - -default_lang [$obj lang] \ - -forms $wfMaster] + -parent_id [$obj parent_id] -package_id [$obj package_id] \ + -default_lang [$obj lang] \ + -forms $wfMaster] set f [$WF create_form_page_instance \ - -name $wfName \ - -nls_language [$obj nls_language] \ + -name $wfName \ + -nls_language [$obj nls_language] \ -publish_status ready \ - -parent_id [$obj item_id] \ - -package_id [$obj package_id] \ - -default_variables [list title $wfTitle] \ - -instance_attributes [list workflow_definition $wfDef \ - form_constraints "@table:_name,_state,$attributeNames @cr_fields:hidden"]] + -parent_id [$obj item_id] \ + -package_id [$obj package_id] \ + -default_variables [list title $wfTitle] \ + -instance_attributes [list workflow_definition $wfDef \ + form_constraints "@table:_name,_state,$attributeNames @cr_fields:hidden"]] $f save_new - :log "create_answer_workflow $obj DONE [$f pretty_link]" + #:log "create_answer_workflow $obj DONE [$f pretty_link]" } ######################################################################## # get_answer_wf: return the workflow denoted by the property wfName in obj # -my proc get_answer_wf {obj} { +:proc get_answer_wf {obj} { return [::xowiki::Weblog instantiate_forms \ -parent_id [$obj item_id] -package_id [$obj package_id] \ -default_lang [$obj lang] \ @@ -150,7 +166,7 @@ ######################################################################## # get_wf_instances: return the workflow instances # -my proc get_wf_instances {{-initialize false} wf} { +:proc get_wf_instances {{-initialize false} wf} { return [::xowiki::FormPage get_form_entries \ -base_item_ids [$wf item_id] -form_fields "" \ -always_queried_attributes "*" -initialize $initialize \ @@ -160,7 +176,7 @@ ######################################################################## # delete_all_answer_data: delete all instances of the answer workflow # -my proc delete_all_answer_data {obj} { +:proc delete_all_answer_data {obj} { set wf [:get_answer_wf $obj] if {$wf ne ""} { set items [:get_wf_instances -initialize false $wf] @@ -174,7 +190,7 @@ # target group # Action instproc publish_link {obj} { - set aLink "[$obj pretty_link]?m=answer" + set aLink [$obj pretty_link -query m=answer] util_user_message -html -message "[$obj name] is available as [ns_quotehtml $aLink]" # TODO: make it happen } @@ -188,27 +204,136 @@ # TODO: make it happen } + + +######################################################################## +# +# Helper methods for the workflow context +# +######################################################################## + +######################################################################## +# form loader: create dynamically a form containing the disabled +# questions and the survey results (the results can be refreshed) +# +:proc load_form {title} { + set state [:property _state] + + set questions [:get_questions] + set counter 0 + set fullQuestionForm "" + foreach q $questions { + append fullQuestionForm \ + "

#xowf.question# [incr counter]

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

$title

" + + set wf [[:wf_container] get_answer_wf ${:object}] + if {$wf eq ""} { + :msg "cannot get current workflow for [${:object} 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 [${:object} pretty_link -query m=answer] + set pLink [${:object} pretty_link -query m=print-answers] + #util_user_message -html -message "$survey is available as $pLink" + set menu "\[#xowf.refresh#,\ + #xowf.online-exam-exam_instances#,\ + #xowf.print#\]" + } + + set extraAction "" + switch [:property _state] { + "created" { + set extraAction "
#xowf.online-exam-try_out# #xowf.testrun#" + } + "published" { + set extraAction "
#xowf.online-exam-can_answer# $aLink" + } + } + append text "$menu $extraAction\n" + + set wfName [:property wfName] + set report [expr {$wfName ne "" + ? "{{form-stats -parent_id [${:object} item_id] -form $wfName}}\n" + : ""}] + append report "
$menu" + + set style "background: #dddddd; padding: 10px; margin:10px;" + set f [::xowiki::Form new \ + -set name en:question \ + -form [subst {
$text
$fullQuestionForm
$report
text/html}] \ + -text {} \ + -anon_instances t \ + -form_constraints {@cr_fields:hidden answer:disabled,label=#xowf.answer#} \ + ] +} + +######################################################################## +# get_question: load and initialize the interaction forms +# +:proc get_questions {} { + set questions [lmap ref [:property question] { + if {![string match "*/*" $ref]} { + set ref [[${:object} parent_id] name]/$ref + } + set ref + }] + set questionNames [join $questions |] + set questionForms [::xowiki::Weblog instantiate_forms \ + -package_id [${:object} package_id] \ + -default_lang [${:object} lang] \ + -forms $questionNames] + if {[llength $questionForms] < 1} { + error "unknown form $questionNames" + } + #:msg "questionNames '$questionNames', questionForms 'questionForms'" + return $questionForms +} + + + +######################################################################## +# +# Object specific operations +# +######################################################################## + :object-specific { ######################################################################## # Extern callable methods ######################################################################## ######################################################################## - # delete: delete the workflow instance and all its associated data + # web-callable method "delete" # + # Delete the workflow instance and all its associated data. + # :proc www-delete {} { set ctx [::xowf::Context require [self]] [$ctx wf_container] delete_all_answer_data [self] next } - :proc -deprecated delete {} { - :www-delete - } - ######################################################################## - # print-answers: print the answers in a somewhat printer friendly way + # web-callable method "print-answers" # + # Print the answers in a somewhat printer friendly way. + # :proc www-print-answers {} { set HTML "" set ctx [::xowf::Context require [self]] @@ -220,41 +345,70 @@ set pretty_date [clock format [clock scan $time] -format "%Y-%m-%d %T"] set uid [$i property _creation_user] set text "

[acs_user::get_element -user_id $uid -element username] / [::xo::get_user_name $uid] / $pretty_date

" + # + # The call to "render_content" calls actually the + # "summary_form" of the oneline-exam-answer workflow. + # + $i set __feedback_mode 2 set question_form [$i render_content] + set answer $question_form set title [$i title] array set ia [$i set instance_attributes] regsub -all {
|} $answer {

} answer + #regsub -all {|} $answer {

} answer + regsub -all {