%3 ::xo::Package ::xo::Package initialize reply_to_user require_root_folder ::xo::db::Object ::xo::db::Object ::xo::Package->::xo::db::Object ::xo::db::chat_transcript ::xo::db::chat_transcript save_new ::xo::db::chat_transcript->::xo::db::Object ::xo::db::chat_room ::xo::db::chat_room ban_user count_messages create_transcript delete delete_messages flush grant_creator grant_moderator grant_user post_message revoke_moderator revoke_user save_new transcript_messages unban_user ::xo::db::chat_room->::xo::db::Object ::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::CrCache::Item ::xo::db::CrCache::Item ::xo::db::CrItem->::xo::db::CrCache::Item instmixin ::xo::db::CrItem->::xo::db::Object ::xo::db::apm_parameter ::xo::db::apm_parameter ::xo::db::apm_parameter->::xo::db::Object ::xo::parameter ::xo::parameter ::xo::db::apm_parameter->::xo::parameter instmixin ::xotcl::Object ::xotcl::Object ::xo::db::CrCache::Item->::xotcl::Object ::xo::oauth::ServerMetadata ::xo::oauth::ServerMetadata ::xo::oauth::ServerMetadata->::xo::db::CrItem ::xo::db::image ::xo::db::image ::xo::db::image->::xo::db::CrItem ::xo::oauth::ClientMetadata ::xo::oauth::ClientMetadata ::xo::oauth::ClientMetadata->::xo::db::CrItem ::xowiki::Page ::xowiki::Page → find_slot anchor create_form_fields_from_form_constraints create_link find_slot get_form_data include is_folder_page pretty_link render resolve_included_page_name save_new substitute_markup www-autosave-attribute www-bulk-delete www-clipboard-add www-clipboard-clear www-clipboard-content www-clipboard-copy www-clipboard-export www-create-new www-create-or-use www-csv-dump www-delete www-delete-revision www-diff www-duplicate www-edit www-list www-make-live-revision www-popular-tags www-revisions www-save-attributes www-save-tags www-toggle-publish-status www-validate-attribute www-view ::xowiki::Page->::xo::db::CrItem ::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 ::xo::oauth::Credentials ::xo::oauth::Credentials ::xo::oauth::Credentials->::xo::db::CrItem ::xowiki::File ::xowiki::File www-download ::xowiki::File->::xowiki::Page ::xowiki::PageTemplate ::xowiki::PageTemplate www-delete ::xowiki::PageTemplate->::xowiki::Page ::xowiki::PageInstance ::xowiki::PageInstance get_from_template www-use-template ::xowiki::PageInstance->::xowiki::Page ::xowiki::PlainPage ::xowiki::PlainPage ::xowiki::PlainPage->::xowiki::Page ::xo::oauth::TempCredentials ::xo::oauth::TempCredentials ::xo::oauth::TempCredentials->::xo::oauth::Credentials ::xo::oauth::TokenCredentials ::xo::oauth::TokenCredentials ::xo::oauth::TokenCredentials->::xo::oauth::Credentials ::xo::oauth::ClientCredentials ::xo::oauth::ClientCredentials ::xo::oauth::ClientCredentials->::xo::oauth::Credentials

Class ::xo::db::CrItem

::xo::db::CrItem[i] create ... \
           [ -package_id package_id ] \
           [ -parent_id (default "-100") ] \
           [ -publish_status (default "ready") ] \
           [ -storage_type (default "text") ]

Defined in

Class Relations

  • class: ::xo::db::CrClass[i]
  • superclass: ::xo::db::Object[i]
  • instmixin: ::xo::db::CrCache::Item[i]
  • subclass: ::xo::oauth::ServerMetadata[i], ::xo::db::image[i], ::xo::oauth::ClientMetadata[i], ::xowiki::Page[i], ::xo::db::CrFolder[i], ::xo::oauth::Credentials[i]
::xo::db::CrClass create ::xo::db::CrItem \
     -superclass ::xo::db::Object \
     -instmixin ::xo::db::CrCache::Item

