• Publicity: Public Only All

attachments-procs.tcl

Attachments

Location:
packages/attachments/tcl/attachments-procs.tcl
Author:
Arjun Sanyal <arjun@openforce.net>
CVS Identification:
$Id: attachments-procs.tcl,v 1.23.2.10 2022/09/12 14:43:22 antoniop Exp $

Procedures in this file

Detailed information

attachments::add_attachment_url (public)

 attachments::add_attachment_url [ -folder_id folder_id ] \
    [ -package_id package_id ] -object_id object_id \
    [ -return_url return_url ] [ -pretty_name pretty_name ]
Switches:
-folder_id
(optional)
-package_id
(optional)
-object_id
(required)
-return_url
(optional)
-pretty_name
(optional)
Returns:
the url that can be used to attach something to an object

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::add_attachment_url attachments::add_attachment_url test_attachments_url_api->attachments::add_attachment_url attachments::get_attachments_url attachments::get_attachments_url (private) attachments::add_attachment_url->attachments::get_attachments_url packages/calendar/www/cal-item-view.tcl packages/calendar/ www/cal-item-view.tcl packages/calendar/www/cal-item-view.tcl->attachments::add_attachment_url packages/forums/lib/message/post.tcl packages/forums/ lib/message/post.tcl packages/forums/lib/message/post.tcl->attachments::add_attachment_url

Testcases:
attachments_url_api

attachments::attach (public)

 attachments::attach -object_id object_id -attachment_id attachment_id \
    [ -approved_p approved_p ]

perform the attachment

