xowiki::Package instproc resolve_page (public)
<instance of xowiki::Package> resolve_page \ [ -use_package_path use_package_path ] [ -simple on|off ] \ [ -lang lang ] object method_var
Defined in /var/www/openacs.org/packages/xowiki/tcl/package-procs.tcl
Try to resolve from object (path) and query parameter the called object (might be a package or page) and the method to be called.
- Switches:
- -use_package_path (optional, defaults to
"true"
)- -simple (optional, boolean, defaults to
"false"
)- when set, do not try to resolve using item refs, prototype pages or package_path
- -lang (optional)
- language used for resolving
- Parameters:
- object (required)
- element name to be resolved (not an XOTcl object)
- method_var (required)
- output variable for method to be called on the object
- Returns:
- instantiated object (Page or Package) or empty
- Testcases:
- xowiki_test_cases, path_resolve
Source code: upvar $method_var method # get the default language if not specified if {![info exists lang]} { set lang [:default_language] :log "no lang specified for '$object', use default_language <$lang>" } #:log "object '$object', default-lang $lang" # # First, resolve package level methods, # having the syntax PACKAGE_URL?METHOD&.... # if {$object eq ""} { # # We allow only to call methods defined by the policy # set exported [${:policy} defined_methods Package] foreach m $exported { #:log "--QP :exists_query_parameter $m = [:exists_query_parameter $m] || [:exists_form_parameter $m]" if {[:exists_query_parameter $m] || [:exists_form_parameter $m]} { set method $m ;# determining the method, similar file extensions return [self] } } } if {[string match "//*" $object]} { # # We have a reference to another instance, we can't resolve this # from this package. Report back not found by empty result. # #ns_log notice "reference to another instance: <$object>" return "" } #:log "--o object is '$object'" if {$object eq ""} { # # We have no object, but as well no method callable on the # package If the method is "view", allow it to be called on the # root folder object. set m [:query_parameter m] if {$m in {list show-object file-upload}} { array set "" [list name [::${:folder_id} name] stripped_name [::${:folder_id} name] parent_id [::${:folder_id} parent_id] item_id ${:folder_id} method [:query_parameter m]] } else { set object [${:id} get_parameter index_page:graph "index"] #:log "--o object after getting index_page is '$object'" } } # # Second, resolve on object level, unless we have already an # item_id from above. # if {![info exists (item_id)]} { array set "" [:item_info_from_url -with_package_prefix false -default_lang $lang $object] #:log "item_info_from_url returns [array get {}]" } #:log "object <$object>" set fallback_languages [:get_parameter -check_query_parameter false fallback_languages ""] if {$(item_id) == 0 && $fallback_languages ne ""} { foreach fallback_language $fallback_languages { if {$fallback_language ne $lang} { array set "" [:item_info_from_url -with_package_prefix false -default_lang $fallback_language $object] if { $(item_id) != 0 } { :log "item_info_from_url based on fallback_lang <$fallback_language> returns [array get {}]" break } } } } if {$(item_id) ne 0} { if {$(method) ne ""} { set method $(method) } if {![info exists method]} { set method "" } if {$method eq "download"} { set object_id $(item_id) set isObject [::xo::dc 0or1row -prepare integer check_object_id { select 1 from acs_objects where object_id = :object_id }] if {!$isObject} { # # Something horrible must have happened. We have a cached # item_id, which is not an object. # ns_log error "GN: BIG PROBLEM: the cache lookup of <$(parent_id)-$(name)> returned" "something, which is not an object <$(item_id)>.. flush cache for this" xo::xotcl_object_type_cache flush -partition_key $(parent_id) $(parent_id-$(name) set parent_id $(parent_id) set name $(name) set fetched_id [::xo::dc get_value -prepare integer,text check_object_id { select item_id from cr_items where parent_id = :parent_id and name = :name }] ns_log notice "... refetched ID <$(parent_id)-$(name)> -> $fetched_id" set (item_id) $fetched_id } } try { :get_page_from_item_or_revision_id $(item_id) } on error {errorMsg} { ns_log error "GN: BIG PROBLEM 2: could not fetch page for item_id '$(item_id)' CONTEXT: [array get {}]" try { set cache_name [::nsf::dispatch xo::xotcl_object_type_cache cache_name $(item_id)] set cache_key $(parent_id)-$(name) set cache_value "NONE" set cached [ns_cache_get $cache_name $cache_key cache_value] set cache_info "cache_name $cache_name cache_key $cache_key cached $cached cache_value $cache_value" if {$cached} { xo::xotcl_object_type_cache flush -partition_key $(parent_id) $(parent_id)-$(name) } } on error {errorMsg} { set cache_info "no cache info <$errorMsg>" } ns_log notice "... cache info $cache_info" return -code error -errorcode $::errorCode -errorinfo $::errorInfo $errorMsg } on ok {result} { set page $result } try { set cache_name [::nsf::dispatch xo::xotcl_object_type_cache cache_name $(item_id)] set cache_key $(parent_id)-$(name) set cache_value "NONE" set cached [ns_cache_get $cache_name $cache_key cache_value] set cache_info "cache_name $cache_name cache_key $cache_key cached $cached cache_value $cache_value" } on error {errorMsg} { set cache_info "no cache info <$errorMsg>" } #ns_log notice "GOT <$page> cache info $cache_info" # TODO: remove me when settled if {[$page info vars storage_type] eq ""} {ad_log notice "$page has no storage_type"} if {[info exists (logical_package_id)] && [info exists (logical_parent_id)]} { # # If there was a logical_package_id provided from # item_info_from_url, we require that also a logical_parent_id # is required. In this case, change the context of the # resolved package to this page. # $page set_resolve_context -package_id $(logical_package_id) -parent_id $(logical_parent_id) } return $page } if {$simple} { return "" } #:log "NOT found object=$object" # try standard page set standard_page [${:id} get_parameter -check_query_parameter false $(stripped_name)_page] if {$standard_page ne ""} { # # Allow for now mapped standard pages just on the top-level # set page [:get_page_from_item_ref -allow_cross_package_item_refs false -use_package_path true -use_site_wide_pages true -use_prototype_pages true -default_lang $lang -parent_id ${:folder_id} $standard_page] #:log "--o resolving standard_page '$standard_page' returns $page" if {$page ne ""} { return $page } # Maybe we are calling from a different language, but the # standard page with en: was already instantiated. #set standard_page "en:$stripped_object" #set page [:resolve_request -default_lang en -path $standard_page method] #:msg "resolve -default_lang en -path $standard_page returns --> $page" #if {$page ne ""} { # return $page #} } # Maybe, a prototype page was imported with language en:, but the current language is different #if {$lang ne "en"} { # set page [:resolve_request -default_lang en -path $stripped_object method] # #:msg "resolve -default_lang en -path $stripped_object returns --> $page" # if {$page ne ""} { # return $page # } #} if {$use_package_path} { # Check for this page along the package path #:log "check along package path" foreach package [:package_path] { set page [$package resolve_page -simple true -lang $lang $object method] if {$page ne ""} { #:log "set_resolve_context inherited -package_id ${:id} -parent_id ${:folder_id}" $page set_resolve_context -package_id ${:id} -parent_id ${:folder_id} return $page } } #:log "package path done [array get {}]" } # # The call ":lookup -use_site_wide_pages true" works for looking # up the site-wide-pages all kind of packages, not only ::xowiki::Package # set (item_id) [:lookup -use_site_wide_pages true -name en:$(stripped_name)] set page [expr {$(item_id) != 0 ? [:get_page_from_item_or_revision_id $(item_id)] : ""}] #:log "get_site_wide_page for en:'$(stripped_name)' returned '$page' (stripped name)" if {$page ne ""} { #:log "set_resolve_context site-wide -package_id ${:id} -parent_id ${:folder_id}" $page set_resolve_context -package_id ${:id} -parent_id ${:folder_id} return $page } # # Is the current user allowed to create a page from the prototype # pages? In some packages, this might not be allowed. # if {[:check_permissions -package_id ${:id} [self] create-from-prototype]} { :log "try to import a prototype page for '$(stripped_name)' [array get {}]" if {$(stripped_name) ne ""} { # # Try to import of prototype pages into the actual folder. # if {[info exists (logical_parent_id)]} { set parent_id $(logical_parent_id) } elseif {[info exists (parent_id)]} { set parent_id $(parent_id) } else { set parent_id ${:folder_id} } set page [:www-import-prototype-page -lang $lang -parent_id $parent_id -add_revision false $(stripped_name)] } if {$page eq ""} { :log "no prototype for '$object' found" } } return $pageXQL Not present: Generic, PostgreSQL, Oracle