Methods (to be applied on instances)

  • delete (scripted, public)

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

    Delete the item from the content repository with the item_id taken from the instance variable.

    Testcases:
    test_cr_items
    # delegate deletion to the class
    [:info class] delete -item_id ${:item_id}
  • is_package_root_folder (scripted, public)

     <instance of xo::db::CrItem[i]> is_package_root_folder

    # In general, every cr_item may be in the role of a # "root-folder" of a package.

    Testcases:
    create_folder_with_page, create_workflow_with_instance
    # e.g. the -100 folder has no package_id
    # if {$package_id eq ""} {return false}
    if {![info exists :item_id]} {
      return false
    }
    #::xo::Package require ${:package_id}
    return [expr {${:item_id} eq [::${:package_id} folder_id]} ? true : false]
  • privilege=creator (scripted, public)

     <instance of xo::db::CrItem[i]> privilege=creator [ -login login ] \
        user_id package_id method

    Define an object specific privilege to be used in the policies. Grant access to a content item for the creator (creation_user) of the item, and for the package admin.

    Switches:
    -login (optional, defaults to "true")
    Parameters:
    user_id (required)
    package_id (required)
    method (required)

    Testcases:
    No testcase defined.
    set allowed 0
    # :log "--checking privilege [self args]"
    if {[info exists :creation_user]} {
      if {${:creation_user} == $user_id} {
        set allowed 1
      } else {
        # allow the package admin always access
        set allowed [::xo::cc permission  -object_id $package_id  -party_id $user_id  -privilege admin]
      }
    }
    return $allowed
  • rename (scripted, public)

     <instance of xo::db::CrItem[i]> rename -old_name old_name  \
        -new_name new_name 

    Rename a content item

    Switches:
    -old_name (required)
    -new_name (required)

    Testcases:
    create_form_with_form_instance
    set item_id ${:item_id}
    ::xo::dc dml update_rename  "update cr_items set name = :new_name where item_id = :item_id"
    set :name $new_name
    :update_item_index
  • save (scripted, public)

     <instance of xo::db::CrItem[i]> save \
        [ -modifying_user modifying_user ] [ -live_p on|off ] \
        [ -use_given_publish_date on|off ]

    Updates an item in the content repository. We insert a new revision instead of changing the current revision.

    Switches:
    -modifying_user (optional)
    -live_p (optional, boolean, defaults to "true")
    make this revision the live revision
    -use_given_publish_date (optional, boolean, defaults to "false")

    Testcases:
    xotcl_core_tutorial_4, test_cr_items
    set __atts [list creation_user]
    set __vars $__atts
    if {[ns_conn isconnected]} {
      lappend __atts creation_ip
      set peeraddr [ad_conn peeraddr]
      lappend __vars peeraddr
    }
    
    #
    # The modifying_user is not maintained by the CR (bug?).
    # xotcl-core handles this by having the modifying user as
    # creation_user of the revision.
    #
    # Caveat: the creation_user fetched can be different if we fetch
    # via item_id (the creation_user is the creator of the item) or if
    # we fetch via revision_id (the creation_user is the creator of
    # the revision).
    
    set creation_user [expr {[info exists modifying_user] ?
                             $modifying_user :
                             [:current_user_id]}]
    #set old_revision_id ${:revision_id}
    
    foreach {__slot_name __slot} [[:info class] array get db_slot] {
      if {
          [$__slot domain] eq "::xo::db::Object"
          || $__slot in {
            "::xo::db::CrItem::slot::name"
            "::xo::db::CrItem::slot::publish_date"
          }
        } continue
      #ns_log notice "REMAINING SLOT: [$__slot serialize]"
      set $__slot_name [set :$__slot_name]
      lappend __atts [$__slot column_name]
      lappend __vars $__slot_name
    }
    
    if {$use_given_publish_date} {
      if {"publish_date" ni $__atts} {
        set publish_date ${:publish_date}
        lappend __atts publish_date
        lappend __vars publish_date
      }
      set publish_date_flag [list -publish_date $publish_date]
    } else {
      set publish_date_flag ""
    }
    
    ::xo::dc transaction {
      #
      # Provide a row-lock to protect against deadlocks during
      # concurrent updates on the same item in different threads.
      #
      ::xo::dc row_lock -for "no key update" -prepare integer item_lock {
        select item_id from cr_items where item_id = :item_id
      }
    
      [:info class] instvar storage_type
      set revision_id [xo::dc nextval acs_object_id_seq]
      if {$storage_type eq "file"} {
        #
        # Get the mime_type from the file, eventually creating a new
        # one if it's unrecognized.
        #
        set :mime_type [cr_check_mime_type  -mime_type ${:mime_type}  -filename  ${:name}  -file      ${:import_file}]
        set :text [cr_create_content_file $item_id $revision_id ${:import_file}]
        set text ${:text}
        set mime_type ${:mime_type}
      }
      ::xo::dc [::xo::dc insert-view-operation] revision_add  [[:info class] insert_statement $__atts $__vars]
    
      :fix_content $revision_id $text
    
      if {$live_p} {
        #
        # Update the life revision with the publish status and
        # optionally the "publish_date".
        #
        ::acs::dc call content_item set_live_revision  -revision_id $revision_id  -publish_status ${:publish_status}  -is_latest true  {*}$publish_date_flag
        set :revision_id $revision_id
        :update_item_index
      } else {
        #
        # If we do not make the revision live, use the old
        # revision_id, and let CrCache save it ......
        #
      }
    
      #
      # Update instance variables "modifying_user" and "last_modified"
      # from potentially changed DB values.
      #
      set :modifying_user $creation_user
      ::xo::dc 1row -prepare integer get_metadata {
        select last_modified
        from acs_objects where object_id = :revision_id
      }
      set :last_modified $last_modified
    
      #
      # In case the context_id has in the DB is different as in the
      # instance variable, push the value from the instance variable
      # to the DB as well.
      #
      if {[info exists :context_id]} {
        set context_id ${:context_id}
    
        ::xo::dc dml update_context {
          UPDATE acs_objects
          SET context_id = :context_id
          WHERE object_id = :item_id
          AND   context_id != :context_id
        }
      }
    }
    return $item_id
  • save_new (scripted, public)

     <instance of xo::db::CrItem[i]> save_new [ -package_id package_id ] \
        [ -creation_user creation_user ] [ -creation_ip creation_ip ] \
        [ -context_id context_id ] [ -live_p on|off ] \
        [ -use_given_publish_date on|off ]

    Insert a new item to the content repository.

    Switches:
    -package_id (optional)
    -creation_user (optional)
    user_id if the creating user
    -creation_ip (optional)
    -context_id (optional)
    -live_p (optional, boolean, defaults to "true")
    make this revision the live revision
    -use_given_publish_date (optional, boolean, defaults to "false")

    Testcases:
    xotcl_core_tutorial_4, test_cr_items
    
    set __class [:info class]
    
    if {![info exists package_id] && [info exists :package_id]} {
      set package_id ${:package_id}
    }
    if {![info exists context_id]} {
      set context_id [expr {[info exists :context_id] ? ${:context_id} : ""}]
    }
    [self class] get_context package_id creation_user creation_ip
    set :creation_user $creation_user
    set __atts  [list creation_user]
    set __vars $__atts
    
    # :log "db_slots for $__class: [$__class array get db_slot]"
    foreach {__slot_name __slot} [$__class array get db_slot] {
      # :log "--slot = $__slot"
      if {
          [$__slot domain] eq "::xo::db::Object"
          || $__slot in {
            "::xo::db::CrItem::slot::name"
            "::xo::db::CrItem::slot::publish_date"
          }
        } continue
      :instvar $__slot_name
      if {![info exists $__slot_name]} {set $__slot_name ""}
      lappend __atts [$__slot column_name]
      lappend __vars $__slot_name
    }
    
    if {$use_given_publish_date} {
      if {"publish_date" ni $__atts} {
        set publish_date ${:publish_date}
        lappend __atts publish_date
        lappend __vars publish_date
      }
      set publish_date_flag [list -publish_date $publish_date]
    } else {
      set publish_date_flag ""
    }
    
    ::xo::dc transaction {
      $__class instvar storage_type object_type
      [self class] lock acs_objects "SHARE ROW EXCLUSIVE"
      set revision_id [xo::dc nextval acs_object_id_seq]
      set :revision_id $revision_id
    
      if {![info exists :name] || ${:name} eq ""} {
        # we have an autonamed item, use a unique value for the name
        set :name [expr {[info exists :__autoname_prefix] ?
                         "${:__autoname_prefix}$revision_id" : $revision_id}]
      }
      if {$title eq ""} {
        set title [expr {[info exists :__title_prefix] ?
                         "${:__title_prefix} (${:name})" : ${:name}}]
      }
    
      if {$storage_type eq "file"} {
        #
        # Get the mime_type from the file, eventually creating a new
        # one if it's unrecognized.
        #
        set mime_type [cr_check_mime_type  -mime_type $mime_type  -filename  ${:name}  -file      ${:import_file}]
      }
    
      set :item_id [::acs::dc call content_item new  -name            ${:name}  -parent_id       ${:parent_id}  -creation_user   $creation_user  -creation_ip     $creation_ip  -context_id      $context_id  -item_subtype    "content_item"  -content_type    $object_type  -description     $description  -mime_type       $mime_type  -nls_language    $nls_language  -is_live         f  -storage_type    $storage_type  -package_id      $package_id  -with_child_rels f]
    
      if {$storage_type eq "file"} {
        set text [cr_create_content_file ${:item_id} $revision_id ${:import_file}]
      }
    
      ::xo::dc [::xo::dc insert-view-operation] revision_add  [[:info class] insert_statement $__atts $__vars]
      :fix_content $revision_id $text
    
      if {$live_p} {
        #
        # Update the life revision with the publish status and
        # optionally the publish_date
        #
        ::acs::dc call content_item set_live_revision  -revision_id $revision_id  -publish_status ${:publish_status}  -is_latest true  {*}$publish_date_flag
        :update_item_index
      }
    }
    
    :db_1row [:qn get_dates] {
      select creation_date, last_modified
      from acs_objects where object_id = :revision_id
    }
    set :object_id ${:item_id}
    return ${:item_id}
  • set_live_revision (scripted, public)

     <instance of xo::db::CrItem[i]> set_live_revision \
        -revision_id revision_id  [ -publish_status publish_status ] \
        [ -is_latest on|off ]
    Switches:
    -revision_id (required)
    -publish_status (optional, defaults to "ready")
    one of 'live', 'ready' or 'production'
    -is_latest (optional, boolean, defaults to "false")

    Testcases:
    create_folder_with_page, create_workflow_with_instance
    ::acs::dc call content_item set_live_revision  -revision_id $revision_id  -publish_status $publish_status  -is_latest $is_latest
    ::xo::xotcl_object_cache flush ${:item_id}
    ::xo::xotcl_object_cache flush $revision_id
  • update_attribute_from_slot (scripted)

     <instance of xo::db::CrItem[i]> update_attribute_from_slot

    Testcases:
    slot_interactions, xowiki
    set :[$slot name] $value
    if {![info exists revision_id]} {
      set revision_id ${:revision_id}
    }
    set domain [$slot domain]
    #set sql "update [$domain table_name]  #          set [$slot column_name] = '$value'  #  where [$domain id_column] = $revision_id"
    #ns_log notice UPDATE-$sql
    ::xo::dc dml update_attribute_from_slot [subst {
      update [$domain table_name]
      set [$slot column_name] = :value
      where [$domain id_column] = :revision_id
    }]
    #
    # Probably we should call here update_last_modified, but for
    # that we would need the modifying_user and the modifying IP
    # address.
    #
    # ::acs::dc call acs_object update_last_modified  #      -object_id $revision_id  #      -modifying_user ${:publish_status}  #      -modifying_ip ...
    
    ::xo::dc dml update_attribute_from_slot_last_modified {
      update acs_objects set last_modified = CURRENT_TIMESTAMP
      where object_id = :revision_id
    }
  • update_item_index (scripted, public)

     <instance of xo::db::CrItem[i]> update_item_index

    Dummy stub to allow subclasses to produce a more efficient index for items based on live revisions.

    Testcases:
    xotcl_core_tutorial_4, xowiki_test_cases
    next