Switches:
-object_id
(required)
-attachment_id
(required)
-approved_p
(defaults to "t") (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_basic_api attachments_basic_api (test attachments) attachments::attach attachments::attach test_attachments_basic_api->attachments::attach db_dml db_dml (public) attachments::attach->db_dml packages/attachments/www/attach-2.tcl packages/attachments/ www/attach-2.tcl packages/attachments/www/attach-2.tcl->attachments::attach packages/attachments/www/file-add-2.tcl packages/attachments/ www/file-add-2.tcl packages/attachments/www/file-add-2.tcl->attachments::attach packages/attachments/www/simple-add-2.tcl packages/attachments/ www/simple-add-2.tcl packages/attachments/www/simple-add-2.tcl->attachments::attach packages/forums/lib/message/post.tcl packages/forums/ lib/message/post.tcl packages/forums/lib/message/post.tcl->attachments::attach richtext::ckeditor4::ckfinder::file_attach richtext::ckeditor4::ckfinder::file_attach (public) richtext::ckeditor4::ckfinder::file_attach->attachments::attach

Testcases:
attachments_basic_api

attachments::context_bar (public)

 attachments::context_bar -folder_id folder_id [ -final final ] \
    [ -extra_vars extra_vars ] [ -multirow multirow ]

Create a multirow with cols (url title) for the file-storage bar starting at folder_id

Switches:
-folder_id
(required)
-final
(optional)
-extra_vars
(optional)
-multirow
(defaults to "fs_context") (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::context_bar attachments::context_bar test_attachments_url_api->attachments::context_bar _ _ (public) attachments::context_bar->_ attachments::get_root_folder attachments::get_root_folder (public) attachments::context_bar->attachments::get_root_folder fs_context_bar_list fs_context_bar_list (public) attachments::context_bar->fs_context_bar_list template::multirow template::multirow (public) attachments::context_bar->template::multirow packages/attachments/www/attach.tcl packages/attachments/ www/attach.tcl packages/attachments/www/attach.tcl->attachments::context_bar

Testcases:
attachments_url_api

attachments::detach_url (public)

 attachments::detach_url [ -package_id package_id ] \
    -object_id object_id -attachment_id attachment_id \
    [ -base_url base_url ] [ -return_url return_url ]
Switches:
-package_id
(optional)
-object_id
(required)
-attachment_id
(required)
-base_url
(optional)
-return_url
(optional)
Returns:
the url to detach an attached item from an object

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::detach_url attachments::detach_url test_attachments_url_api->attachments::detach_url ad_urlencode ad_urlencode (public) attachments::detach_url->ad_urlencode attachments::get_attachments_url attachments::get_attachments_url (private) attachments::detach_url->attachments::get_attachments_url attachments::get_all_attachments attachments::get_all_attachments (public) attachments::get_all_attachments->attachments::detach_url packages/forums/lib/message/attachment-list.tcl packages/forums/ lib/message/attachment-list.tcl packages/forums/lib/message/attachment-list.tcl->attachments::detach_url

Testcases:
attachments_url_api

attachments::get_all_attachments (public)

 attachments::get_all_attachments -object_id object_id \
    [ -base_url base_url ] [ -return_url return_url ] \
    [ -approved_only ] [ -add_detach_url ]
Switches:
-object_id
(required)
object to check for attachments.
-base_url
(optional)
URL path that will be prepended to generated URLs.
-return_url
(optional)
only meaningful if we are also generating detach_url, is the location we will return to after detaching.
-approved_only
(boolean) (optional)
flag deciding if we want to return only attachments that have been approved. All attachments will be returned when this is not specified.
-add_detach_url
(boolean) (optional)
flag deciding whether we want to generate also detach_url in the result.
Returns:
a list representing attachments and their UI URLs.
list of lists in the format {item_id name url} or {item_id name url detach_url} when add_detach_url is specified.

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_basic_api attachments_basic_api (test attachments) attachments::get_all_attachments attachments::get_all_attachments test_attachments_basic_api->attachments::get_all_attachments attachments::detach_url attachments::detach_url (public) attachments::get_all_attachments->attachments::detach_url attachments::get_title attachments::get_title (public) attachments::get_all_attachments->attachments::get_title attachments::goto_attachment_url attachments::goto_attachment_url (public) attachments::get_all_attachments->attachments::goto_attachment_url db_list_of_lists db_list_of_lists (public) attachments::get_all_attachments->db_list_of_lists attachments::get_attachments attachments::get_attachments (public) attachments::get_attachments->attachments::get_all_attachments

Testcases:
attachments_basic_api

attachments::get_attachments (public)

 attachments::get_attachments -object_id object_id \
    [ -base_url base_url ] [ -return_url return_url ]
Switches:
-object_id
(required)
-base_url
(optional)
-return_url
(optional)
Returns:
a list of attachment ids and names which are approved: {item_id name url detach_url}

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_basic_api attachments_basic_api (test attachments) attachments::get_attachments attachments::get_attachments test_attachments_basic_api->attachments::get_attachments attachments::get_all_attachments attachments::get_all_attachments (public) attachments::get_attachments->attachments::get_all_attachments forum::message::get_attachments forum::message::get_attachments (public, deprecated) forum::message::get_attachments->attachments::get_attachments forum::message::notify_users forum::message::notify_users (private) forum::message::notify_users->attachments::get_attachments packages/calendar/www/cal-item-view.tcl packages/calendar/ www/cal-item-view.tcl packages/calendar/www/cal-item-view.tcl->attachments::get_attachments packages/forums/lib/message/attachment-list.tcl packages/forums/ lib/message/attachment-list.tcl packages/forums/lib/message/attachment-list.tcl->attachments::get_attachments packages/richtext-ckeditor4/lib/file-browser.tcl packages/richtext-ckeditor4/ lib/file-browser.tcl packages/richtext-ckeditor4/lib/file-browser.tcl->attachments::get_attachments

Testcases:
attachments_basic_api

attachments::get_package_key (public)

 attachments::get_package_key
Returns:
the package key (attachments)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_package_key attachments_package_key (test attachments) attachments::get_package_key attachments::get_package_key test_attachments_package_key->attachments::get_package_key attachments::get_url attachments::get_url (public) attachments::get_url->attachments::get_package_key

Testcases:
attachments_package_key

attachments::get_root_folder (public)

 attachments::get_root_folder [ -package_id package_id ]
Switches:
-package_id
(optional)
when omitted, will default to the package mounted on the current node's parent.
Returns:
the attachment root folder id for the package.

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::get_root_folder attachments::get_root_folder test_attachments_url_api->attachments::get_root_folder ad_conn ad_conn (public) attachments::get_root_folder->ad_conn db_string db_string (public) attachments::get_root_folder->db_string site_node::get_parent site_node::get_parent (public) attachments::get_root_folder->site_node::get_parent attachments::context_bar attachments::context_bar (public) attachments::context_bar->attachments::get_root_folder packages/attachments/www/admin/new-root-folder-map.tcl packages/attachments/ www/admin/new-root-folder-map.tcl packages/attachments/www/admin/new-root-folder-map.tcl->attachments::get_root_folder packages/attachments/www/attach.tcl packages/attachments/ www/attach.tcl packages/attachments/www/attach.tcl->attachments::get_root_folder packages/attachments/www/file-add-2.tcl packages/attachments/ www/file-add-2.tcl packages/attachments/www/file-add-2.tcl->attachments::get_root_folder

Testcases:
attachments_url_api

attachments::get_title (public)

 attachments::get_title -attachment_id attachment_id
Switches:
-attachment_id
(required)
ID of the attachment (item_id)
Returns:
The title of the attachment (string)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_name_api attachments_name_api (test attachments) attachments::get_title attachments::get_title test_attachments_name_api->attachments::get_title acs_object::get_element acs_object::get_element (public) attachments::get_title->acs_object::get_element acs_object_type acs_object_type (public) attachments::get_title->acs_object_type content::extlink::is_extlink content::extlink::is_extlink (public) attachments::get_title->content::extlink::is_extlink content::extlink::name content::extlink::name (public) attachments::get_title->content::extlink::name content::item::get_title content::item::get_title (public) attachments::get_title->content::item::get_title attachments::get_all_attachments attachments::get_all_attachments (public) attachments::get_all_attachments->attachments::get_title packages/attachments/www/detach.tcl packages/attachments/ www/detach.tcl packages/attachments/www/detach.tcl->attachments::get_title

Testcases:
attachments_name_api

attachments::get_url (public)

 attachments::get_url
Returns:
the value of the RelativeUrl package parameter

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::get_url attachments::get_url test_attachments_url_api->attachments::get_url apm_package_id_from_key apm_package_id_from_key (public) attachments::get_url->apm_package_id_from_key attachments::get_package_key attachments::get_package_key (public) attachments::get_url->attachments::get_package_key parameter::get parameter::get (public) attachments::get_url->parameter::get attachments::get_attachments_url attachments::get_attachments_url (private) attachments::get_attachments_url->attachments::get_url attachments::graphic_url attachments::graphic_url (public) attachments::graphic_url->attachments::get_url

Testcases:
attachments_url_api

attachments::goto_attachment_url (public)

 attachments::goto_attachment_url [ -package_id package_id ] \
    -object_id object_id -attachment_id attachment_id \
    [ -base_url base_url ]
Switches:
-package_id
(optional)
-object_id
(required)
-attachment_id
(required)
-base_url
(optional)
Returns:
the url to go to an attachment

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::goto_attachment_url attachments::goto_attachment_url test_attachments_url_api->attachments::goto_attachment_url attachments::get_attachments_url attachments::get_attachments_url (private) attachments::goto_attachment_url->attachments::get_attachments_url attachments::get_all_attachments attachments::get_all_attachments (public) attachments::get_all_attachments->attachments::goto_attachment_url

Testcases:
attachments_url_api

attachments::graphic_url (public)

 attachments::graphic_url [ -package_id package_id ]
Switches:
-package_id
(optional)
Returns:
the attachment icon

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_url_api attachments_url_api (test attachments) attachments::graphic_url attachments::graphic_url test_attachments_url_api->attachments::graphic_url attachments::get_url attachments::get_url (public) attachments::graphic_url->attachments::get_url packages/forums/lib/message/attachment-list.tcl packages/forums/ lib/message/attachment-list.tcl packages/forums/lib/message/attachment-list.tcl->attachments::graphic_url

Testcases:
attachments_url_api

attachments::map_root_folder (public)

 attachments::map_root_folder -package_id package_id \
    -folder_id folder_id

Designate a folder as the attachment root folder for a package.

Switches:
-package_id
(required)
-folder_id
(required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_map_folder attachments_map_folder (test attachments) attachments::map_root_folder attachments::map_root_folder test_attachments_map_folder->attachments::map_root_folder db_dml db_dml (public) attachments::map_root_folder->db_dml packages/attachments/www/admin/new-root-folder-map-2.tcl packages/attachments/ www/admin/new-root-folder-map-2.tcl packages/attachments/www/admin/new-root-folder-map-2.tcl->attachments::map_root_folder packages/attachments/www/admin/new-root-folder-map.tcl packages/attachments/ www/admin/new-root-folder-map.tcl packages/attachments/www/admin/new-root-folder-map.tcl->attachments::map_root_folder

Testcases:
attachments_map_folder

attachments::root_folder_map_p (public, deprecated)

 attachments::root_folder_map_p -package_id package_id
Deprecated. Invoking this procedure generates a warning.

Switches:
-package_id
(required)
Returns:
1 if the package_id has an fs_folder mapped to it
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 ad_log_deprecated ad_log_deprecated (public) attachments::root_folder_p attachments::root_folder_p (public) attachments::root_folder_map_p attachments::root_folder_map_p attachments::root_folder_map_p->ad_log_deprecated attachments::root_folder_map_p->attachments::root_folder_p

Testcases:
No testcase defined.

attachments::root_folder_p (public)

 attachments::root_folder_p -package_id package_id
Switches:
-package_id
(required)
Returns:
1 if the package_id has an fs_folder mapped to it

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_map_folder attachments_map_folder (test attachments) attachments::root_folder_p attachments::root_folder_p test_attachments_map_folder->attachments::root_folder_p db_string db_string (public) attachments::root_folder_p->db_string attachments::root_folder_map_p attachments::root_folder_map_p (public, deprecated) attachments::root_folder_map_p->attachments::root_folder_p packages/attachments/www/admin/new-root-folder-map.tcl packages/attachments/ www/admin/new-root-folder-map.tcl packages/attachments/www/admin/new-root-folder-map.tcl->attachments::root_folder_p

Testcases:
attachments_map_folder

attachments::toggle_approved (public)

 attachments::toggle_approved -object_id object_id -item_id item_id \
    [ -approved_p approved_p ]

toggle approved_p for attachment

Switches:
-object_id
(required)
-item_id
(required)
-approved_p
(optional)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_basic_api attachments_basic_api (test attachments) attachments::toggle_approved attachments::toggle_approved test_attachments_basic_api->attachments::toggle_approved db_dml db_dml (public) attachments::toggle_approved->db_dml packages/attachments/www/toggle-approved.tcl packages/attachments/ www/toggle-approved.tcl packages/attachments/www/toggle-approved.tcl->attachments::toggle_approved

Testcases:
attachments_basic_api

attachments::unattach (public)

 attachments::unattach -object_id object_id \
    -attachment_id attachment_id

undo the attachment

Switches:
-object_id
(required)
-attachment_id
(required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_basic_api attachments_basic_api (test attachments) attachments::unattach attachments::unattach test_attachments_basic_api->attachments::unattach db_dml db_dml (public) attachments::unattach->db_dml packages/attachments/www/detach.tcl packages/attachments/ www/detach.tcl packages/attachments/www/detach.tcl->attachments::unattach

Testcases:
attachments_basic_api

attachments::unmap_root_folder (public)

 attachments::unmap_root_folder -package_id package_id \
    -folder_id folder_id

Designate a folder as the attachment root folder for a package.

Switches:
-package_id
(required)
-folder_id
(required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_attachments_map_folder attachments_map_folder (test attachments) attachments::unmap_root_folder attachments::unmap_root_folder test_attachments_map_folder->attachments::unmap_root_folder db_dml db_dml (public) attachments::unmap_root_folder->db_dml

Testcases:
attachments_map_folder
[ hide source ] | [ make this the default ]

Content File Source

#
#  This is free software; you can redistribute it and/or modify it under the
#  terms of the GNU General Public License as published by the Free Software
#  Foundation; either version 2 of the License, or (at your option) any later
#  version.
#
#  This is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
#  details.
#

ad_library {
    Attachments

    @author Arjun Sanyal (arjun@openforce.net)
    @cvs-id $Id: attachments-procs.tcl,v 1.23.2.10 2022/09/12 14:43:22 antoniop Exp $
}

namespace eval attachments {

    d_proc -public root_folder_p {
        {-package_id:required}
    } {
        @return 1 if the package_id has an fs_folder mapped to it
    } {
        return [db_string root_folder_p_select {} -default 0]
    }

    d_proc -public get_root_folder {
        {-package_id ""}
    } {
        @param package_id when omitted, will default to the package
                          mounted on the current node's parent.
        @return the attachment root folder id for the package.
    } {
        if {$package_id eq ""} {
            # Get the package ID from the parent URL
            array set parent_node [site_node::get_parent -node_id [ad_conn node_id]]
            set package_id $parent_node(object_id)
        }

        return [db_string get_root_folder_select {} -default {}]
    }

    d_proc -deprecated root_folder_map_p {
        {-package_id:required}
    } {
        @return 1 if the package_id has an fs_folder mapped to it

        @see attachments::root_folder_p
    } {
        # this is a duplicate (Ben)
        return [root_folder_p -package_id $package_id]
    }

    d_proc -public map_root_folder {
        {-package_id:required}
        {-folder_id:required}
    } {
        Designate a folder as the attachment root folder for a
        package.
    } {
        db_dml map_root_folder_insert {}
    }

    d_proc -public unmap_root_folder {
        {-package_id:required}
        {-folder_id:required}
    } {
        Designate a folder as the attachment root folder for a
        package.
    } {
        db_dml unmap_root_folder_delete {}
    }

    d_proc -public attach {
        {-object_id:required}
        {-attachment_id:required}
        {-approved_p t}
    } {
        perform the attachment
    } {
        db_dml insert_attachment {}
    }

    d_proc -public unattach {
        {-object_id:required}
        {-attachment_id:required}
    } {
        undo the attachment
    } {
        db_dml delete_attachment {}
    }

    d_proc -public toggle_approved {
        {-object_id:required}
        {-item_id:required}
        {-approved_p ""}
    } {
        toggle approved_p for attachment
    } {
        db_dml toggle_approved_p {}
    }

    ad_proc -public get_package_key {} {
        @return the package key (attachments)
    } {
        return attachments
    }

    ad_proc -public get_url {} {
        @return the value of the RelativeUrl package parameter
    } {
        return [parameter::get  \
            -package_id [apm_package_id_from_key [get_package_key]] \
            -parameter RelativeUrl
        ]
    }

    d_proc -private get_attachments_url {
        {-base_url ""}
    } {

        As 'attachments::get_url' returns the value of the attachments package
        'RelativeUrl' parameter, which can change at any time, it could happen
        that previously mounted attachments have a different url and are not
        found anymore.

        We try our best here to find a mounted attachments package under
        'base_url' to mitigate this, probably flawed, package logic.

        In the future, probably a better method should be used for URL resolving
        that is not so broken.

        The whole thing is even more weird, as the attachments package is
        currently a singleton that auto-mounts on /attachments, so i am tempted
        to replace this whole thing with just that, but anyway...

        @param base_url The base URL where to look for the attachments package.

        @return The attachments package URL under 'base_url', or "" if none is
                found.

        @see attachments::get_url

    } {
        if {![ns_conn isconnected]} {
            return "${base_url}[attachments::get_url]"
        } else {
            #
            # Get some context
            #
            set url             "[ad_conn package_url]${base_url}"
            set relative_url    "${url}[attachments::get_url]"
            #
            # Is this URL an attachments package? Otherwise try to find one...
            #
            set package_key [dict get [site_node::get_from_url -url "$relative_url"] package_key]
            if {$package_key eq "attachments"} {
                return $relative_url
            } else {
                set url_node_id [site_node::get_node_id -url $url]
                return [site_node::get_children \
                            -package_key "attachments" \
                            -element "url" \
                            -node_id $url_node_id]
            }
        }
    }

    d_proc -public add_attachment_url {
        {-folder_id ""}
        {-package_id ""}
        {-object_id:required}
        {-return_url ""}
        {-pretty_name ""}
    } {
        @return the url that can be used to attach something to an object
    } {
        return "[get_attachments_url]/attach?pretty_object_name=[ns_urlencode $pretty_name]&folder_id=$folder_id&object_id=$object_id&return_url=[ns_urlencode $return_url]"
    }

    d_proc -public goto_attachment_url {
        {-package_id ""}
        {-object_id:required}
        {-attachment_id:required}
        {-base_url ""}
    } {
        @return the url to go to an attachment
    } {
        return "[get_attachments_url -base_url ${base_url}]/go-to-attachment?object_id=$object_id&attachment_id=$attachment_id"
    }

    d_proc -public detach_url {
        {-package_id ""}
        {-object_id:required}
        {-attachment_id:required}
        {-base_url ""}
        {-return_url ""}
    } {
        @return the url to detach an attached item from an object
    } {
        return "[get_attachments_url -base_url ${base_url}]/detach?object_id=$object_id&attachment_id=$attachment_id&return_url=[ad_urlencode $return_url]"
    }

    d_proc -public graphic_url {
        {-package_id ""}
    } {
        @return the attachment icon
    } {
        return "<img valign=bottom src=\"[attachments::get_url]/graphics/file.gif\">"
    }

    d_proc -public get_attachments {
        {-object_id:required}
        {-base_url ""}
        {-return_url ""}
    } {
        @return a list of attachment ids and names which are approved:
        {item_id name url detach_url}
    } {
        return [get_all_attachments \
                    -object_id $object_id \
                    -base_url $base_url \
                    -return_url $return_url \
                    -approved_only -add_detach_url]
    }

    d_proc -public get_title {
        {-attachment_id:required}
    } {
        @param attachment_id ID of the attachment (item_id)
        @return The title of the attachment (string)
    } {
        #
        # Try our best to get the 'title', depending on the object type
        #
        set title ""
        set object_type [acs_object_type $attachment_id]
        if {[content::extlink::is_extlink -item_id $attachment_id]} {
            #
            # URL
            #
            set title [content::extlink::name -item_id $attachment_id]
        } elseif {[content::item::is_subclass \
                        -object_type $object_type \
                        -supertype "content_item"]} {
            #
            # Content item, or subtype
            #
            set title [content::item::get_title -item_id $attachment_id]
        } elseif {[content::item::is_subclass \
                        -object_type $object_type \
                        -supertype "content_revision"]} {
            #
            # Content revision, or subtype
            #
            set title [content::revision::get_title -revision_id $attachment_id]
        } else {
            #
            # Let's try the 'title' column on 'acs_objects'
            #
            set title [acs_object::get_element \
                            -object_id $attachment_id \
                            -element "title"]
        }
        #
        # If everything fails, set the 'attachment_id' as title
        #
        if {$title eq ""} {
            set title $attachment_id
        }

        return $title
    }

    d_proc -public get_all_attachments {
        {-object_id:required}
        {-base_url ""}
        {-return_url ""}
        -approved_only:boolean
        -add_detach_url:boolean
    } {
        @return a list representing attachments and their UI URLs.

        @param object_id object to check for attachments.
        @param base_url URL path that will be prepended to generated URLs.
        @param return_url only meaningful if we are also generating
                          detach_url, is the location we will return
                          to after detaching.
        @param approved_only flag deciding if we want to return only
                             attachments that have been approved. All
                             attachments will be returned when this is
                             not specified.
        @param add_detach_url flag deciding whether we want to
                              generate also detach_url in the result.

        @return list of lists in the format {item_id name url} or
                {item_id name url detach_url} when
                <code>add_detach_url</code> is specified.
    } {
        set lst_with_urls [list]

        foreach item_id [db_list_of_lists select_attachments {
            select item_id from attachments
             where object_id = :object_id
               and (not :approved_only_p or approved_p)}] {
            #
            # Set the attachment 'label'
            #
            set label [attachments::get_title -attachment_id $item_id]
            #
            # Set the attachment URL
            #
            set url [goto_attachment_url \
                         -object_id     $object_id \
                         -attachment_id $item_id \
                         -base_url      $base_url]
            set element [list $item_id $label $url]
            if {$add_detach_url_p} {
                lappend element [detach_url \
                                     -object_id     $object_id \
                                     -attachment_id $item_id \
                                     -base_url      $base_url \
                                     -return_url    $return_url]
            }
            lappend lst_with_urls $element
        }

        return $lst_with_urls
    }

    d_proc -public context_bar {
        {-folder_id:required}
        {-final ""}
        {-extra_vars ""}
        {-multirow "fs_context"}
    } {
        Create a multirow with cols (url title) for the file-storage bar
        starting at folder_id
    } {

        set root_folder_id [attachments::get_root_folder]

        set cbar_list [fs_context_bar_list -extra_vars $extra_vars -folder_url "attach" -file_url "attach" -root_folder_id $root_folder_id -final $final $folder_id]

        template::multirow create $multirow url label

        if { $root_folder_id ne "" && $cbar_list ne "" } {
            template::multirow append $multirow "attach?${extra_vars}&folder_id=$root_folder_id" [_ attachments.Top]
            foreach elm $cbar_list {
                if { [llength elm] > 1 } {
                    template::multirow append $multirow [lindex $elm 0] [lindex $elm 1]
                } else {
                    template::multirow append $multirow "" $elm
                }
            }
        } else {
            template::multirow append $multirow "" [_ attachments.Top]
        }
    }

}

# Local variables:
#    mode: tcl
#    tcl-indent-level: 4
#    indent-tabs-mode: nil
# End: