Class ::xowiki::Importer

::xowiki::Importer[i] create ... \
           [ -added (default "0") ] \
           [ -inherited (default "0") ] \
           [ -package_id package_id ] \
           [ -parent_id parent_id ] \
           [ -replaced (default "0") ] \
           [ -updated (default "0") ] \
           [ -user_id user_id ]

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xotcl::Object[i]
::xotcl::Class create ::xowiki::Importer \
     -superclass ::xotcl::Object

Methods (to be applied on instances)

  • added (setter)

  • import (scripted)

    #
    # Import a single object. In essence, this method demarshalls a
    # single object and inserts it (or updates it) in the database. It
    # takes as well care about categories.
    #
    
    $object demarshall -parent_id [$object parent_id] -package_id ${:package_id}  -creation_user ${:user_id} -create_user_ids $create_user_ids
    set item_id [::xo::db::CrClass lookup -name [$object name] -parent_id [$object parent_id]]
    #:msg "lookup of [$object name] parent [$object parent_id] => $item_id"
    if {$item_id != 0} {
      if {$replace} { ;# we delete the original
        ::xo::db::CrClass delete -item_id $item_id
        set item_id 0
        :report_line $object replaced
        incr :replaced
      } else {
        #:msg "$item_id update: [$object name]"
        ::xo::db::CrClass get_instance_from_db -item_id $item_id
        set item ::$item_id
        $item copy_content_vars -from_object $object
        $item save -use_given_publish_date [$item exists publish_date]  -modifying_user [$object set modifying_user]
        #:log "$item_id saved"
        $object set item_id [$item item_id]
        #:msg "$item_id updated: [$object name]"
        :report_line $item_id updated
        incr :updated
      }
    }
    if {$item_id == 0} {
      $object save_new  -use_given_publish_date [$object exists publish_date]  -creation_user [$object set modifying_user]
      set item $object
      #:msg "$object added: [$object name]"
      :report_line $object added
      incr :added
    }
    #
    # The method demarshall might set the mapped __category_ids in $object.
    # Insert these into the category object map
    #
    if {[$object exists __category_ids]} {
      #:msg "$item_id map_categories [object set __category_ids] // [$item item_id]"
      $item map_categories [$object set __category_ids]
    }
    
    ${:package_id} flush_references -item_id [$object item_id] -name [$object name]
  • import_all (scripted)

    #
    # Import a series of objects. This method takes care especially
    # about dependencies of objects, which is reflected by the order
    # of object-imports.
    #
    #
    # Extract information from objects to be imported, that might be
    # changed later in the objects.
    #
    foreach o $objects {
      #
      # Remember old item_ids and old_names for pages with
      # item_ids. Only these can have parents (page_templates) or
      # child_objects
      #
      if {[$o exists item_id]}   {
        set item_ids([$o item_id]) $o
        set old_names([$o item_id]) [$o name]
      } {
        $o item_id ""
      }
      # Remember old parent_ids for name-mapping, names are
      # significant per parent_id.
      if {[$o exists parent_id]} {
        set parent_ids([$o item_id]) [$o parent_id]
      } {
        $o parent_id ""
      }
      set todo($o) 1
    
      #
      # Handle import of categories in the first pass
      #
      if {[$o exists __map_command]} {
        $o package_id ${:package_id}
        $o eval [$o set __map_command]
      }
      # FIXME remove?
      #if {[$o exists __category_map]} {
      #  array set ::__category_map [$o set __category_map]
      #}
    }
    #:msg "item_ids=[array names item_ids], parent_ids=[array names parent_ids]"
    
    #
    # Make a fix-point iteration during import. Do only import, when
    # all pre-requirement pages are already loaded.
    #
    while {[array size todo] > 0} {
      set new 0
      foreach o [array names todo] {
        #:msg "work on $o [$o info class] [$o name]"
    
        set old_name      [$o name]
        set old_item_id   [$o item_id]
        set old_parent_id [$o parent_id]
    
        # page instances have references to page templates, add the templates first
        if {[$o istype ::xowiki::PageInstance]} {
          set old_template_id [$o page_template]
          if {![info exists old_names($old_template_id)]} {
            set new 0
            :msg "need name for $old_template_id. Maybe item_ids for PageTemplate missing?"
            break
          }
    
          set template_name_key $parent_ids($old_template_id)-$old_names($old_template_id)
          if {![info exists name_map($template_name_key)]} {
            #:msg "... delay import of $o (no object with name $template_name_key) imported"
            continue
          }
          #:msg "we found entry for name_map($template_name_key) = $name_map($template_name_key)"
        }
    
        if {[info exists item_ids($old_parent_id)]} {
          # we have a child object
          if {![info exists id_map($old_parent_id)]} {
            #:msg "... delay import of $o (map of parent_id $old_parent_id missing)"
            continue
          }
        }
    
        set need_to_import 1
        #
        # If the page was implicitly added (due to being a
        # page_template of an exported page), and a page (e.g. a form
        # or a workflow) with the same name can be found in the
        # target, don't materialize the inherited page.
        #
        if {$keep_inherited
            && [$o exists __export_reason]
            && [$o set __export_reason] eq "implicit_page_template"} {
          $o unset __export_reason
          set page [::${:package_id} get_page_from_item_ref  -allow_cross_package_item_refs false  -use_package_path true  -use_site_wide_pages true  -use_prototype_pages false  [$o name]  ]
    
          # If we would like to restrict to just inherited pages in
          # the target, we could extend the test below with a test like
          # the following:
          #   set inherited [expr {[$page physical_parent_id] ne [$page parent_id]}]
    
          if {$page ne ""} {
            #:msg "page [$o name] can ne found in folder ${:parent_id}"
            incr :inherited
            unset todo($o)
            set o $page
            set need_to_import 0
          }
        }
    
        if {$need_to_import} {
          # Now, all requirements are met, parent-object and
          # child-object conditions are fulfilled. We have to map
          # page_template for PageInstances and parent_ids for child
          # objects to new IDs.
          #
          if {[$o istype ::xowiki::PageInstance]} {
            #:msg "importing [$o name] page_instance, map $template_name_key to $name_map($template_name_key)"
            $o page_template $name_map($template_name_key)
            #:msg "exists template? [nsf::is object [$o page_template]]"
            if {![nsf::is object [$o page_template]]} {
              ::xo::db::CrClass get_instance_from_db -item_id [$o page_template]
              #:msg "[nsf::is object [$o page_template]] loaded"
            }
          }
    
          if {[info exists item_ids($old_parent_id)]} {
            $o set parent_id $id_map($old_parent_id)
          } else {
            $o set parent_id ${:parent_id}
          }
    
          # Everything is mapped, we can now do the import.
    
          #:msg "start import for $o, name=[$o name]"
          :import  -object $o  -replace $replace  -create_user_ids $create_user_ids
          #:msg "import for $o done, name=[$o name]"
    
          unset todo($o)
        }
    
        #
        # Maintain the maps and iterate
        #
        if {$old_item_id ne ""} {
          set id_map($old_item_id) [$o item_id]
        }
        set name_map($old_parent_id-$old_name) [$o item_id]
        #:msg "setting name_map($old_parent_id-$old_name)=$name_map($old_parent_id-$old_name), o=$o, old_item_id=$old_item_id"
    
        set new 1
      }
      if {$new == 0} {
        :msg "could not import [array names todo]"
        break
      }
    }
    #:msg "final name_map=[array get name_map], id_map=[array get id_map]"
    
    #
    # final cleanup
    #
    foreach o $objects {if {[nsf::is object $o]} {$o destroy}}
    
    ${:package_id} flush_page_fragment_cache
  • inherited (setter)

  • init (scripted)

    set :log ""
    :destroy_on_cleanup
  • package_id (setter)

  • parent_id (setter)

  • replaced (setter)

  • report (scripted)

    return "<b>${:added}</b> #xowiki.objects_newly_inserted#, <b>${:updated}</b> #xowiki.objects_updated#, <b>${:replaced}</b> #xowiki.objects_replaced#, <b>${:inherited}</b> #xowiki.inherited_update_ignored#<p> [:report_lines]"
  • report_line (scripted)

    set href [$obj pretty_link]
    set name [[$obj package_id] external_name -parent_id [$obj parent_id] [$obj name]]
    switch -- $operation {
      "added"     { set operation [_ xowiki.added]     }
      "replaced"  { set operation [_ xowiki.replaced]  }
      "updated"   { set operation [_ xowiki.updated]   }
      "inherited" { set operation [_ xowiki.inherited] }
    }
    append :log "<tr><td>$operation</td><td><a href='[ns_quotehtml $href]'>$name</a></td></tr>\n"
  • report_lines (scripted)

    util_user_message -message "[_ xowiki.Import_successful]"
    return "<table><caption>Details</caption>${:log}</table>"
  • updated (setter)

  • user_id (setter)