%3 ::xo::db::CrItem ::xo::db::CrItem delete is_package_root_folder privilege=creator rename save save_new set_live_revision update_attribute_from_slot update_item_index ::xo::db::Object ::xo::db::Object delete save save_new update ::xo::db::CrItem->::xo::db::Object ::xo::db::CrCache::Item ::xo::db::CrCache::Item ::xo::db::CrItem->::xo::db::CrCache::Item instmixin ::xotcl::Object ::xotcl::Object ::xo::db::Object->::xotcl::Object ::xo::db::CrFolder ::xo::db::CrFolder → fetch_object → get_instance_from_db → instance_select_query → register_content_types delete save save_new ::xo::db::CrFolder->::xo::db::CrItem

Class ::xo::db::CrFolder

::xo::db::CrFolder[i] create ...

This is a generic class that represents a "cr_folder" XoWiki specific methods are currently directly mixed into all instances of this class.
See Also:
xowiki::Folder
Defined in packages/xotcl-core/tcl/cr-procs.tcl

Class Relations

  • class: ::xo::db::CrClass[i]
  • superclass: ::xo::db::CrItem[i]
::xo::db::CrClass create ::xo::db::CrFolder \
     -superclass ::xo::db::CrItem

Methods (to be applied on the object)

  • fetch_object (scripted, public)

     xo::db::CrFolder[i] fetch_object -item_id item_id  \
        [ -revision_id revision_id ] -object object  \
        [ -initialize on|off ]

    We overwrite the default fetch_object method here. We join acs_objects, cr_items and cr_folders and fetch all attributes. The revision_id is completely ignored.

    Switches:
    -item_id
    (required)
    -revision_id
    (defaults to "0") (optional)
    -object
    (required)
    -initialize
    (boolean) (defaults to "true") (optional)
    See Also:
    • CrClass fetch_object

    Partial Call Graph (max 5 caller/called nodes):
    %3 db_1row db_1row (public) xo::db::CrFolder proc fetch_object xo::db::CrFolder proc fetch_object xo::db::CrFolder proc fetch_object->db_1row

    Testcases:
    No testcase defined.
    if {![nsf::is object $object]} {
      :create $object
    }
    $object set item_id $item_id
    $object db_1row [:qn fetch_folder] {
        SELECT * FROM cr_folders
        JOIN cr_items on cr_folders.folder_id = cr_items.item_id
        JOIN acs_objects on cr_folders.folder_id = acs_objects.object_id
        WHERE folder_id = :item_id
    }
    
    if {$initialize} {
      $object initialize_loaded_object
    }
    return $object
  • get_instance_from_db (scripted, public)

     xo::db::CrFolder[i] get_instance_from_db [ -item_id item_id ] \
        [ -revision_id revision_id ] [ -initialize on|off ]

    The "standard" get_instance_from_db methods return objects following the naming convention "::<acs_object_id>", e.g. ::1234

    Usually, the id of the item that is fetched from the database is used. However, XoWiki's "folder objects" (i.e. an ::xowiki::Object instance that can be used to configure the respective instance) are created using the acs_object_id of the root folder of the xowiki instance, which is actually the id of another acs_object.

    Because of this, we cannot simply create the instances of CrFolder using the "standard naming convention". Instead we create them as ::cr_folder<acs_object_id>.

    Switches:
    -item_id
    (defaults to "0") (optional)
    -revision_id
    (defaults to "0") (optional)
    -initialize
    (boolean) (defaults to "true") (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3

    Testcases:
    No testcase defined.
    set object ::$item_id
    if {![nsf::is object $object]} {
      :fetch_object -object $object -item_id $item_id -initialize $initialize
      $object destroy_on_cleanup
    }
    return $object
  • instance_select_query (scripted, public)

     xo::db::CrFolder[i] instance_select_query \
        [ -select_attributes select_attributes ] [ -orderby orderby ] \
        [ -where_clause where_clause ] [ -from_clause from_clause ] \
        [ -with_subtypes on|off ] [ -with_children on|off ] \
        [ -publish_status publish_status ] [ -count on|off ] \
        [ -folder_id folder_id ] [ -parent_id parent_id ] \
        [ -page_size page_size ] [ -page_number page_number ] \
        [ -base_table base_table ]

    returns the SQL-query to select the CrItems of the specified object_type

    Switches:
    -select_attributes
    (optional)
    attributes for the SQL query to be retrieved, in addition to item_id, name, publish_status, object_type which are always returned
    -orderby
    (optional)
    for ordering the solution set
    -where_clause
    (optional)
    clause for restricting the answer set
    -from_clause
    (optional)
    -with_subtypes
    (boolean) (defaults to "true") (optional)
    return subtypes as well
    -with_children
    (boolean) (defaults to "true") (optional)
    return immediate child objects of all objects as well
    -publish_status
    (optional)
    one of 'live', 'ready', or 'production'
    -count
    (boolean) (defaults to "false") (optional)
    return the query for counting the solutions
    -folder_id
    (optional)
    parent_id
    -parent_id
    (optional)
    -page_size
    (defaults to "20") (optional)
    -page_number
    (optional)
    -base_table
    (defaults to "cr_folders") (optional)
    typically automatic view, must contain title and revision_id
    Returns:
    SQL query

    Partial Call Graph (max 5 caller/called nodes):
    %3

    Testcases:
    No testcase defined.
    if {![info exists folder_id]} {set folder_id ${:folder_id}}
    if {![info exists parent_id]} {set parent_id $folder_id}
    
    if {$base_table eq "cr_folders"} {
      set attributes [list ci.item_id ci.name ci.publish_status acs_objects.object_type]
    } else {
      set attributes [list bt.item_id ci.name ci.publish_status bt.object_type]
    }
    foreach a $select_attributes {
      # if {$a eq "title"} {set a bt.title}
      lappend attributes $a
    }
    # FIXME: This is dirty: We "fake" the base table for this function, so we can reuse the code
    set type_selection_clause [:type_selection_clause -base_table cr_revisions -with_subtypes false]
    # :log "type_selection_clause -with_subtypes $with_subtypes returns $type_selection_clause"
    if {$count} {
      set attribute_selection "count(*)"
      set orderby ""      ;# no need to order when we count
      set page_number  ""      ;# no pagination when count is used
    } else {
      set attribute_selection [join $attributes ,]
    }
    
    set cond [list]
    if {$type_selection_clause ne ""} {lappend cond $type_selection_clause}
    if {$where_clause ne ""}          {lappend cond $where_clause}
    if {[info exists publish_status]} {lappend cond "ci.publish_status = :publish_status"}
    if {$base_table eq "cr_folders"} {
      lappend cond "acs_objects.object_id = cf.folder_id and ci.item_id = cf.folder_id"
      set acs_objects_table "acs_objects, cr_items ci, "
    } else {
      lappend cond "ci.item_id = bt.item_id"
      set acs_objects_table ""
    }
    if {$parent_id ne ""} {
      set parent_clause "ci.parent_id = :parent_id"
      if {$with_children} {
        lappend cond "ci.item_id in (
                select children.item_id from cr_items parent, cr_items children
                where children.tree_sortkey between parent.tree_sortkey and tree_right(parent.tree_sortkey)
                and parent.item_id = $parent_id and parent.tree_sortkey <> children.tree_sortkey)"
      } else {
        lappend cond $parent_clause
      }
    }
    
    if {$page_number ne ""} {
      set limit $page_size
      set offset [expr {$page_size*($page_number-1)}]
    } else {
      set limit ""
      set offset ""
    }
    
    set sql [::xo::dc select  -vars $attribute_selection  -from "$acs_objects_table cr_folders cf $from_clause"  -where [join $cond " and "]  -orderby $orderby  -limit $limit -offset $offset]
    return $sql
  • register_content_types (scripted, public)

     xo::db::CrFolder[i] register_content_types -folder_id folder_id  \
        [ -content_types content_types ]

    Register the specified content types for the folder. If a content_type ends with a *, include its subtypes

    Switches:
    -folder_id
    (required)
    -content_types
    (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3 test_xowiki_test_cases xowiki_test_cases (test xowiki) xo::db::CrFolder proc register_content_types xo::db::CrFolder proc register_content_types test_xowiki_test_cases->xo::db::CrFolder proc register_content_types

    Testcases:
    xowiki_test_cases
    foreach content_type $content_types {
      set with_subtypes [expr {[regexp {^(.*)[*]$} $content_type _ content_type] ? "t" : "f"}]
      ::acs::dc call content_folder register_content_type  -folder_id $folder_id  -content_type $content_type  -include_subtypes $with_subtypes
    }

Methods (to be applied on instances)

  • delete (scripted, public)

     <instance of xo::db::CrFolder[i]> delete

    Delete the CrFolder instance. This method takes the folder_id of the current instance.

    Partial Call Graph (max 5 caller/called nodes):
    %3 ad_return_error ad_return_error (public) xo::db::CrFolder instproc delete xo::db::CrFolder instproc delete xo::db::CrFolder instproc delete->ad_return_error

    Testcases:
    No testcase defined.
    if {[:is_package_root_folder]} {
      ad_return_error "Removal denied" "Don't delete the package root folder, delete the package"
      return
    }
    # delegate deletion to the class
    [:info class] delete -item_id ${:folder_id}
  • save (scripted, public)

     <instance of xo::db::CrFolder[i]> save args [ args... ]

    Save an existing CrFolder instance in the database.

    Parameters:
    args

    Partial Call Graph (max 5 caller/called nodes):
    %3 content::folder::update content::folder::update (public) xo::db::CrFolder instproc save xo::db::CrFolder instproc save xo::db::CrFolder instproc save->content::folder::update

    Testcases:
    No testcase defined.
    set folder_id ${:folder_id}
    content::folder::update  -folder_id $folder_id  -attributes [list  [list name ${:name}]  [list label ${:label}]  [list description ${:description}] ]
    [:info class] get_context package_id user_id ip
    ::xo::dc 1row _ "select acs_object__update_last_modified(:folder_id, :user_id, :ip)"
  • save_new (scripted, public)

     <instance of xo::db::CrFolder[i]> save_new \
        [ -creation_user creation_user ]

    Save a new CrFolder instance in the database.

    Switches:
    -creation_user
    (optional)

    Partial Call Graph (max 5 caller/called nodes):
    %3

    Testcases:
    No testcase defined.
    set package_id ${:package_id}
    [:info class] get_context package_id creation_user creation_ip
    set :folder_id [::acs::dc call content_folder new  -name ${:name} -label [:label]  -description [:description]  -parent_id ${:parent_id}  -package_id $package_id  -creation_user $creation_user  -creation_ip $creation_ip]
    #parent_s has_child_folders attribute could have become outdated
    if { [nsf::is object ::${:parent_id}] } {
      ::${:parent_id} set has_child_folders t
    }
    # well, obtaining the allowed content_types this way is not very
    # straightforward, but since we currently create these folders via
    # ad_forms, and we have no form variable, this should be at least
    # robust.
    if {[[self class] exists allowed_content_types]} {
      ::xo::db::CrFolder register_content_types  -folder_id ${:folder_id}  -content_types [[self class] set allowed_content_types]
    }
    ::xo::xotcl_object_cache flush ${:parent_id}
    
    return ${:folder_id}