Index: openacs-4/packages/imsld/catalog/imsld.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/catalog/imsld.en_US.ISO-8859-1.xml,v diff -u -r1.34.4.6 -r1.34.4.7 --- openacs-4/packages/imsld/catalog/imsld.en_US.ISO-8859-1.xml 9 Jul 2007 16:09:50 -0000 1.34.4.6 +++ openacs-4/packages/imsld/catalog/imsld.en_US.ISO-8859-1.xml 10 Jul 2007 10:58:30 -0000 1.34.4.7 @@ -8,6 +8,7 @@ Act Identifier active Activities + Activity Activity Identifier Activity Name Activity report Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/imsld/lib/choice-select.adp'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/imsld/lib/imsld-master.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/lib/imsld-master.adp,v diff -u -r1.1.2.3 -r1.1.2.4 --- openacs-4/packages/imsld/lib/imsld-master.adp 27 Jun 2007 10:21:58 -0000 1.1.2.3 +++ openacs-4/packages/imsld/lib/imsld-master.adp 10 Jul 2007 10:58:30 -0000 1.1.2.4 @@ -90,45 +90,22 @@ - Index: openacs-4/packages/imsld/lib/imsld-master.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/lib/imsld-master.tcl,v diff -u -r1.1.2.2 -r1.1.2.3 --- openacs-4/packages/imsld/lib/imsld-master.tcl 27 Jun 2007 10:21:58 -0000 1.1.2.2 +++ openacs-4/packages/imsld/lib/imsld-master.tcl 10 Jul 2007 10:58:30 -0000 1.1.2.3 @@ -31,25 +31,25 @@ } set header_stuff "[subst { - - - - - - - - - - - - - - - - - -}] -$header_stuff" + + + + + + + + + + + + + + + + + + }] + $header_stuff" if {![info exists onload]} { set onload "" Index: openacs-4/packages/imsld/tcl/imsld-cr-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/tcl/imsld-cr-procs.xql,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/imsld/tcl/imsld-cr-procs.xql 1 Feb 2006 11:34:48 -0000 1.1 +++ openacs-4/packages/imsld/tcl/imsld-cr-procs.xql 10 Jul 2007 10:58:30 -0000 1.1.4.1 @@ -1,14 +1,12 @@ - - - - - select 1 - from imsld_cp_files icf, cr_items cri - where cri.item_id = :item_id - and cri.live_revision = icf.imsld_file_id - - + + + select 1 + from imsld_cp_files icf, cr_items cri + where cri.item_id = :item_id + and cri.live_revision = icf.imsld_file_id + + Index: openacs-4/packages/imsld/tcl/imsld-fs-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/tcl/imsld-fs-procs.tcl,v diff -u -r1.6 -r1.6.4.1 --- openacs-4/packages/imsld/tcl/imsld-fs-procs.tcl 25 Apr 2007 10:52:30 -0000 1.6 +++ openacs-4/packages/imsld/tcl/imsld-fs-procs.tcl 10 Jul 2007 10:58:30 -0000 1.6.4.1 @@ -26,9 +26,14 @@ -edit:boolean -complete_path } { - Creates a file (file or directory) in the fs. If the type is file, the file is created with its attributes, which are: href, file_name, path_to_file and parent_id. + Creates a file (file or directory) in the fs. If the type is file, the file + is created with its attributes, which are: href, file_name, path_to_file + and parent_id. - All the parent dirs (lindex 0) of the corresponding file (path_to_file) that are found in the files_struct_list are created too (if they haven't been created yet). The file structure is the one created with the imsld::parse::get_files_structure proc. + All the parent dirs (lindex 0) of the corresponding file (path_to_file) + that are found in the files_struct_list are created too (if they haven't + been created yet). The file structure is the one created with the + imsld::parse::get_files_structure proc. Returns the file_id of the created file. @@ -186,15 +191,17 @@ -revision_id {-string ""} } { - Create an empty file and stores in the given revision id. - this is helpful for the property of type file (for instance), because when the properties are instantiated, there is no - file associated to them and the fs shows an error message. + Create an empty file and stores in the given revision id. This is helpful + for the property of type file (for instance), because when the properties + are instantiated, there is no file associated to them and the fs shows an + error message. @param revision_id @param string Optional string that will be written into the file } { - set string [expr { [string eq "" $string] ? "[_ imsld.Empty_property_value]" : "$string" }] + set string [expr { [string eq "" $string] ? \ + "[_ imsld.Empty_property_value]" : "$string" }] set tmpfile [ns_mktemp "/tmp/imsld_emtpyXXXXXX"] set file [open $tmpfile a] puts $file "$string" @@ -203,14 +210,21 @@ set mime_type "text/plain" # database_p according to the file storage parameter - set fs_package_id [site_node_apm_integration::get_child_package_id \ - -package_id [dotlrn_community::get_package_id [dotlrn_community::get_community_id]] \ - -package_key "file-storage"] - set database_p [parameter::get -parameter "StoreFilesInDatabaseP" -package_id $fs_package_id] + set fs_package_id \ + [site_node_apm_integration::get_child_package_id \ + -package_id [dotlrn_community::get_package_id \ + [dotlrn_community::get_community_id]] \ + -package_key "file-storage"] + set database_p [parameter::get \ + -parameter "StoreFilesInDatabaseP" \ + -package_id $fs_package_id] set content_length [file size $tmpfile] if { !$database_p } { # create the new item - set filename [cr_create_content_file [content::revision::item_id -revision_id $revision_id] $revision_id $tmpfile] + set filename [cr_create_content_file \ + [content::revision::item_id \ + -revision_id $revision_id] \ + $revision_id $tmpfile] db_dml set_file_content { update cr_revisions set content = :filename, @@ -220,16 +234,84 @@ } } else { # create the new item - db_dml lob_content " - update cr_revisions - set lob = [set __lob_id [db_string get_lob_id "select empty_lob()"]] - where revision_id = :revision_id" -blob_files [list $tmpfile] + db_dml lob_content \ + "update cr_revisions + set lob = [set __lob_id [db_string get_lob_id "select empty_lob()"]] + where revision_id = :revision_id" -blob_files [list $tmpfile] - # Unfortunately, we can only calculate the file size after the lob is uploaded + # Unfortunately, we can only calculate the file size after the lob is + # uploaded db_dml lob_size { update cr_revisions set content_length = :content_length where revision_id = :revision_id } } -} +} + +ad_proc -public imsld::fs::traverse_zip { + -dir:required + -pattern:required +} { + Function to recursively traverse the files in a ZIP to then detect those + that are not reerenced in a resource, but still need to be in the file + storate. +} { + upvar files_struct_list files_struct_list + # Iterate over all the files in the given directory + foreach fname [glob -nocomplain -tail -types f -directory $dir $pattern] { + # See if the file was already created + if { [imsld::fs::find_file_not_created \ + -file_name $fname \ + -file_list $files_struct_list \ + -path_prefix $dir] } { + # Create the new file + imsld::fs::file_new \ + -path_to_file $fname \ + -type file \ + -complete_path "[ns_urldecode ${dir}/${fname}]" + } + } + + # Recur over the directories + foreach subd [glob -tail -nocomplain -types d -directory $dir $pattern] { + imsld::fs::traverse_zip -dir $dir -pattern "$subd/*" + } +} + +ad_proc -public imsld::fs::find_file_not_created { + -file_name:required + -file_list:required + -path_prefix:required +} { + Procedure to search for a given file name in the given file list. This list + is assumed to have the structure derived from the parsing. It returns a + boolean encoding if the given file_name is in the list with an object_id + equal to zero. The files are supposed to be in the list with the given + path_prefix. + + @param file_name File to search for + @param file_list List of files contained in a UoL + @param path_prefix Prefix present in all the files +} { + while { [llength $file_list] > 0 } { + set dirx [lindex $file_list 0] + foreach content [lindex $dirx 1] { + if { [lsearch -exact [string tolower $content] \ + [string tolower "$path_prefix/$file_name"]] >=0 && \ + [lindex $content 1] eq "file" } { + # If the object_id is zero, the file was found + if { [lindex $content 2] == 0 } { + return 1 + } else { + # In this case, the file is already in the fs + return 0 + } + } + } + # Advance the processing + set file_list [lrange $file_list 1 [ expr [llength $file_list] -1]] + } + return 0 +} + Index: openacs-4/packages/imsld/tcl/imsld-instance-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/tcl/imsld-instance-procs.tcl,v diff -u -r1.13.4.5 -r1.13.4.6 --- openacs-4/packages/imsld/tcl/imsld-instance-procs.tcl 27 Jun 2007 10:21:58 -0000 1.13.4.5 +++ openacs-4/packages/imsld/tcl/imsld-instance-procs.tcl 10 Jul 2007 10:58:30 -0000 1.13.4.6 @@ -16,20 +16,35 @@ {-community_id ""} } { @param imsld_id the imsld_id to instantiate - @option community_id the community to which the imsld will be instantiated into + @option community_id the community to which the imsld will be instantiated + into @return the run_id created Instantiates an imsld, i.e. creates the run. - If community_id is given, the run is created for that community (the users associated to the run are the users of the community) + If community_id is given, the run is created for that community (the users + associated to the run are the users of the community) } { # 1. create the run (status = 'waiting') - set run_id [package_exec_plsql -var_list [list [list run_id ""] [list imsld_id $imsld_id] [list status "waiting"]] imsld_run new] + set run_id [package_exec_plsql -var_list [list [list run_id ""] \ + [list imsld_id $imsld_id] \ + [list status "waiting"]] \ + imsld_run new] # 2. create the run group - set group_run_id [package_instantiate_object -creation_user [ad_conn user_id] -creation_ip [ad_conn peeraddr] -package_name imsld_run_users_group -start_with "group" -var_list [list [list group_id ""] [list group_name "IMS-LD Run Group ($run_id)"] [list run_id $run_id]] imsld_run_users_group] + set group_run_id \ + [package_instantiate_object \ + -creation_user [ad_conn user_id] \ + -creation_ip [ad_conn peeraddr] \ + -package_name imsld_run_users_group \ + -start_with "group" \ + -var_list [list [list group_id ""] \ + [list group_name "IMS-LD Run Group ($run_id)"] \ + [list run_id $run_id]]\ + imsld_run_users_group] -# jopez: commented out so the users assigned to the run are the ones that the user actually assigns to the run... +# jopez: commented out so the users assigned to the run are the ones that the +# user actually assigns to the run... # # 3. if community_id is not empty, assign the community users to the run # if { ![string eq $community_id ""] } { # foreach user [dotlrn_community::list_users $community_id] { @@ -45,7 +60,9 @@ -run_id:required {-community_id ""} } { - set community_id [expr { [empty_string_p $community_id] ? [dotlrn_community::get_community_id] : $community_id }] + set community_id [expr { [empty_string_p $community_id] ? \ + [dotlrn_community::get_community_id] : \ + $community_id }] db_1row get_context_inf { select org.manifest_id @@ -57,51 +74,71 @@ and iis.organization_id = org.item_id } # Gets file-storage root folder_id - set fs_package_id [site_node_apm_integration::get_child_package_id \ - -package_id [dotlrn_community::get_package_id $community_id] \ - -package_key "file-storage"] + set fs_package_id \ + [site_node_apm_integration::get_child_package_id \ + -package_id [dotlrn_community::get_package_id $community_id] \ + -package_key "file-storage"] set fs_root_folder_id [fs::get_root_folder -package_id $fs_package_id] - set fs_folder_id [content::item::get_id -item_path "manifest_${manifest_id}" -root_folder_id $fs_root_folder_id -resolve_index f] - set run_folder_id [content::item::get_id -item_path "run_${run_id}" -root_folder_id $fs_root_folder_id -resolve_index f] + set fs_folder_id [content::item::get_id \ + -item_path "manifest_${manifest_id}" \ + -root_folder_id $fs_root_folder_id \ + -resolve_index f] + set run_folder_id [content::item::get_id \ + -item_path "run_${run_id}" \ + -root_folder_id $fs_root_folder_id \ + -resolve_index f] if { [empty_string_p $run_folder_id] } { db_transaction { set folder_name "run_${run_id}" # checks for write permission on the parent folder if { ![empty_string_p $fs_root_folder_id] } { - ad_require_permission $fs_root_folder_id write + permission::require_permission \ + -object_id $fs_root_folder_id \ + -privilege write } # create the root cr dir + set run_folder_id [imsld::cr::folder_new \ + -parent_id $fs_folder_id \ + -folder_name $folder_name \ + -folder_label "Run-${run_id}-Folder"] - set run_folder_id [imsld::cr::folder_new -parent_id $fs_folder_id -folder_name $folder_name -folder_label "Run-${run_id}-Folder"] - # PERMISSIONS FOR FILE-STORAGE # Before we go about anything else, lets just set permissions straight. # Disable folder permissions inheritance permission::toggle_inherit -object_id $run_folder_id # Set read permissions for community/class dotlrn_member_rel - set party_id_member [dotlrn_community::get_rel_segment_id -community_id $community_id -rel_type dotlrn_member_rel] - permission::grant -party_id $party_id_member -object_id $run_folder_id -privilege read + set party_id_member [dotlrn_community::get_rel_segment_id \ + -community_id $community_id \ + -rel_type dotlrn_member_rel] + permission::grant -party_id $party_id_member \ + -object_id $run_folder_id -privilege read # Set read permissions for community/class dotlrn_admin_rel - set party_id_admin [dotlrn_community::get_rel_segment_id -community_id $community_id -rel_type dotlrn_admin_rel] - permission::grant -party_id $party_id_admin -object_id $run_folder_id -privilege read + set party_id_admin [dotlrn_community::get_rel_segment_id \ + -community_id $community_id \ + -rel_type dotlrn_admin_rel] + permission::grant -party_id $party_id_admin \ + -object_id $run_folder_id -privilege read # Set read permissions for *all* other professors within .LRN # (so they can see the content) - set party_id_professor [dotlrn::user::type::get_segment_id -type professor] - permission::grant -party_id $party_id_professor -object_id $run_folder_id -privilege read + set party_id_professor [dotlrn::user::type::get_segment_id \ + -type professor] + permission::grant -party_id $party_id_professor \ + -object_id $run_folder_id -privilege read # Set read permissions for *all* other admins within .LRN # (so they can see the content) set party_id_admins [dotlrn::user::type::get_segment_id -type admin] - permission::grant -party_id $party_id_admins -object_id $run_folder_id -privilege read + permission::grant -party_id $party_id_admins \ + -object_id $run_folder_id -privilege read } # register content types content::folder::register_content_type -folder_id $run_folder_id \ @@ -124,17 +161,23 @@ # There are 5 property types # 1. loc-proerty: same value for every user in the run # 2. locpers-property: different value for every user in the run - # 3. locrole-property: same value for every user in the same rol during the run - # 4. globpers-property: different value for every user (run and ims-ld independent) - # 5. glob-property: one value independent from the run, ims-ld, user or role + # 3. locrole-property: same value for every user in the same rol during the + # run + # 4. globpers-property: different value for every user (run and ims-ld + # independent) + # 5. glob-property: one value independent from the run, ims-ld, user or + # role db_1row context_info { select ic.item_id as component_item_id, ii.imsld_id, ii.item_id as imsld_item_id, rug.group_id as run_group_id, org.manifest_id - from imsld_componentsi ic, imsld_imsldsi ii, imsld_runs ir, imsld_run_users_group_ext rug, + from imsld_componentsi ic, + imsld_imsldsi ii, + imsld_runs ir, + imsld_run_users_group_ext rug, imsld_cp_organizationsi org where ic.imsld_id = ii.item_id and content_revision__is_live(ii.imsld_id) = 't' @@ -144,19 +187,26 @@ and ii.organization_id = org.item_id } - # before we can continue we create the folder where the properties of type file will be stored + # before we can continue we create the folder where the properties of type + # file will be stored set run_folder_id [imsld::instance::create_run_folder -run_id $run_id] - set cr_root_folder_id [imsld::cr::get_root_folder -community_id [dotlrn_community::get_community_id]] - set cr_folder_id [content::item::get_id -item_path "cr_manifest_${manifest_id}" -root_folder_id $cr_root_folder_id -resolve_index f] + set cr_root_folder_id \ + [imsld::cr::get_root_folder \ + -community_id [dotlrn_community::get_community_id]] + set cr_folder_id [content::item::get_id \ + -item_path "cr_manifest_${manifest_id}" \ + -root_folder_id $cr_root_folder_id -resolve_index f] set global_folder_id [imsld::global_folder_id] - # 1. loc-property: We create only one entry in the imsld_property_instances table for each property of this type + # 1. loc-property: We create only one entry in the imsld_property_instances + # table for each property of this type db_foreach loc_property { select property_id, identifier, datatype, initial_value, - title + title, + coalesce(title,identifier) as item_name from imsld_propertiesi where component_id = :component_item_id and type = 'loc' @@ -170,28 +220,37 @@ and run_id = :run_id and content_revision__is_live(instance_id) = 't' }] } { - set instance_id [imsld::item_revision_new -attributes [list [list run_id $run_id] \ - [list value $initial_value] \ - [list identifier $identifier] \ - [list property_id $property_id]] \ - -content_type imsld_property_instance \ - -title $title \ - -parent_id [expr [string eq $datatype "file"] ? $run_folder_id : $cr_folder_id]] + set instance_id \ + [imsld::item_revision_new \ + -attributes [list [list run_id $run_id] \ + [list value $initial_value] \ + [list identifier $identifier] \ + [list property_id $property_id]] \ + -content_type imsld_property_instance \ + -name $item_name \ + -title $title \ + -parent_id [expr [string eq $datatype "file"] ? \ + $run_folder_id : $cr_folder_id]] if { [string eq $datatype "file"] } { - # initialize the file to an empty one so the fs doesn't generate an error when requesting the file - imsld::fs::empty_file -revision_id [content::item::get_live_revision -item_id $instance_id] + # initialize the file to an empty one so the fs doesn't + # generate an error when requesting the file + imsld::fs::empty_file \ + -revision_id [content::item::get_live_revision \ + -item_id $instance_id] } } } - # 2. locpers-property: Instantiate the property for each user assigned to the run + # 2. locpers-property: Instantiate the property for each user assigned to + # the run foreach property_list [db_list_of_lists locpers_property { select property_id, identifier, datatype, initial_value, - title + title, + coalesce(title,identifier) from imsld_propertiesi where component_id = :component_item_id and type = 'locpers' @@ -202,12 +261,13 @@ set datatype [lindex $property_list 2] set initial_value [lindex $property_list 3] set title [lindex $property_list 4] + set item_name [lindex $property_list 5] db_foreach user_in_run { select ar.object_id_two as party_id from acs_rels ar where ar.object_id_one = :run_group_id and ar.rel_type = 'imsld_run_users_group_rel' - } { + } { if { ![db_0or1row locrole_already_instantiated_p { select 1 from imsld_property_instances @@ -217,17 +277,35 @@ and run_id = :run_id and content_revision__is_live(instance_id) = 't' }] } { - set instance_id [imsld::item_revision_new -attributes [list [list run_id $run_id] \ - [list value $initial_value] \ - [list identifier $identifier] \ - [list party_id $party_id] \ - [list property_id $property_id]] \ - -content_type imsld_property_instance \ - -title $title \ - -parent_id [expr [string eq $datatype "file"] ? $run_folder_id : $cr_folder_id]] + # Create a folder for each user in the run if needed. + set user_folder_id \ + [content::item::get_id \ + -item_path \ + [imsld::instance::user_folder_name -user_id $party_id] \ + -root_folder_id $run_folder_id] + if { $user_folder_id eq "" } { + set user_folder_id [imsld::instance::create_user_folder \ + -user_id $party_id \ + -parent_folder_id $run_folder_id] + } + set instance_id \ + [imsld::item_revision_new \ + -attributes [list [list run_id $run_id] \ + [list value $initial_value] \ + [list identifier $identifier] \ + [list party_id $party_id] \ + [list property_id $property_id]] \ + -content_type imsld_property_instance \ + -name $item_name \ + -title $title \ + -parent_id [expr [string eq $datatype "file"] ? \ + $user_folder_id : $cr_folder_id]] if { [string eq $datatype "file"] } { - # initialize the file to an empty one so the fs doesn't generate an error when requesting the file - imsld::fs::empty_file -revision_id [content::item::get_live_revision -item_id $instance_id] + # initialize the file to an empty one so the fs doesn't + # generate an error when requesting the file + imsld::fs::empty_file \ + -revision_id [content::item::get_live_revision \ + -item_id $instance_id] } } } @@ -240,7 +318,8 @@ identifier, datatype, initial_value, - title + title, + coalesce(title,identifier) as item_name from imsld_propertiesi where component_id = :component_item_id and type = 'locrole' @@ -267,35 +346,45 @@ and content_revision__is_live(instance_id) = 't' }] } { - set instance_id [imsld::item_revision_new -attributes [list [list run_id $run_id] \ - [list value $initial_value] \ - [list identifier $identifier] \ - [list party_id $party_id] \ - [list property_id $property_id]] \ - -content_type imsld_property_instance \ - -title $title \ - -parent_id [expr [string eq $datatype "file"] ? $run_folder_id : $cr_folder_id]] + set instance_id \ + [imsld::item_revision_new \ + -attributes [list [list run_id $run_id] \ + [list value $initial_value] \ + [list identifier $identifier] \ + [list party_id $party_id] \ + [list property_id $property_id]] \ + -content_type imsld_property_instance \ + -name $item_name \ + -title $title \ + -parent_id [expr [string eq $datatype "file"] ? \ + $run_folder_id : $cr_folder_id]] if { [string eq $datatype "file"] } { - # initialize the file to an empty one so the fs doesn't generate an error when requesting the file - imsld::fs::empty_file -revision_id [content::item::get_live_revision -item_id $instance_id] + # initialize the file to an empty one so the fs doesn't + # generate an error when requesting the file + imsld::fs::empty_file \ + -revision_id [content::item::get_live_revision \ + -item_id $instance_id] } } } } - # 4. globpers-property: Special case. The table imsld_property_instances must hold only one entrance for these properties. - # Besides, if existng href exists, the value of the property is taken from the URI. Otherwise, if - # global definition is not empty, then the property is defined. - # The global definition is stored in the same row of the property_id, so the initial_value of - # the global_definition is in fact the initial_value of the property + # 4. globpers-property: Special case. The table imsld_property_instances + # must hold only one entrance for these properties. + # Besides, if existng href exists, the value of the property is taken from + # the URI. Otherwise, if global definition is not empty, then the property + # is defined. The global definition is stored in the same row of the + # property_id, so the initial_value of the global_definition is in fact the + # initial_value of the property foreach property_list [db_list_of_lists globpers_property { select property_id, identifier, datatype, initial_value, existing_href, uri, - title + title, + coalesce(title,identifier) from imsld_propertiesi where component_id = :component_item_id and type = 'globpers' @@ -308,6 +397,7 @@ set existing_href [lindex $property_list 4] set uri [lindex $property_list 5] set title [lindex $property_list 6] + set item_name [lindex $property_list 7] db_foreach user_in_run { select ar.object_id_two as party_id from acs_rels ar @@ -321,24 +411,46 @@ and party_id = :party_id and content_revision__is_live(instance_id) = 't' }] } { - # not instantiated... is it already defined (existing href)? or must we use the one of the global definition? + # not instantiated... is it already defined (existing href)? or + # must we use the one of the global definition? if { ![string eq $existing_href ""] } { # it is already defined # NOTE: there must be a better way to deal with this, # but by the moment we treat the href as the property value set initial_value $existing_href } - # TODO: the property must be somehow instantiated in the given URI also - set instance_id [imsld::item_revision_new -attributes [list [list value $initial_value] \ - [list identifier $identifier] \ - [list party_id $party_id] \ - [list property_id $property_id]] \ - -content_type imsld_property_instance \ - -title $title \ - -parent_id [expr [string eq $datatype "file"] ? $global_folder_id : $cr_folder_id]] + + # Create a folder for each user in the run if needed. + set user_folder_id \ + [content::item::get_id \ + -item_path \ + [imsld::instance::user_folder_name -user_id $party_id] \ + -root_folder_id $global_folder_id] + if { $user_folder_id eq "" } { + set user_folder_id [imsld::instance::create_user_folder \ + -user_id $party_id \ + -parent_folder_id $global_folder_id] + } + + # TODO: the property must be somehow instantiated in the given + # URI also + set instance_id \ + [imsld::item_revision_new \ + -attributes [list [list value $initial_value] \ + [list identifier $identifier] \ + [list party_id $party_id] \ + [list property_id $property_id]] \ + -content_type imsld_property_instance \ + -name $item_name \ + -title $title \ + -parent_id [expr [string eq $datatype "file"] ? \ + $user_folder_id : $cr_folder_id]] if { [string eq $datatype "file"] } { - # initialize the file to an empty one so the fs doesn't generate an error when requesting the file - imsld::fs::empty_file -revision_id [content::item::get_live_revision -item_id $instance_id] + # initialize the file to an empty one so the fs doesn't + # generate an error when requesting the file + imsld::fs::empty_file \ + -revision_id [content::item::get_live_revision \ + -item_id $instance_id] } } } @@ -353,7 +465,8 @@ initial_value, existing_href, uri, - title + title, + coalesce(title,identifier) as item_name from imsld_propertiesi where component_id = :component_item_id and type = 'global' @@ -375,16 +488,22 @@ } # TODO: the property must be somehow instantiated in the given URI # also - set instance_id [imsld::item_revision_new -attributes [list [list value $initial_value] \ - [list identifier $identifier] \ - [list property_id $property_id]] \ - -content_type imsld_property_instance \ - -title $title \ - -parent_id [expr [string eq $datatype "file"] ? $global_folder_id : $cr_folder_id]] + set instance_id \ + [imsld::item_revision_new \ + -attributes [list [list value $initial_value] \ + [list identifier $identifier] \ + [list property_id $property_id]] \ + -content_type imsld_property_instance \ + -name $item_name \ + -title $title \ + -parent_id [expr [string eq $datatype "file"] ? \ + $global_folder_id : $cr_folder_id]] if { [string eq $datatype "file"] } { # initialize the file to an empty one so the fs doesn't # generate an error when requesting the file - imsld::fs::empty_file -revision_id [content::item::get_live_revision -item_id $instance_id] + imsld::fs::empty_file \ + -revision_id [content::item::get_live_revision \ + -item_id $instance_id] } } } @@ -397,16 +516,22 @@ } { @param run_id The run_id we are instantiating - There are some attributes (like isvisible or the class global attributes) which are not properties but - have to be instantiated because the context of those attributes is the context of the run. So anytime a run - is created, those attributes must be initialized according to the values parsed from the manifest, and not - from the possible changed values of a previous run. + There are some attributes (like isvisible or the class global attributes) + which are not properties but have to be instantiated because the context of + those attributes is the context of the run. So anytime a run is created, + those attributes must be initialized according to the values parsed from + the manifest, and not from the possible changed values of a previous run. } { - set involved_roles [imsld::roles::get_list_of_roles -imsld_id [db_string get_imsld_from_run {select imsld_id from imsld_runs where run_id=:run_id}] ] + set involved_roles \ + [imsld::roles::get_list_of_roles \ + -imsld_id [db_string get_imsld_from_run \ + {select imsld_id from imsld_runs where run_id=:run_id}] ] set involved_users [list] foreach role $involved_roles { - set involved_users [concat $involved_users [imsld::roles::get_users_in_role -role_id [lindex $role 0] -run_id $run_id]] + set involved_users [concat $involved_users \ + [imsld::roles::get_users_in_role \ + -role_id [lindex $role 0] -run_id $run_id]] } foreach user_id [lsort -unique $involved_users] { @@ -418,17 +543,20 @@ ii.prerequisite_id as imsld_prerequisite_id, ii.item_id as run_imsld_item_id, rug.group_id as run_group_id - from imsld_componentsi ic, imsld_imsldsi ii, imsld_runs ir, imsld_run_users_group_ext rug + from imsld_componentsi ic, + imsld_imsldsi ii, + imsld_runs ir, + imsld_run_users_group_ext rug where ic.imsld_id = ii.item_id and content_revision__is_live(ii.imsld_id) = 't' and ii.imsld_id = ir.imsld_id and rug.run_id = ir.run_id and ir.run_id = :run_id } - # 1. items --> learning objectives, prerequisites, roles, - # learning objects, activity description, information(activity structures), - # feedback + # 1. items --> learning objectives, prerequisites, roles, learning + # objects, activity description, information(activity structures), # + # feedback # 1.1 learning objectives items set linear_item_list [db_list item_in_imsld_loi { @@ -439,33 +567,42 @@ and lo.learning_objective_id = :imsld_learning_objective_id }] - set linear_item_list [concat $linear_item_list [db_list item_in_activity_loi { - select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_learning_activities ia, imsld_learning_objectivesi lo - where ar.object_id_one = lo.item_id - and ar.object_id_two = ii.item_id - and ia.learning_objective_id = lo.item_id - and ia.component_id = :component_item_id - }]] + set linear_item_list \ + [concat $linear_item_list [db_list item_in_activity_loi { + select ii.imsld_item_id + from acs_rels ar, + imsld_itemsi ii, + imsld_learning_activities ia, + imsld_learning_objectivesi lo + where ar.object_id_one = lo.item_id + and ar.object_id_two = ii.item_id + and ia.learning_objective_id = lo.item_id + and ia.component_id = :component_item_id + }]] # 1.2. prerequisites - set linear_item_list [concat $linear_item_list [db_list item_in_imsld_pre { - select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_prerequisitesi pre - where ar.object_id_one = pre.item_id - and ar.object_id_two = ii.item_id - and pre.prerequisite_id = :imsld_prerequisite_id - }]] + set linear_item_list \ + [concat $linear_item_list [db_list item_in_imsld_pre { + select ii.imsld_item_id + from acs_rels ar, imsld_itemsi ii, imsld_prerequisitesi pre + where ar.object_id_one = pre.item_id + and ar.object_id_two = ii.item_id + and pre.prerequisite_id = :imsld_prerequisite_id + }]] - set linear_item_list [concat $linear_item_list [db_list item_in_activity_pre { - select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_learning_activities ia, imsld_prerequisitesi pre - where ar.object_id_one = pre.item_id - and ar.object_id_two = ii.item_id - and ia.prerequisite_id = pre.item_id - and ia.component_id = :component_item_id - }]] - + set linear_item_list \ + [concat $linear_item_list [db_list item_in_activity_pre { + select ii.imsld_item_id + from acs_rels ar, + imsld_itemsi ii, + imsld_learning_activities ia, + imsld_prerequisitesi pre + where ar.object_id_one = pre.item_id + and ar.object_id_two = ii.item_id + and ia.prerequisite_id = pre.item_id + and ia.component_id = :component_item_id + }]] + # 1.3. roles set linear_item_list [concat $linear_item_list [db_list item_in_role { select ii.imsld_item_id @@ -474,11 +611,14 @@ and ar.object_id_two = ii.item_id and ir.component_id = :component_item_id }]] - + # 1.4. learning objects (environments) set linear_item_list [concat $linear_item_list [db_list item_in_lo { select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_learning_objectsi lo, imsld_environmentsi env + from acs_rels ar, + imsld_itemsi ii, + imsld_learning_objectsi lo, + imsld_environmentsi env where ar.object_id_one = lo.item_id and ar.object_id_two = ii.item_id and lo.environment_id = env.item_id @@ -488,7 +628,10 @@ # 1.5. activity description (learning activities) set linear_item_list [concat $linear_item_list [db_list item_in_la_desc { select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_learning_activitiesi la, imsld_activity_descsi ad + from acs_rels ar, + imsld_itemsi ii, + imsld_learning_activitiesi la, + imsld_activity_descsi ad where ar.object_id_one = ad.item_id and ar.object_id_two = ii.item_id and la.activity_description_id = ad.item_id @@ -498,41 +641,53 @@ # 1.6. activity description (support activities) set linear_item_list [concat $linear_item_list [db_list item_in_sa_desc { select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_support_activitiesi sa, imsld_activity_descsi ad + from acs_rels ar, + imsld_itemsi ii, + imsld_support_activitiesi sa, + imsld_activity_descsi ad where ar.object_id_one = ad.item_id and ar.object_id_two = ii.item_id and sa.activity_description_id = ad.item_id and sa.component_id = :component_item_id }]] # 1.7. information(activity structures) - set linear_item_list [concat $linear_item_list [db_list item_in_as_info { - select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_activity_structuresi ast - where ar.object_id_one = ast.item_id - and ar.object_id_two = ii.item_id - and ast.component_id = :component_item_id - }]] + set linear_item_list \ + [concat $linear_item_list [db_list item_in_as_info { + select ii.imsld_item_id + from acs_rels ar, imsld_itemsi ii, + imsld_activity_structuresi ast + where ar.object_id_one = ast.item_id + and ar.object_id_two = ii.item_id + and ast.component_id = :component_item_id + }]] # 1.8. feedbak (learning activities) - set linear_item_list [concat $linear_item_list [db_list item_in_la_feedback { - select ii.imsld_item_id - from acs_rels ar, imsld_itemsi ii, imsld_learning_activitiesi la - where ar.object_id_one = la.on_completion_id - and ar.object_id_two = ii.item_id - and ar.rel_type = 'imsld_feedback_rel' - and la.component_id = :component_item_id - }]] - + set linear_item_list \ + [concat $linear_item_list [db_list item_in_la_feedback { + select ii.imsld_item_id + from acs_rels ar, imsld_itemsi ii, + imsld_learning_activitiesi la + where ar.object_id_one = la.on_completion_id + and ar.object_id_two = ii.item_id + and ar.rel_type = 'imsld_feedback_rel' + and la.component_id = :component_item_id + }]] + foreach imsld_item_id $linear_item_list { db_foreach nested_associated_items { select ii.imsld_item_id, ii.item_id, coalesce(ii.is_visible_p, 't') as is_visible_p, ii.identifier from imsld_itemsi ii - where (imsld_tree_sortkey between tree_left((select imsld_tree_sortkey from imsld_items where imsld_item_id = :imsld_item_id)) - and tree_right((select imsld_tree_sortkey from imsld_items where imsld_item_id = :imsld_item_id)) - or ii.imsld_item_id = :imsld_item_id) + where + (imsld_tree_sortkey between + tree_left((select imsld_tree_sortkey from + imsld_items where imsld_item_id = :imsld_item_id)) + and + tree_right((select imsld_tree_sortkey from + imsld_items where imsld_item_id = :imsld_item_id)) + or ii.imsld_item_id = :imsld_item_id) } { if { ![db_0or1row info_as_already_instantiated_p { select 1 @@ -542,7 +697,18 @@ and user_id = :user_id and type = 'isvisible' }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id $imsld_item_id] [list type "isvisible"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p $is_visible_p] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id $imsld_item_id] \ + [list type "isvisible"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p $is_visible_p] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } } @@ -563,7 +729,18 @@ and user_id = :user_id and type = 'isvisible' }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id $activity_id] [list type "isvisible"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p $is_visible_p] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id $activity_id] \ + [list type "isvisible"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p $is_visible_p] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } @@ -583,7 +760,18 @@ and user_id = :user_id and type = 'isvisible' }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id $activity_id] [list type "isvisible"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p $is_visible_p] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id $activity_id] \ + [list type "isvisible"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p $is_visible_p] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } @@ -605,17 +793,40 @@ and user_id = :user_id and type = 'isvisible' }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id $learning_object_id] [list type "isvisible"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p $is_visible_p] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id $learning_object_id] \ + [list type "isvisible"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p $is_visible_p] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } - if { ![string eq "" $class] && ![db_0or1row lo_env_already_instantiated_p { - select 1 - from imsld_attribute_instances - where run_id = :run_id - and user_id= :user_id - and type = 'class' - and identifier = :class - }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id ""] [list type "class"] [list identifier $class] [list run_id $run_id] [list user_id $user_id] [list is_visible_p "t"] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + if { ![string eq "" $class] && + ![db_0or1row lo_env_already_instantiated_p { + select 1 + from imsld_attribute_instances + where run_id = :run_id + and user_id= :user_id + and type = 'class' + and identifier = :class + }] } { + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id ""] \ + [list type "class"] \ + [list identifier $class] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p "t"] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } @@ -637,17 +848,40 @@ and user_id = :user_id and type = 'isvisible' }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id $service_id] [list type "isvisible"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p $is_visible_p] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql -var_list \ + [list [list instance_id ""] \ + [list owner_id $service_id] \ + [list type "isvisible"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p $is_visible_p] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } - if { ![string eq "" $class] && ![db_0or1row serv_env_already_instantiated_p { - select 1 - from imsld_attribute_instances - where run_id = :run_id - and user_id = :user_id - and type = 'class' - and identifier = :class - }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id ""] [list type "class"] [list identifier $class] [list run_id $run_id] [list user_id $user_id] [list is_visible_p "t"] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + if { ![string eq "" $class] && + ![db_0or1row serv_env_already_instantiated_p { + select 1 + from imsld_attribute_instances + where run_id = :run_id + and user_id = :user_id + and type = 'class' + and identifier = :class + }] } { + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id ""] \ + [list type "class"] \ + [list identifier $class] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p "t"] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } @@ -668,10 +902,21 @@ and user_id = :user_id and type = 'isvisible' }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id $play_id] [list type "isvisible"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p $is_visible_p] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id $play_id] \ + [list type "isvisible"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p $is_visible_p] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } - + # 7. classes db_foreach class { select cla.class_id, @@ -686,7 +931,18 @@ and run_id = :run_id and user_id = :user_id }] } { - set instance_id [package_exec_plsql -var_list [list [list instance_id ""] [list owner_id ""] [list type "class"] [list identifier $identifier] [list run_id $run_id] [list user_id $user_id] [list is_visible_p "t"] [list title ""] [list with_control_p ""]] imsld_attribute_instance new] + set instance_id \ + [package_exec_plsql \ + -var_list [list [list instance_id ""] \ + [list owner_id ""] \ + [list type "class"] \ + [list identifier $identifier] \ + [list run_id $run_id] \ + [list user_id $user_id] \ + [list is_visible_p "t"] \ + [list title ""] \ + [list with_control_p ""]] \ + imsld_attribute_instance new] } } } @@ -701,9 +957,113 @@ @return 1 if successful, 0 otherwise } { - return [package_exec_plsql -var_list [list [list run_id $run_id]] imsld_run del] + return [package_exec_plsql -var_list [list [list run_id $run_id]] \ + imsld_run del] } +ad_proc -public imsld::instance::create_user_folder { + -user_id:required + -parent_folder_id:required + {-community_id ""} +} { + Procedure that given a user id, creates inside the + given parent_id one folder with name user_NNNN_folder where + NNNN is the user_id within the platform. This folder is required to + store the values of locpers-property and globpers-property of type file. + Since each user may have an instance of the same file, separating them into + user folders facilitates its later manipulation. All the files submitted + for locpers-property or globpers-property for the same person are found in + one single folder. + As for the "folder_label" it is not given to the imsld::cr::folder_new on + purpose in order for it to reuse folder_name. Navigating through WebDAV in + one of this folders, only shows the folder_name, therefore, this duality + between folder_name and folder_label, has been avoided. + + Returns the item_id of the created folder + + @param user_id user id for which to create the folder + @param parent_folder_id cr_item from which to create the sub-folder +} { + # If the community_id is not given, obtained from the environment + if { [empty_string_p $community_id] } { + set community_id [dotlrn_community::get_community_id] + } + + # Require writing permission in the given parent_folder_id + permission::require_permission \ + -object_id $parent_folder_id \ + -privilege write + + db_transaction { + # First cook up the folder name. + set folder_name [imsld::instance::user_folder_name \ + -user_id $user_id] + + # Create the folder. No folder_label is given, therefore, the + # folder_name is reused. + set user_folder_id [imsld::cr::folder_new \ + -parent_id $parent_folder_id \ + -folder_name $folder_name] + # And now, the permissions. These folders should only be visible to + # the user + # Disable folder permissions inheritance + permission::toggle_inherit -object_id $user_folder_id + + # Set read permissions for the user + permission::grant -party_id $user_id \ + -object_id $user_folder_id -privilege read + + # Set admin permissions for community/class dotlrn_admin_rel + set party_id_admin [dotlrn_community::get_rel_segment_id \ + -community_id $community_id \ + -rel_type dotlrn_admin_rel] + permission::grant -party_id $party_id_admin \ + -object_id $user_folder_id \ + -privilege read + + # Set read permissions for *all* other professors within .LRN + # FIXME: This should be restricted to professors members of THIS + # community + set party_id_professor [dotlrn::user::type::get_segment_id \ + -type professor] + permission::grant -party_id $party_id_professor \ + -object_id $user_folder_id \ + -privilege read + + # Set read permissions for *all* other admins within .LRN + set party_id_admins [dotlrn::user::type::get_segment_id -type admin] + permission::grant -party_id $party_id_admins \ + -object_id $user_folder_id -privilege read + + # register content types + content::folder::register_content_type -folder_id $user_folder_id \ + -content_type imsld_property_instance + + # In principle no sub-folders are allowed in this folder. + } + + return $user_folder_id +} + +ad_proc -public imsld::instance::user_folder_name { + -user_id:required +} { + This procedure is to centralize the place where the user folder name is + computed. It is used to create this folder and access it to store + properties of type file. By centralizing here the name creation, when + modified, this is the only place in the code where the change needs to be + reflected. + + Returns the string used for folder identification + + @param user_id the user identifier for the folder name +} { + db_1row user_info { + select username as username from users where user_id=:user_id + } + return ${user_id}_$username +} + # LocalWords: type Index: openacs-4/packages/imsld/tcl/imsld-parse-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/tcl/imsld-parse-procs.tcl,v diff -u -r1.63.4.4 -r1.63.4.5 --- openacs-4/packages/imsld/tcl/imsld-parse-procs.tcl 9 Jul 2007 16:09:51 -0000 1.63.4.4 +++ openacs-4/packages/imsld/tcl/imsld-parse-procs.tcl 10 Jul 2007 10:58:30 -0000 1.63.4.5 @@ -938,13 +938,16 @@ } { Parse a global definition and stores all the information in the database. - Returns a list with the new global_definition_id (item_id, actually a property_id) created if there were no errors, or 0 and an explanation messge if there was an error. + Returns a list with the new global_definition_id (item_id, actually a + property_id) created if there were no errors, or 0 and an explanation + messge if there was an error. @option global_def_node global_def node to parse @param identifier @param existing_href @param component_id Comoponent id of the one which owns the property - @param type Type of the property defined by this global definition, which can be globpers or glob + @param type Type of the property defined by this global definition, which + can be globpers or glob @param manifest Manifest tree @param manifest_id Manifest ID or the manifest being parsed @param parent_id Parent folder ID @@ -953,13 +956,25 @@ upvar files_struct_list files_struct_list if { ![empty_string_p $global_def_node] } { - set uri [imsld::parse::get_attribute -node $global_def_node -attr_name uri] - set title [imsld::parse::get_title -node $global_def_node -prefix imsld] - set datatype [$global_def_node selectNodes "*\[local-name()='datatype'\]" ] - imsld::parse::validate_multiplicity -tree $global_def_node -multiplicity 1 -element_name "global-definition datatype" -equal - set datatype [string tolower [imsld::parse::get_attribute -node $datatype -attr_name datatype]] - set initial_value [$global_def_node selectNodes "*\[local-name()='initial-value'\]"] - imsld::parse::validate_multiplicity -tree $initial_value -multiplicity 1 -element_name "global-definition initial-value" -lower_than + set uri [imsld::parse::get_attribute -node $global_def_node \ + -attr_name uri] + set title [imsld::parse::get_title \ + -node $global_def_node -prefix imsld] + set datatype \ + [$global_def_node selectNodes "*\[local-name()='datatype'\]" ] + imsld::parse::validate_multiplicity \ + -tree $global_def_node \ + -multiplicity 1 \ + -element_name "global-definition datatype" -equal + set datatype [string tolower \ + [imsld::parse::get_attribute \ + -node $datatype -attr_name datatype]] + set initial_value [$global_def_node selectNodes \ + "*\[local-name()='initial-value'\]"] + imsld::parse::validate_multiplicity \ + -tree $initial_value \ + -multiplicity 1 \ + -element_name "global-definition initial-value" -lower_than if { [llength $initial_value] } { set initial_value [imsld::parse::get_element_text -node $initial_value] } else { @@ -973,26 +988,31 @@ } - set globpers_property_id [imsld::item_revision_new -attributes [list [list component_id $component_id] \ - [list identifier $identifier] \ - [list existing_href $existing_href] \ - [list uri $uri] \ - [list type $type] \ - [list datatype $datatype] \ - [list initial_value $initial_value]] \ - -content_type imsld_property \ - -title $title \ - -parent_id $parent_id] + set globpers_property_id \ + [imsld::item_revision_new \ + -attributes [list [list component_id $component_id] \ + [list identifier $identifier] \ + [list existing_href $existing_href] \ + [list uri $uri] \ + [list type $type] \ + [list datatype $datatype] \ + [list initial_value $initial_value]] \ + -content_type imsld_property \ + -title $title \ + -parent_id $parent_id] if { ![empty_string_p $global_def_node] } { - set restrictions [$global_def_node selectNodes "*\[local-name()='restriction'\]"] + set restrictions \ + [$global_def_node selectNodes "*\[local-name()='restriction'\]"] foreach restriction $restrictions { - set restriction_list [imsld::parse::parse_and_create_restriction -manifest $manifest \ - -property_id $globpers_property_id \ - -manifest_id $manifest_id \ - -restriction_node $restriction \ - -parent_id $parent_id \ - -tmp_dir $tmp_dir] + set restriction_list \ + [imsld::parse::parse_and_create_restriction \ + -manifest $manifest \ + -property_id $globpers_property_id \ + -manifest_id $manifest_id \ + -restriction_node $restriction \ + -parent_id $parent_id \ + -tmp_dir $tmp_dir] set restriction_id [lindex $restriction_list 0] if { !$restriction_id } { @@ -3997,13 +4017,13 @@ # get the files structure set files_struct_list [imsld::parse::get_files_structure -tmp_dir $tmp_dir] - # Parser - # XML => DOM document - dom parse [::tDOM::xmlReadFile $xmlfile] document - - # DOM document => DOM root - $document documentElement manifest - + # Parser + # XML => DOM document + dom parse [::tDOM::xmlReadFile $xmlfile] document + + # DOM document => DOM root + $document documentElement manifest + # manifest set manifest_identifier [imsld::parse::get_attribute -node $manifest -attr_name identifier] set manifest_version [imsld::parse::get_attribute -node $manifest -attr_name version] @@ -4343,7 +4363,7 @@ relation_add imsld_feedback_rel $on_completion_id $item_id } } else { - set on_completion_id [imsld::item_revision_new -parent_id $parent_id \ + set on_completion_id [imsld::item_revision_new -parent_id $parent_id \ -content_type imsld_on_completion] } @@ -4554,8 +4574,12 @@ if { ![db_0or1row already_created_p { select 1 from imsld_cp_resources where identifier = :resource_identifier and manifest_id = :manifest_id }] } { - imsld::parse::validate_multiplicity -tree $resource_left -multiplicity 1 -element_name "resources (cp resources)" -equal - set resource_list [imsld::parse::parse_and_create_resource -resource_node $resource_left \ + imsld::parse::validate_multiplicity \ + -tree $resource_left \ + -multiplicity 1 \ + -element_name "resources (cp resources)" -equal + set resource_list [imsld::parse::parse_and_create_resource \ + -resource_node $resource_left \ -manifest $manifest \ -manifest_id $manifest_id \ -parent_id $cr_folder_id \ @@ -4568,6 +4592,13 @@ } } + # At this point files_struct_list contain the list of all the files in the + # UoL. Those that were stored in the FS have an object_id attached to + # them. Those that still have a zero as object_id are files that are not + # referenced as resources by the manifest, but they are in the ZIP, + # therefore, they need to be moved to the FS. + imsld::fs::traverse_zip -dir $tmp_dir -pattern "*" + if { ![empty_string_p $warnings] } { set warnings "[_ imsld.lt_br__Warnings_ul_warni]" } Index: openacs-4/packages/imsld/tcl/imsld-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/tcl/imsld-procs.tcl,v diff -u -r1.95.2.6 -r1.95.2.7 --- openacs-4/packages/imsld/tcl/imsld-procs.tcl 9 Jul 2007 16:09:51 -0000 1.95.2.6 +++ openacs-4/packages/imsld/tcl/imsld-procs.tcl 10 Jul 2007 10:58:30 -0000 1.95.2.7 @@ -30,12 +30,14 @@ ad_proc -public imsld::object_type_image_path { -object_type } { - returns the path to the image representing the given object_type in the imsld package + returns the path to the image representing the given object_type in the + imsld package } { set community_id [dotlrn_community::get_community_id] - set imsld_package_id [site_node_apm_integration::get_child_package_id \ - -package_id [dotlrn_community::get_package_id $community_id] \ - -package_key "[imsld::package_key]"] + set imsld_package_id \ + [site_node_apm_integration::get_child_package_id \ + -package_id [dotlrn_community::get_package_id $community_id] \ + -package_key "[imsld::package_key]"] switch $object_type { forums_forum { set image_path "[lindex [site_node::get_url_from_object_id -object_id $imsld_package_id] 0]/resources/forums.png" @@ -382,13 +384,20 @@ ad_proc -public imsld::global_folder_id { {-community_id ""} } { - Returns the global folder id where the global properties of type file are stored. - This folder is a subfolder of the dotlrn root folder and there must be only one in the .LRN installation + Returns the global folder id where the global properties of type file are + stored. + This folder is a subfolder of the dotlrn root folder and there must be only + one in the .LRN installation } { - set community_id [expr { [empty_string_p $community_id] ? [dotlrn_community::get_community_id] : $community_id }] + set community_id [expr { [empty_string_p $community_id] ? \ + [dotlrn_community::get_community_id] : \ + $community_id }] set dotlrn_root_folder_id [dotlrn_fs::get_dotlrn_root_folder_id] - set global_folder_id [content::item::get_id -item_path "imsld_global_folder" -root_folder_id $dotlrn_root_folder_id -resolve_index f] + set global_folder_id [content::item::get_id \ + -item_path "imsld_global_folder" \ + -root_folder_id $dotlrn_root_folder_id \ + -resolve_index f] if { [empty_string_p $global_folder_id] } { db_transaction { @@ -399,11 +408,15 @@ # create the root cr dir - set global_folder_id [imsld::cr::folder_new -parent_id $dotlrn_root_folder_id -folder_name $folder_name -folder_label "IMS-LD"] + set global_folder_id [imsld::cr::folder_new \ + -parent_id $dotlrn_root_folder_id \ + -folder_name $folder_name \ + -folder_label "IMS-LD"] # PERMISSIONS FOR FILE-STORAGE - # Before we go about anything else, lets just set permissions straight. + # Before we go about anything else, lets just set permissions + # straight. # Disable folder permissions inheritance permission::toggle_inherit -object_id $global_folder_id @@ -693,6 +706,7 @@ ad_proc -public imsld::item_revision_new { {-attributes ""} {-item_id ""} + {-name ""} {-title ""} {-package_id ""} {-user_id ""} @@ -703,10 +717,17 @@ -parent_id } { Creates a new revision of a content item, calling the cr functions. - If editing, only a new revision is created, otherwise an item is created too. + If editing, only a new revision is created, otherwise an item is created + too. - @option attributes A list of lists of pairs of additional attributes and their values. + @option attributes A list of lists of pairs of additional attributes and + their values. @option title + @option name When given this parameter is to set the field name of the + newly created item. This field is important for two reasons. First, in the + absence of title in the corresponding cr_revision object, it is the string + shown when the item is a file and is visible in the FS. Second, it is the + ONLY name that appears when browsing the FS through WebDAV. @option package_id @option user_id @option creation_ip @@ -715,16 +736,34 @@ @param parent_id Identifier of the parent folder } { - set user_id [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] - set creation_ip [expr { [string eq "" $creation_ip] ? [ad_conn peeraddr] : $creation_ip }] - set creation_date [expr { [string eq "" $creation_date] ? [dt_sysdate] : $creation_date }] - set package_id [expr { [string eq "" $package_id] ? [ad_conn package_id] : $package_id }] - + set user_id \ + [expr { [string eq "" $user_id] ? [ad_conn user_id] : $user_id }] + set creation_ip [expr { [string eq "" $creation_ip] ? \ + [ad_conn peeraddr] : $creation_ip }] + set creation_date [expr { [string eq "" $creation_date] ? \ + [dt_sysdate] : $creation_date }] + set package_id [expr { [string eq "" $package_id] ? \ + [ad_conn package_id] : $package_id }] + if { [string eq $item_id ""] } { # create the item set item_id [db_nextval "acs_object_id_seq"] + + # Decide the name + if { [string eq "" $name] } { + set name "${item_id}_content_type" + } else { + # If the given name collides with another item, it needs to be + # modified as to make it unique (parent_id, name) is what it needs + # to be made unique + if { ![string eq "" [content::item::get_id_by_name \ + -name $name -parent_id $parent_id]] } { + set name "${name}.${item_id}" + } + } + set item_id [content::item::new -item_id $item_id \ - -name "${item_id}_content_type" \ + -name $name \ -content_type $content_type \ -parent_id $parent_id \ -creation_user $user_id \ Index: openacs-4/packages/imsld/www/activity-frame.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/imsld/www/activity-frame.adp,v diff -u -r1.13.4.4 -r1.13.4.5 --- openacs-4/packages/imsld/www/activity-frame.adp 25 Jun 2007 17:46:54 -0000 1.13.4.4 +++ openacs-4/packages/imsld/www/activity-frame.adp 10 Jul 2007 10:58:31 -0000 1.13.4.5 @@ -1,44 +1,37 @@ -init_activity() - - + + 1 -document.write('