Index: openacs-4/packages/acs-core-docs/www/xml/kernel/ext-auth-design.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/xml/kernel/ext-auth-design.xml,v diff -u -N -r1.13.2.2 -r1.13.2.3 --- openacs-4/packages/acs-core-docs/www/xml/kernel/ext-auth-design.xml 9 Aug 2019 20:04:23 -0000 1.13.2.2 +++ openacs-4/packages/acs-core-docs/www/xml/kernel/ext-auth-design.xml 17 Dec 2019 16:37:50 -0000 1.13.2.3 @@ -11,42 +11,42 @@ EXT-AUTH-1: Authentication and Account Status API (4 hours) - by + by Peter Marklund - + Current Design Procedures to support this feature have already been written by Lars. We are using the existing procedure ad_user_login and are deprecating ad_maybe_redirect_for_registration and making it invoke - auth::require_login. + auth::require_login. Execution Story The auth::authenticate procedure will be called by the login page and the auth::require_login procedure at the beginning of any - application pages that require login. + application pages that require login. Tradeoffs: - For this feature reliability and testing are the prime concerns. + For this feature reliability and testing are the prime concerns. External Design - The authtentication API has the following public methods: + The authtentication API has the following public methods: ad_proc -public auth::require_login {} { - If the current session is not authenticated, redirect to the + If the current session is not authenticated, redirect to the login page, and aborts the current page script. Otherwise, returns the user_id of the user logged in. - Use this in a page script to ensure that only registered and authenticated + Use this in a page script to ensure that only registered and authenticated users can execute the page, for example for posting to a forum. @return user_id of user, if the user is logged in. Otherwise will issue an ad_script_abort. @see ad_script_abort @@ -60,13 +60,13 @@ {-username:required} {-password:required} } { - Try to authenticate and login the user forever by validating the username/password combination, - and return authentication and account status codes. - + Try to authenticate and login the user forever by validating the username/password combination, + and return authentication and account status codes. + @param authority_id The ID of the authority to ask to verify the user. Defaults to local authority. @param username Authority specific username of the user. @param password The password as the user entered it. - + } @@ -79,7 +79,7 @@ Procedure auth::authenticate - Need to stub ns_sendmail? + Need to stub ns_sendmail? Test auth_status not "ok" for: @@ -96,7 +96,7 @@ - + Test account_status "closed" for @@ -106,7 +106,7 @@ - + Error handling (requires stubbing the Authenticate service contract): @@ -130,18 +130,18 @@ - + Page Flow - None + None Data Model - None + None TODO @@ -163,7 +163,7 @@ </itemizedlist> </sect3> </sect2> - + <sect2> <sect2info> <title>EXT-AUTH-3: Account Creation API (5 hours) @@ -174,17 +174,17 @@ <title>EXT-AUTH-3: Account Creation API (5 hours) - by + by Peter Marklund - + Current API -ad_proc ad_user_new {email first_names last_name password password_question password_answer +ad_proc ad_user_new {email first_names last_name password password_question password_answer {url ""} {email_verified_p "t"} {member_state "approved"} {user_id ""} } { Creates a new user in the system. The user_id can be specified as an argument to enable double click protection. If this procedure succeeds, returns the new user_id. Otherwise, returns 0. @@ -221,7 +221,7 @@ the authority with lowest sort_order that has register_p set to true. } { set authorities_list [list] - + # Always register the user locally lappend authorities_list [auth::authority::local] # Default authority_id if none was provided @@ -238,9 +238,9 @@ } -default ""] if { $authority_id eq "" } { error "No authority_id provided and could not find an authority that can create users" - } + } lappend authorities_list $authority_id - } + } # Register the user both with the local authority and the external one db_transaction { foreach authority_id $authorities_list { @@ -325,12 +325,12 @@ acs-subsite/www/register/user-new.tcl. Again, all logic is in the pages. - + External Design - We will have to rewrite the following pages: + We will have to rewrite the following pages: User login: /register/index @@ -357,7 +357,7 @@ The code to handle the login process in /register/index.tcl would -look like this: +look like this: ad_form -name user_add -form { {authority_id:integer(hidden)} @@ -436,7 +436,7 @@ user-login.tcl. If user not registered (i.e. $auth_info(account_status) eq "no_account" ), - user is redirected to user-register.tcl. + user is redirected to user-register.tcl. Error Handling @@ -446,7 +446,7 @@ <literal>auth::authenticate </literal> - Returns the array element auth_status, which can either be: + Returns the array element auth_status, which can either be: ok: login was successful, continue @@ -475,7 +475,7 @@ - Also account_status is returned, which can either be: + Also account_status is returned, which can either be: ok: login was successful, continue @@ -498,7 +498,7 @@ auth::register - Returns the array element reg_status, which can either be: + Returns the array element reg_status, which can either be: ok: Registration was successful, continue @@ -560,7 +560,7 @@ - + Execution Story User login scenario: @@ -625,13 +625,13 @@ Otherwise, no "Change my password" link. - + The change password page will call the Password Management API to change the password. - + @@ -657,9 +657,9 @@ ad_proc -public auth::password::can_change_p { {-user_id:required} } { - Returns whether the given user change password. - This depends on the user's authority and the configuration of that authority. - + Returns whether the given user change password. + This depends on the user's authority and the configuration of that authority. + @param user_id The ID of the user whose password you want to change. @return 1 if the user can change password, 0 otherwise. } { @@ -674,7 +674,7 @@ Change the user's password. @param user_id The ID of the user whose password you want to change. @param old_password The current password of that user. This is required for security purposes. - + @param new_password The desired new password of the user. @return An array list with the following entries: <ul> @@ -689,20 +689,20 @@ } ad_proc -public auth::password::get_forgotten_url { {-authority_id:required} -} { +} { Returns the URL to redirect to for forgotten passwords. If the user's authority has a "forgotten_pwd_url" set, it'll return that, otherwise it'll return a link to /register/email-password under the nearest subsite. - + @param authority_id The ID of the authority that the user is trying to log into. @return A URL that can be linked to when the user has forgotten his/her password. } - ad_proc -public auth::password::can_retrieve_p { {-authority_id:required} } { - Returns whether the given authority can retrieve forgotten passwords. - + Returns whether the given authority can retrieve forgotten passwords. + @param authority_id The ID of the authority that the user is trying to log into. @return 1 if the authority allows retrieving passwords, 0 otherwise. } { @@ -730,8 +730,8 @@ ad_proc -public auth::password::can_reset_p { {-authority_id:required} } { - Returns whether the given authority can reset forgotten passwords. - + Returns whether the given authority can reset forgotten passwords. + @param authority_id The ID of the authority that the user is trying to log into. @return 1 if the authority allows resetting passwords, 0 otherwise. } { @@ -758,7 +758,7 @@ returned, it means that caller is responsible for informing the user of his/her new password.</li> </ul> -} { +} { # Implementation note # Calls auth::password::ResetPassword(authority_id, username) for the user's authority. } @@ -809,7 +809,7 @@ - + #29, service contract for password mgmt, will have to change as implied by the return values of this API. @@ -850,7 +850,7 @@ - + EXT-AUTH @@ -932,27 +932,27 @@ through all enabled and batch-enabled authorities and calls <literal>auth::authority::batch_sync -authority_id integer -</literal>. +</literal>. </sect4> </sect3> <sect3> <title>Internal Design - Administration + Administration ad_proc -public auth::authority::enable_batch_sync { -authority_id } { - db_dml toggle_enbaled_p { + db_dml toggle_enbaled_p { update some_table set batch_sync_enabled_p = 't' where authority_id = :authority_id } } - Scheduled proc: + Scheduled proc: ad_proc -public auth::batch_sync_sweeper {} { db_foreach select_authorities { @@ -998,7 +998,7 @@ calls auth::authentication::Authenticate which invokes - the service contract implementation for the authority. Returns: + the service contract implementation for the authority. Returns: auth_status: "ok", "bad_password", "no_account", @@ -1036,7 +1036,7 @@ Invoke the Authenticate service contract operation for the given authority. @param username Username of the user. @param password The password as the user entered it. - + @param authority_id The ID of the authority to ask to verify the user. Leave blank for local authority. } { if { $authority_id eq "" } { @@ -1059,26 +1059,26 @@ password {parameters {}} } { - Implements the Authenticate operation of the auth_authentication + Implements the Authenticate operation of the auth_authentication service contract for the local account implementation. } { array set auth_info [list] # TODO: username = email parameter ... set username [string tolower $username] - + set authority_id [auth::authority::local] set account_exists_p [db_0or1row select_user_info { select user_id from cc_users where username = :username and authority_id = :authority_id - }] - + }] + if { !$account_exists_p } { set auth_info(auth_status) "no_account" return [array get auth_info] } - + if { [ad_check_password $user_id $password] } { set auth_info(auth_status) "ok" } else { @@ -1087,10 +1087,10 @@ ... display link... } else { set auth_info(auth_status) "bad_password" - } + } return [array get auth_info] } - # We set 'external' account status to 'ok', because the + # We set 'external' account status to 'ok', because the # local account status will be checked anyways set auth_info(account_status) ok return [array get auth_info] @@ -1121,7 +1121,7 @@ External Design auth::registration::Register - returns: + returns: creation_status @@ -1162,7 +1162,7 @@ {-parameters ""} } { Invoke the Register service contract operation for the given authority. - + } { if { $authority_id eq "" } { set authority_id [auth::authority::local] @@ -1219,7 +1219,7 @@ set result(creation_message) "We experienced an error while trying to register an account for you." return [array get result] } - + # Creation succeeded set result(creation_status) "ok" # TODO: validate data (see user-new-2.tcl) @@ -1446,16 +1446,16 @@ EXT-AUTH-16: Authentication Service Contract (1 hour) - by + by Peter Marklund - + Already done by Lars. We should ocument which messages can/should be HTML and which should be plain text and in general try to - document expected values of return variables more clearly. - by + document expected values of return variables more clearly. + by Peter Marklund @@ -1467,14 +1467,14 @@ EXT-AUTH-17: Account Creation Service Contract (1 hour) - by + by Peter Marklund - + Already done by Lars. Todo: improve documentation of return values. - by + by Peter Marklund @@ -1486,16 +1486,16 @@ EXT-AUTH-18: Authority Configuration Data Model (2 hours) - by + by Peter Marklund - + The table auth_authorities already exists in acs-kernel for Oracle. We need to create the table for PostgreSQL and provide upgrade scripts. Rename column auth_p authenticate_p for readability and - clarity? Change column name active_p to enabled_p. + clarity? Change column name active_p to enabled_p. TODO: new column: help_contact_text with contact information (phone, email, etc.) to be displayed as a last resort when people are having problems with an authority. @@ -1509,9 +1509,9 @@ constraint auth_authority_short_name_un unique, pretty_name varchar2(4000), - active_p char(1) default 't' + active_p char(1) default 't' constraint auth_authority_active_p_nn - not null + not null constraint auth_authority_active_p_ck check (active_p in ('t','f')), sort_order integer not null, @@ -1555,7 +1555,7 @@ Password recovery is currently handled by /register/email-password.tcl, email-password-2.tcl and - email-password-3.tcl. All logic is placed in the pages. + email-password-3.tcl. All logic is placed in the pages. Execution Story @@ -1627,7 +1627,7 @@ </para> The logic of bad-password will be moved into /register/index as part of ad_form, but the logic should look like something along the - lines of: + lines of: <programlisting> set user_id [ad_conn] set authority_id [auth::authority -user_id $user_id] @@ -1636,14 +1636,14 @@ set reset_password_p [auth::password::CanResetPassword -driver $driver] </programlisting> If $retrieve_password_p and $reset_password_p is true, this text - will be displayed: + will be displayed: <para>"If you've forgotten your password, you can <ulink url="email-password?user_id=blahblah">ask this server to reset your password and email a new randomly generated password to you </ulink>." </para> - And email-password, should look something like this: + And email-password, should look something like this: <programlisting> # Fetch the username. What proc should we use? set username [auth::username] @@ -1674,7 +1674,7 @@ return } </programlisting> - We'll want to add a check for CanChangePassword in /pvt/home. + We'll want to add a check for CanChangePassword in /pvt/home. </sect3> <sect3> <title>Estimate @@ -1798,7 +1798,7 @@ <sect3 id="execution_stor"> <title>Execution story - User: + User: User visits /pvt/home @@ -1821,7 +1821,7 @@ - Admin: + Admin: () @@ -1841,7 +1841,7 @@ If $change_password_p is true, we'll display the "Change my password" link on /pvt/home. update-password would look something - like this: + like this: if {![db_0or1row select_email {}]} { db_release_unused_handles @@ -1949,7 +1949,7 @@ Execution Story A page showing who has requested a page during the last 5 minutes. - Could be integrated with a chat or instant messaging service. + Could be integrated with a chat or instant messaging service. Internal Design @@ -1961,7 +1961,7 @@ project, but haven't quite finished the work and put it back into the tree. </para> - Lars? + Lars? </sect3> <sect3> <title>Estimate @@ -2033,7 +2033,7 @@ <orderedlist> <listitem> <para>OpenACS retrieves a document from the enterprise server -containing user information. Example mechanisms: +containing user information. Example mechanisms: <itemizedlist> <listitem> <para>A file is delivered to an agreed-on location in the file @@ -2103,7 +2103,7 @@ <para>Service contract for retrieving the document: </para> <programlisting> - GetDocument ( + GetDocument ( type: 0 = snapshot 1 = incremental since: date that you want the incremental update since? @@ -2119,7 +2119,7 @@ <para>Service contract for processing the document: </para> <programlisting> - ProcessDocument ( + ProcessDocument ( type: 0 = snapshot 1 = incremental since: date that you want the incremental update since? @@ -2173,18 +2173,18 @@ <sect3> <title>Internal Design - Describe key algorithms, including pseudo-code. + Describe key algorithms, including pseudo-code. Data Model - Describe data model changes. + Describe data model changes. Error Handling What error codes or error conditions could result? How are they - handled? + handled? Upgrade @@ -2197,14 +2197,14 @@ <title>EXT-AUTH-29: Password Management Service Contract (1 hour) - by + by Peter Marklund - + Already done by Lars. Todo: improve documentation of return values. - by + by Peter Marklund @@ -2219,7 +2219,7 @@ External Design - We'll want an API that lets us + We'll want an API that lets us add authorities: auth::authority::new @@ -2234,7 +2234,7 @@ - authorities. + authorities. Here goes: @@ -2292,7 +2292,7 @@ {-authority_id:required} } { db_exec delete_authority { - delete from auth_authorities + delete from auth_authorities where authority_id = :authority_id } } @@ -2312,7 +2312,7 @@ {-register_url:required} } { db_exec edit_authority { - update auth_authorities + update auth_authorities set short_name = :short_name, pretty_name = :pretty_name, active_p = :active_p, @@ -2350,15 +2350,15 @@ EXT-AUTH-31: External Authentication Datamodel (2 hours) - by + by Peter Marklund - + The columns authority_id and username have been added to the users table for Oracle. We need to add them for PostgreSQL and provide - upgrade scripts. + upgrade scripts. create table users ( user_id not null @@ -2368,8 +2368,8 @@ authority_id integer constraint users_auth_authorities_fk references auth_authorities(authority_id), - username varchar2(100) - constraint users_username_nn + username varchar2(100) + constraint users_username_nn not null, screen_name varchar2(100) constraint users_screen_name_un @@ -2398,7 +2398,7 @@ - by + by Peter Marklund @@ -2470,13 +2470,13 @@ OACS-COL-1: Automate install and self-test (5 hours) - by + by Peter Marklund - - I need to make sure the install scripts work. I then need to: + + I need to make sure the install scripts work. I then need to: Schedule nightly recreation @@ -2492,14 +2492,14 @@ - by + by Peter Marklund - + EXT AUTH #x: Title of feature @@ -2623,7 +2623,7 @@ </para> <para>Risk: </para> - + </sect3> </sect2> </sect1> Index: openacs-4/packages/assessment/www/asm-admin/export/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/assessment/www/asm-admin/export/index.vuh,v diff -u -N -r1.12 -r1.12.2.1 --- openacs-4/packages/assessment/www/asm-admin/export/index.vuh 7 Aug 2017 23:48:04 -0000 1.12 +++ openacs-4/packages/assessment/www/asm-admin/export/index.vuh 17 Dec 2019 16:46:46 -0000 1.12.2.1 @@ -6,13 +6,13 @@ @creation-date 2004-11-25 } -query { {assessment_id:integer,optional} -} +} if {([info exists assessment_id] && $assessment_id ne "")} { # Get the assessment data as::assessment::data -assessment_id $assessment_id set download_name $assessment_data(title) - + # We get rid of spaces since they are annoying regsub -all { } $download_name {_} download_name @@ -56,9 +56,9 @@ $root appendChild $assessment #<qticomment> -as::export::new_element -value $assessment_data(description) -father $assessment -label qticomment -root $doc +as::export::new_element -value $assessment_data(description) -father $assessment -label qticomment -root $doc #<duration>, time_for_response -as::export::new_element -value $assessment_data(time_for_response) -father $assessment -label duration -root $doc +as::export::new_element -value $assessment_data(time_for_response) -father $assessment -label duration -root $doc #<qtimetadata> if {$assessment_data(run_mode) ne "" || $assessment_data(anonymous_p) ne "" || $assessment_data(secure_access_p) ne "" || $assessment_data(reuse_responses_p) ne "" || $assessment_data(show_item_name_p) ne "" || $assessment_data(consent_page) ne "" || $assessment_data(return_url) ne "" || $assessment_data(start_time) ne "" || $assessment_data(end_time) ne "" || $assessment_data(number_tries) ne "" || $assessment_data(wait_between_tries) ne "" || $assessment_data(time_for_response) ne "" || $assessment_data(ip_mask) ne "" || $assessment_data(show_feedback) ne "" || $assessment_data(section_navigation) ne ""} { @@ -67,31 +67,31 @@ #run_mode as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label run_mode -value $assessment_data(run_mode) #anonymous_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label anonymous_p -value $assessment_data(anonymous_p) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label anonymous_p -value $assessment_data(anonymous_p) #secure_access_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label secure_access_p -value $assessment_data(secure_access_p) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label secure_access_p -value $assessment_data(secure_access_p) #reuse_responses_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label reuse_responses_p -value $assessment_data(reuse_responses_p) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label reuse_responses_p -value $assessment_data(reuse_responses_p) #show_item_name_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label show_item_name_p -value $assessment_data(show_item_name_p) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label show_item_name_p -value $assessment_data(show_item_name_p) #consent_page - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label consent_page -value $assessment_data(consent_page) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label consent_page -value $assessment_data(consent_page) #return_url - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label return_url -value $assessment_data(return_url) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label return_url -value $assessment_data(return_url) #start_time - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label start_time -value $assessment_data(start_time) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label start_time -value $assessment_data(start_time) #end_time - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label end_time -value $assessment_data(end_time) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label end_time -value $assessment_data(end_time) #number_tries - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label number_tries -value $assessment_data(number_tries) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label number_tries -value $assessment_data(number_tries) #wait_between_tries - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label wait_between_tries -value $assessment_data(wait_between_tries) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label wait_between_tries -value $assessment_data(wait_between_tries) #ip_mask - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label ip_mask -value $assessment_data(ip_mask) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label ip_mask -value $assessment_data(ip_mask) #show_feedback - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label show_feedback -value $assessment_data(show_feedback) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label show_feedback -value $assessment_data(show_feedback) #section_navigation - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label section_navigation -value $assessment_data(section_navigation) + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label section_navigation -value $assessment_data(section_navigation) } #<objectives> @@ -104,7 +104,7 @@ } else { $assessmentcontrol setAttribute feedbackswitch "Yes" } -$assessmentcontrol setAttribute solutionswitch "No" +$assessmentcontrol setAttribute solutionswitch "No" $assessment appendChild $assessmentcontrol #<rubric> @@ -118,7 +118,7 @@ $assessment appendChild $section #<qticomment> as::export::new_element -value $section_description -father $section -label qticomment -root $doc - + #<qtimetadata> set section_display_type "" set s_num_items "" @@ -128,42 +128,42 @@ set s_submit_answer_p "" set s_sort_order_type "" db_0or1row section_display_data {} - + #<duration> as::export::new_element -value $section_max_time_to_complete -father $section -label duration -root $doc - + if {$section_num_items ne "" || $section_points ne "" || $section_display_type ne "" || $s_num_items ne "" || $s_adp_chunk ne "" || $s_branched_p ne "" || $s_back_button_p ne "" || $s_submit_answer_p ne "" || $s_sort_order_type ne ""} { set qtimetadata [$doc createElement qtimetadata] $section appendChild $qtimetadata #num_items - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label num_items -value $section_num_items + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label num_items -value $section_num_items #points - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label points -value $section_points + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label points -value $section_points #display_type - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label display_type -value $section_display_type + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label display_type -value $section_display_type #s_num_items - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label s_num_items -value $s_num_items + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label s_num_items -value $s_num_items #adp_chunk as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label adp_chunk -value $s_adp_chunk #branched_p as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label branched_p -value $s_branched_p #back_button_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label back_button_p -value $s_back_button_p + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label back_button_p -value $s_back_button_p #submit_answer_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label submit_answer_p -value $s_submit_answer_p + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label submit_answer_p -value $s_submit_answer_p #sort_order_type as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label sort_order_type -value $s_sort_order_type } - + #<objectives> as::export::new_element -value $section_description -father $section -label objectives -root $doc -material_p t #<rubric> as::export::new_element -value $section_instructions -father $section -label rubric -root $doc -material_p t #<sectionfeedback> as::export::new_element -value $section_feedback_text -father $section -label sectionfeedback -root $doc -material_p t -attribute_label ident -attribute_value $section_id - + #<selection_ordering> - set selection_ordering [$doc createElement selection_ordering] + set selection_ordering [$doc createElement selection_ordering] $section appendChild $selection_ordering #<selection> set selection [$doc createElement selection] @@ -177,7 +177,7 @@ set order [$doc createElement order] $order setAttribute order_type "Sequential" $selection_ordering appendChild $order - + db_foreach query_all_items {} { #reset variables set cb__display_id {} @@ -190,47 +190,47 @@ unset ta__display_id set mc_id [as::item_rels::get_target -item_rev_id $as_item_id -type as_item_type_rel] set item_display_id [as::item_rels::get_target -item_rev_id $as_item_id -type as_item_display_rel] - set items_as_item_id [db_string items_items_as_item_id "SELECT item_id FROM cr_revisions WHERE revision_id = :as_item_id"] - #checkbox + set items_as_item_id [db_string items_items_as_item_id "SELECT item_id FROM cr_revisions WHERE revision_id = :as_item_id"] + #checkbox db_0or1row as_item_display_cbx "SELECT as_item_display_id AS cb__display_id FROM as_item_display_cb WHERE as_item_display_id=:item_display_id" #radiobutton db_0or1row as_item_display_rbx "SELECT as_item_display_id AS rb__display_id FROM as_item_display_rb WHERE as_item_display_id=:item_display_id" #textbox (fill-in-the-blank) db_0or1row as_item_display_tbx "SELECT as_item_display_id AS tb__display_id FROM as_item_display_tb WHERE as_item_display_id=:item_display_id" #textarea (short answer) db_0or1row as_item_display_tax "SELECT as_item_display_id AS ta__display_id FROM as_item_display_ta WHERE as_item_display_id=:item_display_id" - + #<item> set item [$doc createElement item] if { $field_name ne "" } { set item_name $field_name } $item setAttribute ident $item_name $section appendChild $item - + #<qticomment> as::export::new_element -value $item_description -father $item -label qticomment -root $doc #<duration> as::export::new_element -value $item_max_time_to_complete -father $item -label duration -root $doc - + if {$item_field_code ne "" || $item_required_p ne "" || $item_points ne "" || $item_data_type ne ""} { set itemmetadata [$doc createElement itemmetadata] $item appendChild $itemmetadata set qtimetadata [$doc createElement qtimetadata] $itemmetadata appendChild $qtimetadata #field_code - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label field_code -value $item_field_code + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label field_code -value $item_field_code #required_p - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label required_p -value $item_required_p + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label required_p -value $item_required_p #points - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label points -value $item_points + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label points -value $item_points #data_type as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label data_type -value $item_data_type - + #multiple response or multiple choice items if {[info exists cb__display_id] || [info exists rb__display_id]} { - #as_item_type_mc----------------- - db_0or1row item_type_data {} + #as_item_type_mc----------------- + db_0or1row item_type_data {} #increasing_p as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label increasing_p -value $increasing_p #allow_negative_p @@ -239,93 +239,93 @@ as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label num_correct_answers -value $num_correct_answers #num_answers as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label num_answers -value $num_answers - + #as_item_display_rb if {[info exists rb__display_id]} { - db_0or1row item_display_rb_data { } + db_0or1row item_display_rb_data { } } else { db_0or1row item_display_cb_data { } - } - + } + #html_display_options as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label html_display_options -value $html_display_options #choice_orientation as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label choice_orientation -value $choice_orientation - #choice_label_orientation + #choice_label_orientation as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label choice_label_orientation -value $choice_label_orientation #sort_order_type as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label sort_order_type -value $sort_order_type #item_answer_alignment as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label item_answer_alignment -value $item_answer_alignment - + } elseif {[info exists ta__display_id]} { db_0or1row item_display_ta_data {} #abs_size as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label abs_size -value $abs_size #item_answer_alignment - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label item_answer_alignment -value $item_answer_alignment + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label item_answer_alignment -value $item_answer_alignment } elseif {[info exists tb__display_id]} { db_0or1row item_display_tb_data {} #abs_size as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label tb_abs_size -value $tb_abs_size #item_answer_alignment - as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label item_answer_alignment -value $item_answer_alignment - } - + as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label item_answer_alignment -value $item_answer_alignment + } + # open question item db_0or1row as_item_oq { } if {[info exists id__as_item_type_oq]} { #default_value as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label default_value -value $default_value #feedback_text as::export::element_qtimetadatafield -root $doc -father $qtimetadata -label feedback_text -value $feedback_text - } + } } - + #<objectives> as::export::new_element -value $item_description -father $item -label objectives -root $doc -material_p t #<rubric> as::export::new_element -value $item_subtext -father $item -label rubric -root $doc -material_p t - + #<presentation> set presentation [$doc createElement presentation] - $item appendChild $presentation - + $item appendChild $presentation + if {![info exists tb__display_id]} { #<material> set material [$doc createElement material] $presentation appendChild $material - #<mattext> - set mattext [$doc createElement mattext] + #<mattext> + set mattext [$doc createElement mattext] $mattext setAttribute texttype text/html - $material appendChild $mattext + $material appendChild $mattext set text [$doc createCDATASection $item_title] $mattext appendChild $text - - #content_type: imagen + + #content_type: imagen set content_type "" - + db_0or1row get_content_type_items {} - if {$content_type eq "image"} { + if {$content_type eq "image"} { #<matimage> set matimage [$doc createElement matimage] $material appendChild $matimage - $matimage setAttribute uri $content_filename + $matimage setAttribute uri $content_filename if {$mime_type ne ""} { $matimage setAttribute imagtype $mime_type - } - + } + set cr_path [cr_fs_path $storage_area_key] - file copy -force -- "${cr_path}${cr_file_name}" [file join ${in_path} $content_filename] - } - } - - + file copy -force -- "${cr_path}${cr_file_name}" [file join ${in_path} $content_filename] + } + } + + #find out the item type (multiple choice or multiple response) if {[info exists cb__display_id] || [info exists rb__display_id]} { if {[info exists cb__display_id]} { # checkbox - set rcardinality "Multiple" + set rcardinality "Multiple" } else { # radiobutton set rcardinality "Single" @@ -334,7 +334,7 @@ set response_lid [$doc createElement response_lid] $response_lid setAttribute ident $item_name $response_lid setAttribute rcardinality $rcardinality - $response_lid setAttribute rtiming "No" + $response_lid setAttribute rtiming "No" $presentation appendChild $response_lid #<render_choice> set render_choice [$doc createElement render_choice] @@ -346,29 +346,29 @@ #<response_label> set response_label [$doc createElement response_label] $response_label setAttribute ident $choice_name - $response_label setAttribute rshuffle "Yes" + $response_label setAttribute rshuffle "Yes" $flow_label appendChild $response_label #<material> set material [$doc createElement material] $response_label appendChild $material - - #content_type: imagen - if {$content_type eq "image"} { - #<matimage> + + #content_type: imagen + if {$content_type eq "image"} { + #<matimage> set matimage [$doc createElement matimage] $material appendChild $matimage - $matimage setAttribute uri $content_filename + $matimage setAttribute uri $content_filename if {$mime_type ne ""} { $matimage setAttribute imagtype $mime_type - } + } set cr_path [cr_fs_path $storage_area_key] - file copy -force -- "${cr_path}${cr_file_name}" [file join ${in_path} $content_filename] - - } else { - #<mattext> + file copy -force -- "${cr_path}${cr_file_name}" [file join ${in_path} $content_filename] + + } else { + #<mattext> set mattext [$doc createElement mattext] $mattext setAttribute texttype text/html - $material appendChild $mattext + $material appendChild $mattext set text [$doc createCDATASection $choice_title] $mattext appendChild $text } @@ -380,29 +380,29 @@ set response_str [$doc createElement response_str] $response_str setAttribute ident $item_name $response_str setAttribute rcardinality "Single" - $response_str setAttribute rtiming "No" - $presentation appendChild $response_str - #get rows and cols for painting a textarea (in abs_size is stored as "rows value cols value", we need to add the symbol =) + $response_str setAttribute rtiming "No" + $presentation appendChild $response_str + #get rows and cols for painting a textarea (in abs_size is stored as "rows value cols value", we need to add the symbol =) db_0or1row html_rows_cols "SELECT html_display_options FROM as_item_display_ta WHERE as_item_display_id=:item_display_id" if {![catch {array set html_array $html_display_options} errMsg] && [info exists html_array(rows)] && [info exists html_array(cols)]} { set rows $html_array(rows) set columns $html_array(cols) } else { set rows 15 set columns 55 - } + } #<render_fib> set render_fib [$doc createElement render_fib] $render_fib setAttribute fibtype "String" $render_fib setAttribute prompt "Box" - $render_fib setAttribute encoding "UTF-8" + $render_fib setAttribute encoding "UTF-8" $render_fib setAttribute rows $rows $render_fib setAttribute columns $columns $response_str appendChild $render_fib #<response_label> set response_label [$doc createElement response_label] $response_label setAttribute ident $item_name - $response_label setAttribute rshuffle "Yes" + $response_label setAttribute rshuffle "Yes" $render_fib appendChild $response_label } else { #fill in the blank @@ -414,40 +414,40 @@ ns_log notice "DEBUG::3 $html1" set item_title1 [split $html1 :] set longitud [llength $item_title1] - + for {set i 0} {$i<=[llength $item_title1]-1} {incr i 2} { ns_log notice "DEBUG::4 $i" set item_title [lindex $item_title1 $i] #<material> - set material [$doc createElement material] + set material [$doc createElement material] $presentation appendChild $material - #<mattext> - set mattext [$doc createElement mattext] + #<mattext> + set mattext [$doc createElement mattext] $mattext setAttribute texttype text/html - $material appendChild $mattext + $material appendChild $mattext set text [$doc createCDATASection $item_title] $mattext appendChild $text #<response_str> set response_str [$doc createElement response_str] - $response_str setAttribute ident $item_name$i + $response_str setAttribute ident $item_name$i $response_str setAttribute rcardinality "Single" - $response_str setAttribute rtiming "No" - $presentation appendChild $response_str + $response_str setAttribute rtiming "No" + $presentation appendChild $response_str #<render_fib> set render_fib [$doc createElement render_fib] $render_fib setAttribute fibtype "String" $render_fib setAttribute prompt "Box" - $render_fib setAttribute encoding "UTF-8" + $render_fib setAttribute encoding "UTF-8" $response_str appendChild $render_fib #<response_label> set response_label [$doc createElement response_label] $response_label setAttribute ident $item_name - $response_label setAttribute rshuffle "Yes" + $response_label setAttribute rshuffle "Yes" $render_fib appendChild $response_label } } - } - + } + if { $assessment_data(survey_p) != "t" && ![info exists ta__display_id] } { #<resprocessing> set resprocessing [$doc createElement resprocessing] @@ -465,32 +465,32 @@ #<conditionvar> set conditionvar [$doc createElement conditionvar] $respcondition appendChild $conditionvar - + #fill-in-blank if {[info exists tb__display_id]} { set i 0 - db_foreach query_all_choices {} { + db_foreach query_all_choices {} { #<or> set or [$doc createElement or] $conditionvar appendChild $or set list_choice_title [list $choice_title] for {set j 0} {$j < [llength $list_choice_title]} {incr j 1} { #<varequal> set varequal [$doc createElement varequal] - $varequal setAttribute respident $item_name$i + $varequal setAttribute respident $item_name$i $or appendChild $varequal set text [$doc createCDATASection [lindex $list_choice_title $j]] $varequal appendChild $text - } + } incr i 2 } } else { - - + + #<and> set and [$doc createElement and] - $conditionvar appendChild $and - + $conditionvar appendChild $and + set exist_false 0 db_foreach query_all_choices2 {} { if {$correct_answer_p == "t" } { @@ -521,12 +521,12 @@ $varequal appendChild $text } } - } + } } - + set num_answers_correct "" db_0or1row num_answers_correct {} - + if {$item_points == 1 && $num_answers_correct>1} { #<setvar> set setvar [$doc createElement setvar] @@ -536,21 +536,21 @@ set text [$doc createCDATASection $item_points] $setvar appendChild $text } - + #<displayfeedback> set displayfeedback [$doc createElement displayfeedback] set linkrefid { } append linkrefid $item_name displayRight $displayfeedback setAttribute linkrefid $linkrefid $respcondition appendChild $displayfeedback - + #<respcondition> set respcondition [$doc createElement respcondition] $resprocessing appendChild $respcondition #<conditionvar> set conditionvar [$doc createElement conditionvar] $respcondition appendChild $conditionvar - + #fill-in-blank if {[info exists tb__display_id]} { set i 0 @@ -560,29 +560,29 @@ #<and> set and [$doc createElement and] $not appendChild $and - db_foreach query_all_choices {} { + db_foreach query_all_choices {} { #<or> set or [$doc createElement or] $and appendChild $or set list_choice_title [list $choice_title] - + for {set j 0} {$j < [llength $list_choice_title]} {incr j 1} { #<varequal> set varequal [$doc createElement varequal] - $varequal setAttribute respident $item_name$i + $varequal setAttribute respident $item_name$i $or appendChild $varequal set text [$doc createCDATASection [lindex $list_choice_title $j]] $varequal appendChild $text } incr i 2 } - - } else { - + + } else { + #<or> set or [$doc createElement or] $conditionvar appendChild $or - + set exist_true 0 db_foreach query_all_choices2 {} { if {$correct_answer_p == "f" } { @@ -595,7 +595,7 @@ } else { set exist_true 1 } - } + } if { $exist_true == 1 } { #<not> set not [$doc createElement not] @@ -610,34 +610,34 @@ $varequal setAttribute respident $item_name $and appendChild $varequal set text [$doc createCDATASection $name] - $varequal appendChild $text - } - } + $varequal appendChild $text + } + } } } - - #<displayfeedback> + + #<displayfeedback> set displayfeedback [$doc createElement displayfeedback] set linkrefid { } append linkrefid $item_name displayWrong $displayfeedback setAttribute linkrefid $linkrefid $respcondition appendChild $displayfeedback - - + + if {$item_points>1 || $num_answers_correct==1} { db_foreach query_all_choices {} { set i 0 # [info exists tb__display_id] because for fib item choice_correct_answer_p is null if { $choice_correct_answer_p == "t" || [info exists tb__display_id] } { set list_choice_title [list $choice_title] - + set length_list_choice_title [llength $list_choice_title] - + if {![info exists tb__display_id]} { set length_list_choice_title 1 } - + for {set j 0} {$j < $length_list_choice_title} {incr j 1} { #<respcondition> set respcondition [$doc createElement respcondition] @@ -650,7 +650,7 @@ set varequal [$doc createElement varequal] if {[info exists tb__display_id]} { $varequal setAttribute respident $item_name$i - } else { + } else { $varequal setAttribute respident $item_name } $conditionvar appendChild $varequal @@ -659,7 +659,7 @@ } else { set text [$doc createCDATASection $choice_name] } - $varequal appendChild $text + $varequal appendChild $text #<setvar> set setvar [$doc createElement setvar] $setvar setAttribute varname "SCORE" @@ -670,7 +670,7 @@ set choice_percent_score 1 } else { set choice_percent_score [expr {round (($num_answers_correct * $choice_percent_score * 1.0) / 100)}] - } + } set text [$doc createCDATASection $choice_percent_score] $setvar appendChild $text #feedback choice @@ -680,11 +680,11 @@ append linkrefid $choice_name feedbackChoice $displayfeedback setAttribute linkrefid $linkrefid $respcondition appendChild $displayfeedback - } - } + } + } } - incr i 2 - + incr i 2 + #for feedback choice if { $choice_correct_answer_p == "f" && $choice_feedback_text ne "" } { #<respcondition> @@ -698,29 +698,29 @@ $varequal setAttribute respident $item_name $conditionvar appendChild $varequal set text [$doc createCDATASection $choice_name] - $varequal appendChild $text + $varequal appendChild $text #feedback choice set displayfeedback [$doc createElement displayfeedback] set linkrefid { } append linkrefid $choice_name feedbackChoice $displayfeedback setAttribute linkrefid $linkrefid - $respcondition appendChild $displayfeedback - } + $respcondition appendChild $displayfeedback + } } } - + #feedback_wrong if {$item_feedback_wrong ne "" } { #<itemfeedback> set itemfeedback [$doc createElement itemfeedback] set ident { } append ident $item_name displayWrong $itemfeedback setAttribute ident $ident - $item appendChild $itemfeedback + $item appendChild $itemfeedback #<flow_mat> - as::export::new_element -value $item_feedback_wrong -father $itemfeedback -label flow_mat -root $doc -material_p t + as::export::new_element -value $item_feedback_wrong -father $itemfeedback -label flow_mat -root $doc -material_p t } - + #feedback_right if {$item_feedback_right ne ""} { #<itemfeedback> @@ -730,9 +730,9 @@ $itemfeedback setAttribute ident $ident $item appendChild $itemfeedback #<flow_mat> - as::export::new_element -value $item_feedback_right -father $itemfeedback -label flow_mat -root $doc -material_p t + as::export::new_element -value $item_feedback_right -father $itemfeedback -label flow_mat -root $doc -material_p t } - + #feedback_choice db_foreach query_all_choices {} { if {$choice_feedback_text ne ""} { @@ -743,11 +743,11 @@ $itemfeedback setAttribute ident $ident $item appendChild $itemfeedback #<flow_mat> - as::export::new_element -value $choice_feedback_text -father $itemfeedback -label flow_mat -root $doc -material_p t - } + as::export::new_element -value $choice_feedback_text -father $itemfeedback -label flow_mat -root $doc -material_p t + } } - } - + } + } }