Ticket Tracker Lite: Developers Notes
-@context@
+{{./} {ticket tracker lite}} {developer notes}
By David Rodriguez (dvr@arsdigita.com)
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/developer.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp,v
diff -u -r1.2 -r1.3
--- openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp 6 Sep 2002 13:28:02 -0000 1.2
+++ openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.adp 16 Jan 2003 14:06:29 -0000 1.3
@@ -1,6 +1,6 @@
-
+
Using the ticket tracker
-@context@
+{{./} {ticket tracker lite}} help
The ticket tracker is a tool for development teams and their
clients to organize bug reports and feature requests.
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/help.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp,v
diff -u -r1.4 -r1.5
--- openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp 6 Sep 2002 13:28:02 -0000 1.4
+++ openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.adp 16 Jan 2003 14:06:29 -0000 1.5
@@ -1,6 +1,6 @@
-
+
Ticket Tracker Lite
-@context@
+"ticket tracker lite"
By David Rodriguez (dvr@arsdigita.com)
Fisheye: Tag 1.3 refers to a dead (removed) revision in file `openacs-4/contrib/obsolete-packages/ticket-tracker-lite/www/doc/index.tcl'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/static-pages/static-pages.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/static-pages.info,v
diff -u -r1.12 -r1.13
--- openacs-4/packages/static-pages/static-pages.info 23 Sep 2002 23:32:34 -0000 1.12
+++ openacs-4/packages/static-pages/static-pages.info 16 Jan 2003 13:58:34 -0000 1.13
@@ -5,18 +5,18 @@
Static Pages
Static Pages
f
- t
+ f
-
+
oracle
postgresql
- Brandoch Calef
- Brandoch Calef
+ Dave Bauer
+ Andrew Piskorski
Static Pages makes it possible to search and comment on static pages.
- 2001-03-09
- ArsDigita Corporation
+ 2002-12-11
+ OpenACS
Static Pages loads the static pages of a site into the database so that their contents are available to other packages, such as site-wide-search. It also allows users to make comments on static pages.
@@ -34,17 +34,14 @@
-
-
-
-
+
@@ -53,7 +50,7 @@
-
+
@@ -64,7 +61,6 @@
-
@@ -76,13 +72,14 @@
-
+
+
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/oracle/static-page-pb.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/oracle/static-page-ph.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql,v
diff -u -r1.1 -r1.2
--- openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql 20 Apr 2001 20:51:22 -0000 1.1
+++ openacs-4/packages/static-pages/sql/oracle/static-pages-create.sql 16 Jan 2003 13:59:05 -0000 1.2
@@ -48,6 +48,17 @@
create index sp_folders_parent_id_idx on sp_folders(parent_id);
create index sp_folders_package_id_idx on sp_folders(package_id);
+
+-- TODO: Why exactly do we need the sp_folders table to completely
+-- mirror the hierarchy in the Content Repository, rather than just
+-- using a small table to point to the root folders, the way File
+-- Storage does? --atp@piskorski.com, 2001/08/26 21:30 EDT
+
+-- TODO: A root folder has a null sp_folders.parent_id, but we can't
+-- index nulls so may want to add a separate sp_root_folders table or
+-- something. --atp@piskorski.com, 2001/08/26 22:47 EDT
+
+
-- The title and content of each page will go into cr_revisions. Here
-- we record the filename.
--
@@ -66,11 +77,17 @@
constraint static_pgs_show_cmnts_chk
check (show_comments_p in ('t','f'))
);
+
comment on table static_pages is '
Extends the cr_items table to hold information on static pages.
';
comment on column static_pages.filename is '
The full path of the file (e.g. /web/my_site/www/books/index.html).
+ --
+ No, not anymore. As of c. 2001/10/30 changes by daveb, it is a
+ RELATIVE path, relative to the page root (server/www/). As of now,
+ it is relative to the server root (server/). --atp@piskorski.com,
+ 2002/12/12 16:56 EST
';
comment on column static_pages.folder_id is '
ID of folder containing page.
@@ -159,593 +176,8 @@
);
end;
/
+show errros
-create or replace package static_page as
- function new (
- -- /**
- -- * Creates a new content_item and content_revision for a
- -- * static page.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-02
- -- **/
- static_page_id in static_pages.static_page_id%TYPE
- default null,
- folder_id in sp_folders.folder_id%TYPE,
- filename in static_pages.filename%TYPE default null,
- title in cr_revisions.title%TYPE default null,
- content in cr_revisions.content%TYPE default null,
- show_comments_p in static_pages.show_comments_p%TYPE default 't',
- creation_date in acs_objects.creation_date%TYPE
- default sysdate,
- creation_user in acs_objects.creation_user%TYPE
- default null,
- creation_ip in acs_objects.creation_ip%TYPE
- default null,
- context_id in acs_objects.context_id%TYPE
- default null
- ) return static_pages.static_page_id%TYPE;
-
- procedure delete (
- -- /**
- -- * Delete a static page, including the associated content_item.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-02
- -- **/
- static_page_id in static_pages.static_page_id%TYPE
- );
-
- function get_root_folder (
- -- /**
- -- * Returns the id of the root folder belonging to this package.
- -- * If none exists, one is created.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-22
- -- **/
- package_id in apm_packages.package_id%TYPE
- ) return sp_folders.folder_id%TYPE;
-
- function new_folder (
- -- /**
- -- * Create a folder in the content_repository to hold files in
- -- * a particular directory.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-02
- -- **/
- folder_id in sp_folders.folder_id%TYPE
- default null,
- name in cr_items.name%TYPE,
- label in cr_folders.label%TYPE,
- description in cr_folders.description%TYPE default null,
- parent_id in cr_items.parent_id%TYPE default null,
- creation_date in acs_objects.creation_date%TYPE
- default sysdate,
- creation_user in acs_objects.creation_user%TYPE
- default null,
- creation_ip in acs_objects.creation_ip%TYPE
- default null,
- context_id in acs_objects.context_id%TYPE
- default null
- ) return sp_folders.folder_id%TYPE;
-
- procedure delete_folder (
- -- /**
- -- * Delete a folder and all the folders and files it contains.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-02
- -- **/
- folder_id in sp_folders.folder_id%TYPE
- );
-
- procedure delete_stale_items (
- -- /**
- -- * Delete items that are in the content repository but not in
- -- * extant_files/extant_folders with the given session_id.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-02
- -- **/
- session_id in sp_extant_files.session_id%TYPE,
- package_id in apm_packages.package_id%TYPE
- );
-
- procedure grant_permission (
- -- /**
- -- * Grant a privilege on a file or folder, perhaps recursively.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-21
- -- **/
- item_id in acs_permissions.object_id%TYPE,
- grantee_id in acs_permissions.grantee_id%TYPE,
- privilege in acs_permissions.privilege%TYPE,
- recursive_p in char
- );
-
- procedure revoke_permission (
- -- /**
- -- * Revoke a privilege on a file or folder, perhaps recursively.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-21
- -- **/
- item_id in acs_permissions.object_id%TYPE,
- grantee_id in acs_permissions.grantee_id%TYPE,
- privilege in acs_permissions.privilege%TYPE,
- recursive_p in char
- );
-
- function five_n_spaces (
- -- /**
- -- * Return 5n nonbreaking spaces.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-27
- -- **/
- n in integer
- ) return varchar2;
-
- procedure set_show_comments_p (
- -- /**
- -- * Establish whether the contents of a comment are displayed
- -- * on a particular page.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-23
- -- **/
- item_id in acs_permissions.object_id%TYPE,
- show_comments_p in static_pages.show_comments_p%TYPE
- );
-
- function get_show_comments_p (
- -- /**
- -- * Retrieve the comment display policy.
- -- *
- -- * @author Brandoch Calef
- -- * @creation-date 2001-02-23
- -- **/
- item_id in acs_permissions.object_id%TYPE
- ) return static_pages.show_comments_p%TYPE;
-
-end static_page;
-/
-
-create or replace package body static_page as
- function new (
- static_page_id in static_pages.static_page_id%TYPE
- default null,
- folder_id in sp_folders.folder_id%TYPE,
- filename in static_pages.filename%TYPE default null,
- title in cr_revisions.title%TYPE default null,
- content in cr_revisions.content%TYPE default null,
- show_comments_p in static_pages.show_comments_p%TYPE default 't',
- creation_date in acs_objects.creation_date%TYPE
- default sysdate,
- creation_user in acs_objects.creation_user%TYPE
- default null,
- creation_ip in acs_objects.creation_ip%TYPE
- default null,
- context_id in acs_objects.context_id%TYPE
- default null
- ) return static_pages.static_page_id%TYPE is
- v_item_id static_pages.static_page_id%TYPE;
- begin
- -- Create content item; this also makes the content revision.
- -- One might be tempted to set the content_type to static_page,
- -- But this would confuse site-wide-search, which expects to
- -- see a content_type of content_revision.
- v_item_id := content_item.new(
- item_id => static_page.new.static_page_id,
- parent_id => static_page.new.folder_id,
- name => static_page.new.filename,
- title => static_page.new.title,
- mime_type => 'text/html',
- creation_date => static_page.new.creation_date,
- creation_user => static_page.new.creation_user,
- creation_ip => static_page.new.creation_ip,
- context_id => static_page.new.context_id,
- is_live => 't',
- data => static_page.new.content
- );
-
- -- We want to be able to have non-commentable folders below
- -- commentable folders. We can't do this if we leave security
- -- inheritance enabled.
- --
- update acs_objects set security_inherit_p = 'f'
- where object_id = v_item_id;
-
- -- Copy permissions from the parent:
- for permission_row in (
- select grantee_id,privilege from acs_permissions
- where object_id = folder_id
- ) loop
- acs_permission.grant_permission(
- object_id => v_item_id,
- grantee_id => permission_row.grantee_id,
- privilege => permission_row.privilege
- );
- end loop;
-
- -- Insert row into static_pages:
- insert into static_pages
- (static_page_id, filename, folder_id, show_comments_p)
- values (
- v_item_id,
- static_page.new.filename,
- static_page.new.folder_id,
- static_page.new.show_comments_p
- );
-
- return v_item_id;
- end;
-
- procedure delete (
- static_page_id in static_pages.static_page_id%TYPE
- ) is
- begin
- -- Delete all permissions on this page:
- delete from acs_permissions where object_id = static_page_id;
-
- -- Drop all comments on this page. general-comments doesn't have
- -- a comment.delete() function, so I just do this (see the
- -- general-comments drop script):
- for comment_row in (
- select comment_id from general_comments
- where object_id = static_page_id
- ) loop
- delete from images
- where image_id in (
- select latest_revision
- from cr_items
- where parent_id = comment_row.comment_id
- );
-
- acs_message.delete(comment_row.comment_id);
- end loop;
-
- -- Delete the page.
- -- WE SHOULDN'T NEED TO DO THIS: CONTENT_ITEM.DELETE SHOULD TAKE CARE OF
- -- DELETING FROM STATIC PAGES.
- delete from static_pages where static_page_id = static_page.delete.static_page_id;
- content_item.delete(static_page_id);
- end;
-
- function get_root_folder (
- package_id in apm_packages.package_id%TYPE
- ) return sp_folders.folder_id%TYPE is
- folder_exists_p integer;
- folder_id sp_folders.folder_id%TYPE;
- begin
- -- If there isn't a root folder for this package, create one.
- -- Otherwise, just return its id.
- select count(*) into folder_exists_p from dual where exists (
- select 1 from sp_folders
- where package_id = static_page.get_root_folder.package_id
- and parent_id is null
- );
-
- if folder_exists_p = 0 then
- folder_id := static_page.new_folder (
- name => 'sp_root',
- label => 'sp_root'
- );
-
- update sp_folders
- set package_id = static_page.get_root_folder.package_id
- where folder_id = static_page.get_root_folder.folder_id;
-
- acs_permission.grant_permission (
- object_id => folder_id,
- grantee_id => acs.magic_object_id('the_public'),
- privilege => 'general_comments_create'
- );
- -- The comments will inherit read permission from the pages,
- -- so the public should be able to read the static pages.
- acs_permission.grant_permission (
- object_id => folder_id,
- grantee_id => acs.magic_object_id('the_public'),
- privilege => 'read'
- );
- else
- select folder_id into folder_id from sp_folders
- where package_id = static_page.get_root_folder.package_id
- and parent_id is null;
- end if;
-
- return folder_id;
- end get_root_folder;
-
-
- function new_folder (
- folder_id in sp_folders.folder_id%TYPE
- default null,
- name in cr_items.name%TYPE,
- label in cr_folders.label%TYPE,
- description in cr_folders.description%TYPE default null,
- parent_id in cr_items.parent_id%TYPE default null,
- creation_date in acs_objects.creation_date%TYPE
- default sysdate,
- creation_user in acs_objects.creation_user%TYPE
- default null,
- creation_ip in acs_objects.creation_ip%TYPE
- default null,
- context_id in acs_objects.context_id%TYPE
- default null
- ) return sp_folders.folder_id%TYPE is
- v_folder_id sp_folders.folder_id%TYPE;
- v_parent_id cr_items.parent_id%TYPE;
- v_package_id apm_packages.package_id%TYPE;
- begin
- if parent_id is null then
- v_parent_id := 0;
- else
- v_parent_id := parent_id;
- end if;
-
- v_folder_id := content_folder.new (
- name => static_page.new_folder.name,
- label => static_page.new_folder.label,
- folder_id => static_page.new_folder.folder_id,
- parent_id => v_parent_id,
- description => static_page.new_folder.description,
- creation_date => static_page.new_folder.creation_date,
- creation_user => static_page.new_folder.creation_user,
- creation_ip => static_page.new_folder.creation_ip,
- context_id => static_page.new_folder.context_id
- );
-
- if parent_id is not null then
- -- Get the package_id from the parent:
- select package_id into v_package_id from sp_folders
- where folder_id = static_page.new_folder.parent_id;
-
- insert into sp_folders (folder_id, parent_id, package_id)
- values (v_folder_id, parent_id, v_package_id);
-
- update acs_objects set security_inherit_p = 'f'
- where object_id = v_folder_id;
-
- -- Copy permissions from the parent:
- for permission_row in (
- select grantee_id,privilege from acs_permissions
- where object_id = parent_id
- ) loop
- acs_permission.grant_permission(
- object_id => v_folder_id,
- grantee_id => permission_row.grantee_id,
- privilege => permission_row.privilege
- );
- end loop;
- else
- insert into sp_folders (folder_id, parent_id)
- values (v_folder_id, parent_id);
-
- -- if it's a root folder, allow it to contain static pages and
- -- other folders (subfolders will inherit these properties)
- content_folder.register_content_type (
- folder_id => v_folder_id,
- content_type => 'static_page'
- );
- content_folder.register_content_type (
- folder_id => v_folder_id,
- content_type => 'content_revision'
- );
- content_folder.register_content_type (
- folder_id => v_folder_id,
- content_type => 'content_folder'
- );
- end if;
-
- return v_folder_id;
- end;
-
- procedure delete_folder (
- folder_id in sp_folders.folder_id%TYPE
- ) is
- begin
- for folder_row in (
- select folder_id from (
- select folder_id,level as path_depth from sp_folders
- start with folder_id = static_page.delete_folder.folder_id
- connect by parent_id = prior folder_id
- ) order by path_depth desc
- ) loop
- for page_row in (
- select static_page_id from static_pages
- where folder_id = folder_row.folder_id
- ) loop
- static_page.delete(page_row.static_page_id);
- end loop;
-
- delete from sp_folders where folder_id = folder_row.folder_id;
- content_folder.delete(folder_row.folder_id);
- end loop;
- end;
-
- procedure delete_stale_items (
- session_id in sp_extant_files.session_id%TYPE,
- package_id in apm_packages.package_id%TYPE
- ) is
- root_folder_id sp_folders.folder_id%TYPE;
- begin
- root_folder_id := static_page.get_root_folder(package_id);
-
- -- First delete all files that are descendants of the root folder
- -- but aren't in sp_extant_files:
- --
- for stale_file_row in (
- select static_page_id from static_pages
- where folder_id in (
- select folder_id from sp_folders
- start with folder_id = root_folder_id
- connect by parent_id = prior folder_id
- ) and static_page_id not in (
- select static_page_id
- from sp_extant_files
- where session_id = static_page.delete_stale_items.session_id
- )
- ) loop
- static_page.delete(stale_file_row.static_page_id);
- end loop;
-
- -- Now delete all folders that aren't in sp_extant_folders. There are two
- -- views created on the fly here: dead (all descendants of the root
- -- folder not in sp_extant_folders) and path (each folder and its depth).
- -- They are joined together to get the depth of all the folders that
- -- need to be deleted. The root folder is excluded because it won't
- -- show up in the filesystem search, so it will be missing from
- -- sp_extant_folders.
- --
- for stale_folder_row in (
- select dead.folder_id from
- (select folder_id from sp_folders
- where (folder_id) not in (
- select folder_id
- from sp_extant_folders
- where session_id = static_page.delete_stale_items.session_id
- )
- ) dead,
- (select folder_id,level as depth from sp_folders
- start with folder_id = root_folder_id
- connect by parent_id = prior folder_id
- ) path
- where dead.folder_id = path.folder_id
- and dead.folder_id <> root_folder_id
- order by path.depth desc
- ) loop
- delete from sp_folders
- where folder_id = stale_folder_row.folder_id;
-
- content_folder.delete(stale_folder_row.folder_id);
- end loop;
- end delete_stale_items;
-
- procedure grant_permission (
- item_id in acs_permissions.object_id%TYPE,
- grantee_id in acs_permissions.grantee_id%TYPE,
- privilege in acs_permissions.privilege%TYPE,
- recursive_p in char
- ) is
- begin
- if recursive_p = 't' then
- -- For each folder that is a descendant of item_id, grant.
- for folder_row in (
- select folder_id from sp_folders
- start with folder_id = item_id
- connect by parent_id = prior folder_id
- ) loop
- acs_permission.grant_permission(
- object_id => folder_row.folder_id,
- grantee_id => static_page.grant_permission.grantee_id,
- privilege => static_page.grant_permission.privilege
- );
- end loop;
- -- For each file that is a descendant of item_id, grant.
- for file_row in (
- select static_page_id from static_pages
- where folder_id in (
- select folder_id from sp_folders
- start with folder_id = item_id
- connect by parent_id = prior folder_id
- )
- ) loop
- acs_permission.grant_permission(
- object_id => file_row.static_page_id,
- grantee_id => static_page.grant_permission.grantee_id,
- privilege => static_page.grant_permission.privilege
- );
- end loop;
- else
- acs_permission.grant_permission(
- object_id => item_id,
- grantee_id => static_page.grant_permission.grantee_id,
- privilege => static_page.grant_permission.privilege
- );
- end if;
- end grant_permission;
-
- procedure revoke_permission (
- item_id in acs_permissions.object_id%TYPE,
- grantee_id in acs_permissions.grantee_id%TYPE,
- privilege in acs_permissions.privilege%TYPE,
- recursive_p in char
- ) is
- begin
- if recursive_p = 't' then
- -- For each folder that is a descendant of item_id, revoke.
- for folder_row in (
- select folder_id from sp_folders
- start with folder_id = item_id
- connect by parent_id = prior folder_id
- ) loop
- acs_permission.revoke_permission(
- object_id => folder_row.folder_id,
- grantee_id => static_page.revoke_permission.grantee_id,
- privilege => static_page.revoke_permission.privilege
- );
- end loop;
- -- For each file that is a descendant of item_id, revoke.
- for file_row in (
- select static_page_id from static_pages
- where folder_id in (
- select folder_id from sp_folders
- start with folder_id = item_id
- connect by parent_id = prior folder_id
- )
- ) loop
- acs_permission.revoke_permission(
- object_id => file_row.static_page_id,
- grantee_id => static_page.revoke_permission.grantee_id,
- privilege => static_page.revoke_permission.privilege
- );
- end loop;
- else
- acs_permission.revoke_permission(
- object_id => item_id,
- grantee_id => static_page.revoke_permission.grantee_id,
- privilege => static_page.revoke_permission.privilege
- );
- end if;
- end revoke_permission;
-
- function five_n_spaces (
- n in integer
- ) return varchar2 is
- space_string varchar2(400);
- begin
- space_string := '';
- for i in 1..n loop
- space_string := space_string || ' ';
- end loop;
- return space_string;
- end five_n_spaces;
-
- procedure set_show_comments_p (
- item_id in acs_permissions.object_id%TYPE,
- show_comments_p in static_pages.show_comments_p%TYPE
- ) is
- begin
- update static_pages
- set show_comments_p = static_page.set_show_comments_p.show_comments_p
- where static_page_id = static_page.set_show_comments_p.item_id;
- end;
-
- function get_show_comments_p (
- item_id in acs_permissions.object_id%TYPE
- ) return static_pages.show_comments_p%TYPE is
- v_show_comments_p static_pages.show_comments_p%TYPE;
- begin
- select show_comments_p into v_show_comments_p from static_pages
- where static_page_id = static_page.get_show_comments_p.item_id;
-
- return v_show_comments_p;
- end;
-
-end static_page;
-/
+@static-page-ph.sql
+@static-page-pb.sql
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/oracle/upgrade/upgrade-4.2a-4.3.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/postgresql/static-page-pb.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql,v
diff -u -r1.18 -r1.19
--- openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql 9 Dec 2001 04:21:58 -0000 1.18
+++ openacs-4/packages/static-pages/sql/postgresql/static-pages-create.sql 16 Jan 2003 14:00:21 -0000 1.19
@@ -254,589 +254,6 @@
'varchar(500)' -- column_spec
);
--- create or replace package body static_page as
-create function static_page__new (
- integer, -- static_page_id in static_pages.static_page_id%TYPE
- -- default null,
- integer, -- folder_id in sp_folders.folder_id%TYPE,
- varchar, -- filename in static_pages.filename%TYPE default null,
- varchar, -- title in cr_revisions.title%TYPE default null,
- text, -- content in cr_revisions.content%TYPE default null,
- boolean, -- show_comments_p in static_pages.show_comments_p%TYPE default 't',
- timestamp, -- creation_date in acs_objects.creation_date%TYPE
- -- default sysdate,
- integer, -- creation_user in acs_objects.creation_user%TYPE
- -- default null,
- varchar, -- creation_ip in acs_objects.creation_ip%TYPE
- -- default null,
- integer, -- context_id in acs_objects.context_id%TYPE
- -- default null
- integer -- mtime
- ) returns integer as '
- declare
- p_static_page_id alias for $1;
- p_folder_id alias for $2;
- p_filename alias for $3;
- p_title alias for $4;
- p_content alias for $5;
- p_show_comments_p alias for $6;
- p_creation_date alias for $7;
- p_creation_user alias for $8;
- p_creation_ip alias for $9;
- p_context_id alias for $10;
- p_mtime alias for $11;
- v_item_id static_pages.static_page_id%TYPE;
- v_permission_row RECORD;
- v_revision_id integer;
- v_is_live boolean default ''t'';
- v_mime_type cr_revisions.mime_type%TYPE default ''text/html'';
- v_storage_type cr_items.storage_type%TYPE default ''file'';
- begin
- -- Create content item; this also makes the content revision.
- -- One might be tempted to set the content_type to static_page,
- -- But this would confuse site-wide-search, which expects to
- -- see a content_type of content_revision.
-
- v_item_id := content_item__new(
- p_static_page_id, -- item_id
- p_filename, -- name
- p_folder_id, -- parent_id
- p_title, -- title
- p_creation_date, -- creation_date
- p_creation_user, -- creation_user
- p_context_id, -- context_id
- p_creation_ip, -- creation_ip
- v_is_live, -- is_live
- v_mime_type, -- mime_type
- p_content, -- text
- v_storage_type, -- storage_type
- FALSE, -- security_inherit_p
- ''STATIC_PAGES'', -- storage_area_key
- ''content_item'', -- item subtype
- ''static_page'' -- content_type
- );
-
-
- -- We want to be able to have non-commentable folders below
- -- commentable folders. We can''t do this if we leave security
- -- inheritance enabled.
- --
--- uses overloaded content_item__new and acs_object__new to set
--- security_inherit_p to ''f'' DaveB
--- update acs_objects set security_inherit_p = ''f''
--- where object_id = v_item_id;
-
- -- Copy permissions from the parent:
- for v_permission_row in
- select grantee_id,privilege from acs_permissions
- where object_id = p_folder_id
- loop
- perform acs_permission__grant_permission(
- v_item_id, -- object_id
- v_permission_row.grantee_id, -- grantee_id
- v_permission_row.privilege -- privilege
- );
- end loop;
-
- -- Insert row into static_pages:
- insert into static_pages
- (static_page_id, filename, folder_id, show_comments_p, mtime)
- values (
- v_item_id,
- p_filename,
- p_folder_id,
- p_show_comments_p,
- p_mtime
- );
-
- return v_item_id;
-end;' language 'plpgsql';
-
-create function static_page__new (
-
- integer, -- folder_id in sp_folders.folder_id%TYPE,
- varchar, -- filename in static_pages.filename%TYPE default null,
- varchar, -- title in cr_revisions.title%TYPE default null
- integer -- mtime
- ) returns integer as '
- declare
- p_folder_id alias for $1;
- p_filename alias for $2;
- p_title alias for $3;
- p_mtime alias for $4;
-
- v_static_page_id static_pages.static_page_id%TYPE;
- v_item_id static_pages.static_page_id%TYPE;
-
- begin
- return static_page__new (
- NULL, -- static_page_id
- p_folder_id, -- folder_id
- p_filename, -- filename
- p_title, -- title
- NULL, -- content
- ''t'', -- show_comments_p
- now(), -- creation_date
- NULL, -- creation_user
- NULL, -- creation_ip
- NULL, -- conext_id
- p_mtime -- mtime
- );
-
-end;' language 'plpgsql';
-
-
-create function static_page__delete (
- integer -- static_page_id in static_pages.static_page_id%TYPE
- ) returns integer as '
- declare
- p_static_page_id alias for $1;
- v_comment_row RECORD;
- v_rec_affected integer;
- v_static_page_id integer;
- begin
- -- Delete all permissions on this page:
-
- delete from acs_permissions where object_id = p_static_page_id;
-
- -- Drop all comments on this page. general-comments doesn''t have
- -- a comment.delete() function, so I just do this (see the
- -- general-comments drop script):
-
- for v_comment_row in
- select comment_id from general_comments
- where object_id = p_static_page_id
- loop
- delete from images
- where image_id in (
- select latest_revision
- from cr_items
- where parent_id = v_comment_row.comment_id
- );
-
- PERFORM acs_message__delete(v_comment_row.comment_id);
- end loop;
-
- -- Delete the page.
- -- WE SHOULDN''T NEED TO DO THIS: CONTENT_ITEM.DELETE SHOULD TAKE CARE OF
- -- DELETING FROM STATIC PAGES.
-
- delete from static_pages where static_page_id = p_static_page_id;
-
- GET DIAGNOSTICS v_rec_affected = ROW_COUNT;
- RAISE NOTICE ''*** Number of rows deleted: %'',v_rec_affected;
- select into v_static_page_id static_page_id from static_pages where static_page_id = p_static_page_id;
- GET DIAGNOSTICS v_rec_affected = ROW_COUNT;
- RAISE NOTICE ''*** selected % rows still in static_pages'',v_rec_affected;
-
-
- PERFORM content_item__delete(p_static_page_id);
-return 0;
-end;' language 'plpgsql';
-
-create function static_page__get_root_folder (
- integer -- package_id in apm_packages.package_id%TYPE
- ) returns integer as '
- declare
- p_package_id alias for $1;
- v_folder_exists_p integer;
- v_folder_id sp_folders.folder_id%TYPE;
- v_rows integer;
-begin
- -- If there isn''t a root folder for this package, create one.
- -- Otherwise, just return its id.
- select count(*) into v_folder_exists_p where exists (
- select 1 from sp_folders
- where package_id = p_package_id
- and parent_id is null
- );
-
- if v_folder_exists_p = 0 then
-
- v_folder_id := static_page__new_folder (
- null,
- ''sp_root'', -- name
- ''sp_root'', -- label
- null,
- null,
- null,
- null,
- null,
- null
- );
-
- update sp_folders
- set package_id = p_package_id
- where folder_id = v_folder_id;
-
- PERFORM acs_permission__grant_permission (
- v_folder_id, -- object_id
- acs__magic_object_id(''the_public''), -- grantee_id
- ''general_comments_create'' -- privilege
- );
- -- The comments will inherit read permission from the pages,
- -- so the public should be able to read the static pages.
- PERFORM acs_permission__grant_permission (
- v_folder_id, -- object_id
- acs__magic_object_id(''the_public''), -- grantee_id
- ''read'' -- privilege
- );
- else
- select folder_id into v_folder_id from sp_folders
- where package_id = p_package_id
- and parent_id is null;
- end if;
-
- return v_folder_id;
-end;' language 'plpgsql';
-
-create function static_page__new_folder (
- integer, -- folder_id in sp_folders.folder_id%TYPE
- -- default null,
- varchar, -- name in cr_items.name%TYPE,
- varchar, -- label in cr_folders.label%TYPE,
- text, -- description in cr_folders.description%TYPE default null,
- integer, -- parent_id in cr_items.parent_id%TYPE default null,
- timestamp, -- creation_date in acs_objects.creation_date%TYPE
- -- default sysdate,
- integer, -- creation_user in acs_objects.creation_user%TYPE
- -- default null,
- varchar, -- creation_ip in acs_objects.creation_ip%TYPE
- -- default null,
- integer -- context_id in acs_objects.context_id%TYPE
- -- default null
- ) returns integer as '
- declare
- p_folder_id alias for $1;
- p_name alias for $2;
- p_label alias for $3;
- p_description alias for $4;
- p_parent_id alias for $5;
- p_creation_date alias for $6;
- p_creation_user alias for $7;
- p_creation_ip alias for $8;
- p_context_id alias for $9;
-
- v_folder_id sp_folders.folder_id%TYPE;
- v_parent_id cr_items.parent_id%TYPE;
- v_package_id apm_packages.package_id%TYPE;
- v_creation_date acs_objects.creation_date%TYPE;
- v_permission_row RECORD;
- begin
- if p_creation_date is null then
- v_creation_date := now();
- else
- v_creation_date := p_creation_date;
- end if;
-
- if p_parent_id is null then
- v_parent_id := 0;
- else
- v_parent_id := p_parent_id;
- end if;
-
- v_folder_id := content_folder__new (
- p_name, -- name
- p_label, -- label
- p_description, -- description
- v_parent_id, -- parent_id
- p_context_id, -- context_id
- p_folder_id, -- folder_id
- v_creation_date, -- creation_date
- p_creation_user, -- creation_user
- p_creation_ip, -- creation_ip
- ''f'' -- secuity_inherit_p
-
- );
-
- if p_parent_id is not null then
- -- Get the package_id from the parent:
- select package_id into v_package_id from sp_folders
- where folder_id = p_parent_id;
-
- insert into sp_folders (folder_id, parent_id, package_id)
- values (v_folder_id, p_parent_id, v_package_id);
-
--- update acs_objects set security_inherit_p = ''f''
--- where object_id = v_folder_id;
-
- -- Copy permissions from the parent:
- for v_permission_row in
- select * from acs_permissions
- where object_id = p_parent_id
- loop
- perform acs_permission__grant_permission(
- v_folder_id, -- object_id
- v_permission_row.grantee_id, -- grantee_id
- v_permission_row.privilege -- privilege
- );
- end loop;
- else
- insert into sp_folders (folder_id, parent_id)
- values (v_folder_id, p_parent_id);
-
- -- if it''s a root folder, allow it to contain static pages and
- -- other folders (subfolders will inherit these properties)
- PERFORM content_folder__register_content_type (
- v_folder_id, -- folder_id
- ''static_page'', -- content_type
- ''f''
- );
- PERFORM content_folder__register_content_type (
- v_folder_id, -- folder_id
- ''content_revision'', -- content_type
- ''f''
- );
- PERFORM content_folder__register_content_type (
- v_folder_id, -- folder_id
- ''content_folder'', -- content_type
- ''f''
- );
- end if;
-
- return v_folder_id;
-end;' language 'plpgsql';
-
-create function static_page__delete_folder (
- integer -- folder_id in sp_folders.folder_id%TYPE
- ) returns integer as '
- declare
- p_folder_id alias for $1;
- v_folder_row RECORD;
- v_page_row RECORD;
- begin
- for v_folder_row in
- select s1.folder_id, tree_level(s1.tree_sortkey) as path_depth
- from sp_folders s1, sp_folders s2
- where s2.folder_id = p_folder_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- order by path_depth desc
- loop
- for v_page_row in
- select static_page_id from static_pages
- where folder_id = v_folder_row.folder_id
- loop
- PERFORM static_page__delete(v_page_row.static_page_id);
- end loop;
-
- delete from sp_folders where folder_id = v_folder_row.folder_id;
- PERFORM content_folder__delete(v_folder_row.folder_id);
- end loop;
-return 0;
-end;' language 'plpgsql';
-
-create function static_page__delete_stale_items (
- integer, -- session_id in sp_extant_files.session_id%TYPE,
- integer -- package_id in apm_packages.package_id%TYPE
- ) returns integer as '
- declare
- p_session_id alias for $1;
- p_package_id alias for $2;
- v_root_folder_id sp_folders.folder_id%TYPE;
- v_stale_file_row RECORD;
- v_stale_folder_row RECORD;
- begin
- v_root_folder_id := static_page__get_root_folder(p_package_id);
-
- -- First delete all files that are descendants of the root folder
- -- but aren''t in sp_extant_files
-
- for v_stale_file_row in
- select sp.static_page_id
- from static_pages sp, sp_folders s1, sp_folders s2
- where sp.folder_id = s1.folder_id
- and s2.folder_id = v_root_folder_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- and not exists (select 1
- from sp_extant_files sef
- where sef.session_id = p_session_id
- and sp.static_page_id = sef.static_page_id)
- loop
- PERFORM static_page__delete(v_stale_file_row.static_page_id);
- end loop;
-
--- Now delete all folders that aren''t in sp_extant_folders. There are two
--- views created on the fly here: dead (all descendants of the root
--- folder not in sp_extant_folders) and path (each folder and its depth).
--- They are joined together to get the depth of all the folders that
--- need to be deleted. The root folder is excluded because it won''t
--- show up in the filesystem search, so it will be missing from
--- sp_extant_folders.
-
- for v_stale_folder_row in
- select dead.folder_id from
- (select folder_id from sp_folders
- where folder_id not in (
- select folder_id
- from sp_extant_folders
- where session_id = p_session_id
- )
- ) dead,
- (select s1.folder_id,tree_level(s1.tree_sortkey) as depth
- from sp_folders s1, sp_folders s2
- where s2.folder_id = v_root_folder_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- ) path
- where dead.folder_id = path.folder_id
- and dead.folder_id <> v_root_folder_id
- order by path.depth desc
- loop
- delete from sp_folders
- where folder_id = v_stale_folder_row.folder_id;
- perform content_folder__delete(v_stale_folder_row.folder_id);
- end loop;
-
-return 0;
-end;' language 'plpgsql';
-
-
-create function static_page__grant_permission (
- integer, -- item_id in acs_permissions.object_id%TYPE,
- integer, -- grantee_id in acs_permissions.grantee_id%TYPE,
- varchar, -- privilege in acs_permissions.privilege%TYPE,
- boolean -- recursive_p in char
- ) returns integer as '
- declare
- p_item_id alias for $1;
- p_grantee_id alias for $2;
- p_privilege alias for $3;
- p_recursive_p alias for $4;
- v_file_row RECORD;
- v_folder_row RECORD;
- begin
- if p_recursive_p = ''t'' then
- -- For each folder that is a descendant of item_id, grant.
- for v_folder_row in
- select s1.folder_id from sp_folders s1, sp_folders s2
- where s2.folder_id = p_item_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- loop
- perform acs_permission__grant_permission(
- v_folder_row.folder_id, -- object_id
- p_grantee_id, -- grantee_id
- p_privilege -- privilege
- );
- end loop;
- -- For each file that is a descendant of item_id, grant.
- for v_file_row in
- select sp.static_page_id
- from static_pages sp, sp_folders s1, sp_folders s2
- where sp.folder_id = s1.folder_id
- and s2.folder_id = p_item_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- loop
- perform acs_permission__grant_permission(
- v_file_row.static_page_id, -- object_id
- p_grantee_id, -- grantee_id
- p_privilege -- privilege
- );
- end loop;
- else
- perform acs_permission__grant_permission(
- p_item_id, -- object_id
- p_grantee_id, -- grantee_id
- p_privilege -- privilege
- );
- end if;
- return 0;
-end;' language 'plpgsql';
-
-
-create function static_page__revoke_permission (
- integer, -- item_id in acs_permissions.object_id%TYPE,
- integer, -- grantee_id in acs_permissions.grantee_id%TYPE,
- varchar, -- privilege in acs_permissions.privilege%TYPE,
- boolean -- recursive_p in char
- ) returns integer as '
- declare
- p_item_id alias for $1;
- p_grantee_id alias for $2;
- p_privilege alias for $3;
- p_recursive_p alias for $4;
- v_file_row RECORD;
- v_folder_row RECORD;
- begin
- if p_recursive_p = ''t'' then
- -- For each folder that is a descendant of item_id, revoke.
- for v_folder_row in
- select s1.folder_id from sp_folders s1, sp_folders s2
- where s2.folder_id = p_item_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- loop
- perform acs_permission__revoke_permission(
- v_folder_row.folder_id, -- object_id
- p_grantee_id, -- grantee_id
- p_privilege -- privilege
- );
- end loop;
- -- For each file that is a descendant of item_id, revoke.
- for v_file_row in
- select sp.static_page_id
- from static_pages sp, sp_folders s1, sp_folders s2
- where sp.folder_id = s1.folder_id
- and s2.folder_id = p_item_id
- and s1.tree_sortkey between s2.tree_sortkey and tree_right(s2.tree_sortkey)
- loop
- perform acs_permission__revoke_permission(
- v_file_row.static_page_id, -- object_id
- p_grantee_id, -- grantee_id
- p_privilege -- privilege
- );
- end loop;
- else
- perform acs_permission__revoke_permission(
- p_item_id, -- object_id
- p_grantee_id, -- grantee_id
- p_privilege -- privilege
- );
- end if;
- return 0;
-end;' language 'plpgsql';
-
-create function static_page__five_n_spaces (
- integer -- n in integer
- ) returns varchar as '
- declare
- p_n alias for $1;
- space_string varchar(400);
- begin
- space_string := '''';
- for i in 1..p_n loop
- space_string := space_string || '' '';
- end loop;
- return space_string;
-end;' language 'plpgsql';
-
-create function static_page__set_show_comments_p (
- integer, -- item_id in acs_permissions.object_id%TYPE,
- boolean -- show_comments_p in static_pages.show_comments_p%TYPE
- ) returns integer as '
- declare
- p_item_id alias for $1;
- p_show_comments_p alias for $2;
- begin
- update static_pages
- set show_comments_p = p_show_comments_p
- where static_page_id = p_item_id;
- return 0;
-end;' language 'plpgsql';
-
-create function static_page__get_show_comments_p (
- integer -- item_id in acs_permissions.object_id%TYPE
- ) returns boolean as '
- declare
- p_item_id alias for $1; -- p_ stands for parameter
- v_show_comments_p static_pages.show_comments_p%TYPE;
- begin
- select show_comments_p into v_show_comments_p from static_pages
- where static_page_id = p_item_id;
-
- return v_show_comments_p;
-end;' language 'plpgsql';
-
-
+\i static-page-pb.sql
\i static-pages-sc-create.sql
--- end static_page;
-
-
Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/static-pages/sql/postgresql/upgrade/upgrade-4.2a-4.3.sql'.
Fisheye: No comparison available. Pass `N' to diff?
Index: openacs-4/packages/static-pages/tcl/static-pages-init.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-init.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/static-pages/tcl/static-pages-init.tcl 15 Dec 2001 01:39:01 -0000 1.2
+++ openacs-4/packages/static-pages/tcl/static-pages-init.tcl 16 Jan 2003 14:01:59 -0000 1.3
@@ -1,13 +1,40 @@
# setup the STATIC_PAGES location for CR_LOCATIONS so that all paths
# stored in the db are relative to the OpenACS installation dir
-if ![nsv_exists CR_LOCATIONS STATIC_PAGES] {
- nsv_set CR_LOCATIONS STATIC_PAGES "[file dirname [string trimright [ns_info tcllib] "/"]]/www"
+if { ![nsv_exists CR_LOCATIONS STATIC_PAGES] } {
+ # Since we allow the fs_root of static-pages package instances to
+ # be beneath the packages/ directory, this must now be relative to
+ # the server root (e.g., "/web/mysite/"), not the web root (e.g.,
+ # "/web/mysite/www/"): --atp@piskorski.com, 2002/12/12 16:17 EST
+
+ nsv_set CR_LOCATIONS STATIC_PAGES "[file dirname [string trimright [ns_info tcllib] "/"]]"
}
-if ![nsv_exists static_pages package_id] {
- nsv_set static_pages package_id [apm_package_id_from_key static-pages]
+
+# Use these to insure that only 1 copy of sp_sync_cr_with_filesystem
+# per Static Pages package instance ever runs at once. For each
+# package_id in the array, empty string means not running, a string
+# means is curretnly running, and the string will give the time the
+# proc started running:
+
+set nsv {sp_sync_cr_fs_times}
+if { ![nsv_array exists $nsv] } {
+ nsv_array set $nsv [list]
+ #nsv_set $nsv foo bar ; nsv_unset $nsv foo
}
+set key {sp_sync_cr_fs_mutex}
+if { ![nsv_exists . $key] } {
+ nsv_set . $key [ns_mutex create]
+}
+
+
+# Register the handler for each static page file extension.
+sp_register_extension
+
+
+# Once per night, at 4 am:
+#ad_schedule_proc -thread t -schedule_proc ns_schedule_daily [list 04 00] sp_sync_cr_with_filesystem_scheduled
+
+
ns_log notice "static-pages-init.tcl loaded"
-
\ No newline at end of file
Index: openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql,v
diff -u -r1.9 -r1.10
--- openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql 6 Sep 2002 12:02:27 -0000 1.9
+++ openacs-4/packages/static-pages/tcl/static-pages-procs-oracle.xql 16 Jan 2003 14:01:59 -0000 1.10
@@ -3,7 +3,7 @@
oracle8.1.6
-
+
begin
@@ -19,7 +19,7 @@
-
+
update cr_revisions set content = empty_blob()
@@ -29,7 +29,7 @@
-
+
select static_page_id from static_pages
@@ -38,33 +38,30 @@
-
+
-
- begin
- :1 := static_page.new(
- filename => :sp_filename,
- title => :page_title,
- folder_id => :parent_folder_id
- );
- end;
-
+begin
+:1 := static_page.new(
+ filename => :sp_filename
+ ,title => :page_title
+ ,folder_id => :parent_folder_id
+ ,mime_type => :mime_type
+);
+end;
-
+
-
update cr_revisions set content = empty_blob()
where revision_id = content_item.get_live_revision(:static_page_id)
returning content into :1
-
-
+
begin
@@ -88,7 +85,7 @@
-
+
select content as file_from_db from cr_revisions
@@ -98,7 +95,7 @@
-
+
select nvl((select item_id from cr_items where name=:cumulative_path),0)
@@ -167,4 +164,35 @@
+
+
+
+select sp.static_page_id, f.package_id
+from static_pages sp, sp_folders f
+where sp.filename = :filename
+and sp.folder_id = f.folder_id
+-- Only want pages from the Static Pages package.
+and f.package_id in (
+ select package_id from apm_packages
+ where package_key = :package_key )
+-- If the same page is in more than one instance of
+-- Static Pages for some reason, we only want one of
+-- them, and we don't care which.
+-- Oracle
+and rownum <= 1
+-- PostgreSQL
+--limit 1
+
+
+
+
+
+
+select site_node.url(min(node_id)) as url
+from site_nodes
+where object_id = :package_id
+
+
+
+
Index: openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql,v
diff -u -r1.17 -r1.18
--- openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql 6 Sep 2002 12:02:27 -0000 1.17
+++ openacs-4/packages/static-pages/tcl/static-pages-procs-postgresql.xql 16 Jan 2003 14:01:59 -0000 1.18
@@ -3,7 +3,7 @@
postgresql7.1
-
+
select content as file_from_db from cr_revisions
@@ -13,7 +13,7 @@
-
+
select coalesce((select item_id from cr_items where name=:cumulative_path),0)
@@ -22,7 +22,7 @@
-
+
select static_page__new_folder (
NULL, -- folder_id
@@ -39,15 +39,15 @@
-
+
update cr_revisions set content = :sp_filename
where revision_id = content_item__get_live_revisions(:static_page_id)
-
+
select static_page_id, mtime as mtime_from_db from static_pages
@@ -56,30 +56,26 @@
-
+
- select static_page__new(
- :parent_folder_id, -- folder_id
- :sp_filename, -- filename
- :page_title, -- title
- :mtime_from_fs -- mtime
-
- );
+select static_page__new(
+ :parent_folder_id, -- folder_id
+ :sp_filename, -- filename
+ :page_title, -- title
+ :mtime_from_fs -- mtime
+ ,:mime_type -- mime_type
+);
-
+
-
update cr_revisions set content = :sp_filename
- where revision_id = content_item__get_live_revisions(:static_page_id)
-
-
-
+ where revision_id = content_item__get_live_revisions(:static_page_id)
-
+
begin
perform static_page__delete_stale_items(:sync_session_id,:package_id);
@@ -159,4 +155,34 @@
+
+
+select sp.static_page_id, f.package_id
+from static_pages sp, sp_folders f
+where sp.filename = :filename
+and sp.folder_id = f.folder_id
+-- Only want pages from the Static Pages package.
+and f.package_id in (
+ select package_id from apm_packages
+ where package_key = :package_key )
+-- If the same page is in more than one instance of
+-- Static Pages for some reason, we only want one of
+-- them, and we don't care which.
+-- Oracle
+--and rownum <= 1
+-- PostgreSQL
+limit 1
+
+
+
+
+
+
+select site_node__url(min(node_id)) as url
+from site_nodes
+where object_id = :package_id
+
+
+
+
Index: openacs-4/packages/static-pages/tcl/static-pages-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs.tcl,v
diff -u -r1.11 -r1.12
--- openacs-4/packages/static-pages/tcl/static-pages-procs.tcl 6 Sep 2002 12:02:27 -0000 1.11
+++ openacs-4/packages/static-pages/tcl/static-pages-procs.tcl 16 Jan 2003 14:01:59 -0000 1.12
@@ -7,18 +7,96 @@
@cvs-id $Id$
}
-ad_proc -public sp_sync_cr_with_filesystem {
+
+ad_proc -public sp_sync_cr_with_filesystem_scheduled {{}} {
+
+ Sync the filesystem and the content repository in a scheduled
+ procedure, rather than manually. Calls sp_sync_cr_with_filesystem
+ just like the www/admin/fs-scan-progress.tcl page does.
+
+
+ Note that if you have comments turned on, be very carefull
+ running this, as the current implementation of
+ sp_sync_cr_with_filesystem will destroy any user
+ contributed comments on the file if you temporarily delete the
+ file, then run that procedure.
+
+ @author Andrew Piskorski (atp@piskorski.com)
+ @creation-date 2002/09/12
+} {
+ set proc_name {sp_sync_cr_with_filesystem_scheduled}
+ ns_log Notice "$proc_name: Starting."
+
+ # sp_sync_cr_with_filesystem callbacks to fill file_items with info:
+
+ proc sp_sch_old_item { path id } {}
+ proc sp_sch_new_item { path id } {}
+ proc sp_sch_changed_item { path id } {
+ # The title may have changed:
+ sp_flush_page $id
+ }
+
+ # TODO: We can have more than one package instance, so must decide
+ # here WHICH package instance to run the sync for. This should
+ # probably be something configurable for each package instance from
+ # the admin page, but for now we simply find and sync ALL package
+ # instances: --atp@piskorski.com, 2002/09/12 14:02 EDT
+
+ set package_key [sp_package_key_is]
+
+ db_foreach each_apm_package_instance {
+ select package_id, instance_name
+ from apm_packages
+ where package_key = :package_key
+ order by package_id
+ } {
+ set root_folder_id [sp_root_folder_id $package_id]
+ set fs_root "[acs_root_dir][ad_parameter -package_id $package_id {fs_root}]"
+
+ ns_log Notice "$proc_name: About to scan the filesystem for: package_id '$package_id', instance_name '$instance_name', fs_root '$fs_root':"
+
+ # If our call to sp_sync_cr_with_filesystem fails for some
+ # reason, want to continue on trying the other package
+ # instances:
+
+ set sync_proc {sp_sync_cr_with_filesystem}
+ if { [catch {
+ set result [$sync_proc -package_id $package_id \
+ -file_unchanged_proc sp_sch_old_item \
+ -file_add_proc sp_sch_new_item \
+ -file_change_proc sp_sch_changed_item \
+ -folder_add_proc sp_sch_new_item \
+ -folder_unchanged_proc sp_sch_old_item \
+ $fs_root $root_folder_id]
+ } errmsg] } {
+ global errorInfo
+ ns_log Error "$proc_name: For package_id: '$package_id', $sync_proc failed with error:\n${errorInfo}"
+ } else {
+ ns_log Notice "$proc_name: For package_id: '$package_id': $result"
+ }
+
+ } if_no_rows {
+ ns_log Warning "$proc_name: NO package ids found for package key: '$package_key'."
+ }
+
+ ns_log Notice "$proc_name: Done."
+}
+
+
+ad_proc -public sp_sync_cr_with_filesystem {
{
- -file_add_proc ""
- -file_change_proc ""
- -file_unchanged_proc ""
- -folder_add_proc ""
- -folder_unchanged_proc ""
+ -file_add_proc ""
+ -file_change_proc ""
+ -file_unchanged_proc ""
+ -file_read_error_proc ""
+ -folder_add_proc ""
+ -folder_unchanged_proc ""
+ -package_id ""
}
fs_root
root_folder_id
{
- static_page_regexp {}
+ static_page_regexp {}
}
} {
Synchronize the content repository with the file system.
@@ -42,7 +120,7 @@
@param folder_unchanged_proc The name of a Tcl proc to be called for each folder
unchanged in the database.
- @param fs_root The starting path in the filesystem. This is relative to the openacs install directory, Files below this point will
+ @param fs_root The starting path in the filesystem. Files below this point will
be scanned.
@param root_folder_id The id of the root folder in the static-pages system (and in
@@ -51,16 +129,185 @@
@param static_page_regexp A regexp to identify static pages.
- @author Brandoch Calef (bcalef@arsdigita.com)
- @creation-date 2001-02-07
+ @param package_id Optionally, the package id of the Static Pages
+ instance. If not specified, determined from ad_conn.
+
+ @author Andrew Piskorski (atp@piskorski.com)
+ @creation-date 2001/08/27
} {
+ if { [empty_string_p $package_id] } {
+ set package_id [ad_conn package_id]
+ }
+
+ if { [catch { set return_val [sp_sync_cr_with_filesystem_internal \
+ -file_add_proc $file_add_proc \
+ -file_change_proc $file_change_proc \
+ -file_unchanged_proc $file_unchanged_proc \
+ -file_read_error_proc $file_read_error_proc \
+ -folder_add_proc $folder_add_proc \
+ -folder_unchanged_proc $folder_unchanged_proc \
+ -package_id $package_id \
+ -stack_depth 2 \
+ {return_mesg} $fs_root $root_folder_id $static_page_regexp ]
+ } result] } {
+ # We caught an unexpected error, so clean up the mutex, and then
+ # re-throw the exact same error:
+
+ sp_sync_cr_with_filesystem_unlock $package_id
+
+ global errorInfo
+ error $result $errorInfo
+ } else {
+ return $return_mesg
+ }
+}
+
+
+ad_proc -private sp_sync_cr_with_filesystem_unlock {package_id} {
+ Unlocks the sp_sync_cr_with_filesystem_times variable - use upon
+ abnormal termination of the sp_sync_cr_with_filesystem_internal
+ stuff. We have it as a separate proc here to make it convenient to
+ call from within multiple different procedures.
+
+ @author Andrew Piskorski (atp@piskorski.com)
+ @creation-date 2001/08/27
+} {
+ set mutex [nsv_get . {sp_sync_cr_fs_mutex}]
+ ns_mutex lock $mutex
+ nsv_set {sp_sync_cr_fs_times} $package_id {}
+ ns_mutex unlock $mutex
+}
+
+
+ad_proc -private sp_sync_cr_with_filesystem_internal {
+ {
+ -file_add_proc ""
+ -file_change_proc ""
+ -file_unchanged_proc ""
+ -file_read_error_proc ""
+ -folder_add_proc ""
+ -folder_unchanged_proc ""
+ -package_id ""
+ -stack_depth 1
+ }
+ return_mesg_var
+ fs_root
+ root_folder_id
+ {
+ static_page_regexp {}
+ }
+} {
+ This procedure was originally named sp_sync_cr_with_filesystem
+ procedure, but has been renamed and modified so that it can be
+ wrapped inside the new sp_sync_cr_with_filesystem, to support the
+ mutex locking.
+
+ We wrap it because at the end of this proc, we must set
+ sp_sync_cr_with_filesystem_times($package_id) back to empty string.
+ But if we hit some random untrapped error partway through, we'll
+ never get there. Therefore, we wrap this proc inside another, and
+ have the wrapper proc catch any errors thrown by this proc, set the
+ var back to empty string, then re-throw the error.
+
+ This procedure takes the exact same arguments as its
+ sp_sync_cr_with_filesystem wrapper proc, except for the addition of
+ return_mesg_var.
+
+ You should never call this procedure, except from
+ sp_sync_cr_with_filesystem.
+
+ @param return_mesg_var Name of variable in which to return text
+ message, for presentation on a web page to the user.
+
+ @param package_id Must be passed in, for this internal
+ version of the proc.
+
+ @author Brandoch Calef (bcalef@arsdigita.com)
+ @author Andrew Piskorski (atp@piskorski.com)
+ @creation-date 2001-02-07
+} {
+ set proc_name {sp_sync_cr_with_filesystem_internal}
+
+ if { [empty_string_p $package_id] } {
+ error "package_id '$package_id' is not valid."
+ }
+ upvar $return_mesg_var return_mesg
+ set return_mesg {}
+
+
+ # Make sure that only 1 copy of this proc per package instance
+ # ever runs at once:
+
+ set mutex [nsv_get . {sp_sync_cr_fs_mutex}]
+ set nsv {sp_sync_cr_fs_times}
+
+ # These multiple nsv operations need to all be atomic, so use a
+ # mutex:
+
+ ns_mutex lock $mutex
+
+ if { ![nsv_array exists $nsv] } {
+ ns_mutex unlock $mutex
+ error "nsv array '$nsv' does not exist!"
+ } elseif { ![nsv_exists $nsv $package_id] } {
+ # The package_id isn't in the array yet at all, so another copy
+ # is not running.
+ set other_start_time {}
+ } else {
+ set other_start_time [nsv_get sp_sync_cr_fs_times $package_id]
+ }
+
+ if { [empty_string_p $other_start_time] } {
+ # We're ok, no other copy is running.
+ nsv_set $nsv $package_id [ns_time]
+ set run_p 1
+ } else {
+ set run_p 0
+ }
+
+ ns_mutex unlock $mutex
+ ns_log Notice "atp: $proc_name: other_start_time: '$other_start_time'"
+
+ if { ! $run_p } {
+ # Another copy is running, must abort:
+ set time_diff [expr [ns_time] - $other_start_time]
+
+ set other_time_pretty [ns_httptime $other_start_time]
+ # Could also use: [clock format [clock seconds]]
+
+ set mesg "sp_sync_cr_with_filesystem: Already running. sp_sync_cr_fs_times($package_id) == $other_time_pretty, $time_diff seconds ago."
+ ns_log Warning $mesg
+
+ set return_mesg "Another copy of this procedure is already running for
+ this package instance. It started running $time_diff seconds
+ ago, at $other_time_pretty. Only one copy may run at a time.
+ Please wait and then try again."
+
+ # Whether you actually see this happen depends whether the
+ # second thread running this proc gets scheduled or not before
+ # the first one completes. If your machine is slow enough, or
+ # you have enough threads going at once, you will see it.
+ # --atp@piskorski.com, 2002/12/16 03:57 EST
+
+ return 0
+ }
+
+
set sync_session_id [db_nextval sp_session_id_seq]
set fs_trimmed [string trimright $fs_root "/"]
set fs_trimmed_length [string length $fs_trimmed]
- set static_page_regexp "\\.[join [split [string trim [ad_parameter -package_id [nsv_get static_pages package_id] AllowedExtensions]] " "] "$|\\."]$"
+ set static_page_regexp "\\.[join [split [string trim [ad_parameter -package_id $package_id AllowedExtensions]] " "] "$|\\."]$"
+ # TODO: What happens if at some point, an Admin CHANGES the
+ # fs_root parameter for a Static Pages package instance? BAD
+ # THINGS, I suspect. We're probably invisibly orphaning content
+ # inside the Content Repository. Look into this. For now, simply
+ # DO NOT change the fs_root of an already in use Static Pages
+ # package instance.
+ # --atp@piskorski.com, 2002/09/15 10:03 EDT
+
foreach file [ad_find_all_files $fs_root] {
if { [regexp -nocase $static_page_regexp $file match] } {
# Chop the starting path off of the full pathname and split it up:
@@ -82,18 +329,19 @@
if { $folder_id == 0} {
set folder_id [db_exec_plsql create_new_folder {}]
if { [string length $folder_add_proc] > 0 } {
- uplevel "$folder_add_proc $cumulative_path $folder_id"
+ uplevel $stack_depth "$folder_add_proc $cumulative_path $folder_id"
}
} else {
if { [string length $folder_unchanged_proc] > 0 } {
- uplevel "$folder_unchanged_proc $cumulative_path $folder_id"
+ uplevel $stack_depth "$folder_unchanged_proc $cumulative_path $folder_id"
}
}
set path_exists($cumulative_path) $folder_id
db_dml insert_path {
insert into sp_extant_folders (session_id,folder_id)
values (:sync_session_id,:folder_id)
}
+
} else {
set folder_id $path_exists($cumulative_path)
}
@@ -111,17 +359,30 @@
# install dir, this is what gets inserted into the db - DaveB
set sp_filename [sp_get_relative_file_path $file]
set mtime_from_fs [file mtime $file]
+
if [db_0or1row check_db_for_page {
select static_page_id, mtime as mtime_from_db from static_pages
where filename = :sp_filename
}] {
+
if { [catch {
set fp [open $file r]
set file_from_fs [read $fp]
close $fp
} errmsg]} {
- ad_return_error "Error reading file" \
- "This error was encountered while reading $file: $errmsg"
+ # Log and return an appropriate message, then
+ # continue on trying to process the other files.
+ # We do NOT want to abort the whole scan just
+ # because one file had problems:
+ # --atp@piskorski.com, 2002/09/12 16:49 EDT
+
+ set mesg "$proc_name: Error reading file: '$file': [ns_quotehtml $errmsg]"
+ ns_log Error $mesg
+ if { ![empty_string_p $file_read_error_proc] } {
+ ns_log Notice "$proc_name: about to run file_read_error_proc:"
+ uplevel $stack_depth [list $file_read_error_proc $file $static_page_id $mesg]
+ }
+ continue
}
set file_updated 0
@@ -160,28 +421,42 @@
}
}
if { [string length $file_change_proc] > 0 } {
- uplevel "$file_change_proc $file $static_page_id"
+ uplevel $stack_depth "$file_change_proc $file $static_page_id"
}
} else {
if { [string length $file_unchanged_proc] > 0 } {
- uplevel "$file_unchanged_proc $file $static_page_id"
+ uplevel $stack_depth "$file_unchanged_proc $file $static_page_id"
}
}
db_dml insert_file {
insert into sp_extant_files (session_id,static_page_id)
values (:sync_session_id,:static_page_id)
}
} else {
+ # The file is NOT in the db yet at all:
+
# Try to extract a title:
if { [catch {
set fp [open $file r]
set file_contents [read $fp]
close $fp
} errmsg]} {
- ad_return_error "Error reading file" \
- "This error was encountered while reading $file: $errmsg"
+ # Log and return an appropriate message, then
+ # continue on trying to process the other files.
+ # We do NOT want to abort the whole scan just
+ # because one file had problems:
+ # --atp@piskorski.com, 2002/09/12 16:49 EDT
+
+ set mesg "$proc_name: Error reading file: '$file': [ns_quotehtml $errmsg]"
+ ns_log Error $mesg
+ if { ![empty_string_p $file_read_error_proc] } {
+ ns_log Notice "$proc_name: about to run file_read_error_proc:"
+ uplevel $stack_depth [list $file_read_error_proc $file $static_page_id $mesg]
+ }
+ continue
}
+ # TODO: This is very HTML specific: --atp@piskorski.com, 2001/08/13 21:58 EDT
if { ![regexp -nocase {
(.+?) :sp_filename,
- title => :page_title,
- folder_id => :parent_folder_id
- );
- end;
- }]
+
+ # If you run two copies of sp_sync_cr_with_filesystem
+ # at once, you CAN get "ORA-00001: unique constraint
+ # (CR_ITEMS_UNIQUE_NAME) violated" errors here when
+ # calling static_page.new - thus the addition of mutex
+ # locking. --atp@piskorski.com, 2001/08/27 01:20 EDT
+
+ set mime_type [sp_maybe_create_new_mime_type $sp_filename]
+ set static_page_id [db_exec_plsql do_sp_new {}]
# Check if -blobs [list $file_contents] would be faster:
- db_dml insert_file_contents {
- update cr_revisions set content = empty_blob()
- where revision_id = content_item.get_live_revision(:static_page_id)
- returning content into :1
- } -blob_files [list $file]
+ db_dml insert_file_contents {} -blob_files [list $file]
+
if { [string length $file_add_proc] > 0 } {
- uplevel "$file_add_proc $file $static_page_id"
+ uplevel $stack_depth "$file_add_proc $file $static_page_id"
}
db_dml insert_file {
insert into sp_extant_files (session_id,static_page_id)
@@ -219,8 +491,22 @@
}
}
+ # TODO: This is very wrong. Should NEVER just delete all content!
+ # Note that the canonical content of the file itself lives in the
+ # fileystem and can easily be re-imported to the database, but
+ # this ALSO blindly deletes all user-contributed comments which
+ # point to the file!
+ #
+ # See also: http://openacs.org/bboard/q-and-a-fetch-msg.tcl?msg_id=0002U2
+ #
+ # --atp@piskorski.com, 2001/08/13 15:07 EDT
+
# Clean up any files that are in the db but no longer in the filesystem:
- set package_id [ad_conn package_id]
+
+ # TODO: Why are we doing these two deletes after calling
+ # static_page.delete_stale_items?
+ # --atp@piskorski.com, 2001/08/23 02:20 EDT
+
db_exec_plsql delete_old_files {
begin
static_page.delete_stale_items(:sync_session_id,:package_id);
@@ -229,8 +515,18 @@
delete from sp_extant_files where session_id = :sync_session_id;
end;
}
+
+ # TODO: We should have a sp_deleted_item hook just like we do for
+ # new, old, and changd items. As it is now, we delete the file
+ # out of the database but provide NO notification that we did so.
+ # --atp@piskorski.com, 2002/12/12 12:43 EST
+
+ sp_sync_cr_with_filesystem_unlock $package_id
+ set return_mesg "Done."
+ return 0
}
+
ad_proc -public sp_root_folder_id { package_id } {
Returns the id of the root folder associated with package_id,
creating one if necessary.
@@ -357,14 +653,24 @@
ad_proc -private sp_get_page_id { filename } {
- Gets page_id
+ Returns a two item list of the page_id and the static-pages
+ package_id it belongs to.
+
@author Dave Bauer (dave@thedesignexperience.org)
@creation-date 2001-07-30
} {
- return [list [db_string search_page "
- select static_page_id from static_pages sp, sp_folders spf
- where filename='$filename' and sp.folder_id=spf.folder_id
- and package_id=[apm_package_id_from_key "static-pages"]" -default -1]]
+ # This package is no longer a singleton, so can't use
+ # apm_package_id_from_key here: --atp@piskorski.com, 2001/08/26
+ # 22:37 EDT
+
+ set package_key [sp_package_key_is]
+ if { [db_0or1row page_and_package_ids {}] } {
+ set results [list $static_page_id $package_id]
+ } else {
+ set results [list -1 -1]
+ }
+
+ return $results
}
ad_proc -public sp_flush_page { page_id } {
@@ -377,6 +683,116 @@
util_memoize_flush [list sp_get_page_info_query $page_id]
}
+
+ad_proc sp_maybe_create_new_mime_type {
+ file_name
+} {
+ This proc should be identical to fs_maybe_create_new_mime_type
+ from the file-storage package. However, we don't want to depend
+ on file-storage being loaded, so if it isn't, define our own
+ implementation here. --atp@piskorski.com, 2002/12/15 19:34 EST
+
+
+ The content repository expects the MIME type to already be defined
+ when you upload content. We use this procedure to add a new type
+ when we encounter something we haven't seen before.
+
+ @author Andrew Piskorski (atp@piskorski.com)
+ @creation-date 2002-12-15
+} {
+ set func {fs_maybe_create_new_mime_type}
+
+ if { [nsv_exists api_proc_doc $func] ||
+ ![empty_string_p [namespace eval :: [list info procs $func]]]
+ } {
+ # The file-storage version of this proc exists, use it:
+ return [list $func $file_name]
+
+ } else {
+ # Fall back to local implementation:
+
+ set file_extension [string trimleft [file extension $file_name] "."]
+ if {[empty_string_p $file_extension]} {
+ return "*/*"
+ }
+
+ # TODO: This insert may fail due to a race condition. Should be
+ # locking the cr_mime_types table first:
+ # --atp@piskorski.com, 2001/08/23 20:20 EDT
+
+ if {![db_0or1row select_mime_type {
+ select mime_type
+ from cr_mime_types
+ where file_extension = :file_extension
+ }]} {
+ # A mime type for this file extension does not exist
+ # in the database. Check to see AOLServer can
+ # generate a mime type.
+
+ set mime_type [ns_guesstype $file_name]
+
+ # Note: If AOLServer can't determine a mime type,
+ # ns_guesstype will return */*. We still record
+ # a mime type for this file extension. At a later
+ # date, the mime type for the file extension may be
+ # updated and, as a result, the files with that
+ # file extension will be associated with the
+ # proper mime types.
+
+ db_dml new_mime_type {
+ insert into cr_mime_types
+ (mime_type, file_extension)
+ values
+ (:mime_type, :file_extension)
+ }
+ }
+ return $mime_type
+ }
+}
+
+
+ad_proc -public sp_package_key_is {} {
+ Simply returns the package key string for this package.
+ @author Andrew Piskorski (atp@piskorski.com)
+ @creation-date 2001/08/26
+} {
+ # TODO: Might want to have this pull and cache the actual key from
+ # the database.
+ return {static-pages}
+}
+
+
+ad_proc -private sp_package_url {package_key} {
+
Given a package key, return a URL of a mounted
+ package instance. If there is more than one instance
+ of the package mounted, the one with the lowest
+ package_id
will be returned. If the
+ package is not instantiated or not mounted anywhere,
+ an error is raised. The proc is meant to be memoized.
+
+} {
+ set proc_name {sp_package_url}
+
+ set found_p [db_0or1row get_any_package_instance {
+ select min(package_id) as package_id
+ from apm_packages
+ where package_key = :package_key
+ }]
+
+ if { !$found_p } {
+ error "$proc_name: the '$package_key' package is not instantiated."
+ }
+
+ set found_p [db_0or1row get_mount_point {}]
+
+ if { !$found_p } {
+ error "$proc_name: the '$package_key' package is not mounted."
+ }
+
+ return $url
+}
+
+
ad_proc -public sp_serve_html_page { } {
Registered proc to serve up static pages.
@@ -385,18 +801,26 @@
} {
set filename [ad_conn file]
set sp_filename [sp_get_relative_file_path $filename]
-
- set page_id [util_memoize [list sp_get_page_id $sp_filename]]
- set package_id [nsv_get static_pages package_id]
+ # In order to determine per-instance parameters like
+ # TemplatingEnabledP, need to know the package_id of the
+ # static-pages instance where this page is located, which is
+ # likely NOT the package_id returned by [ad_conn package_id]:
+ foreach [list page_id package_id] \
+ [util_memoize [list sp_get_page_id $sp_filename]] { break }
+
set file [ad_conn file]
ad_conn -set subsite_id [site_node_closest_ancestor_package "acs-subsite"]
# If the page is in the db, serve it carefully; otherwise just dump it out.
if { $page_id >= 0 } {
set page_info [util_memoize [list sp_get_page_info_query $page_id]]
+ # TODO: Below, what if we only allow registered users to make
+ # comments? Or some smaller group of users? What then?
+ # --atp@piskorski.com, 2001/08/22 23:09 EDT
+
# We only show the link here if the_public has
# general_comments_create privilege on the page. Why the_public
# rather than the current user? Because we don't want admins to
@@ -431,7 +855,8 @@
set body [template::util::read_file $file]
}
- if { [ad_parameter -package_id $package_id TemplatingEnabledP] } {
+ set templating_enabled [ad_parameter -package_id $package_id TemplatingEnabledP]
+ if { ![empty_string_p $templating_enabled] && $templating_enabled } {
# Strip out the .. part as page will now be part of a master template
set headers ""
set sp_scripts ""
@@ -454,13 +879,47 @@
}
}
+
ad_proc -private sp_register_extension {} {
Register the handler for each static page file extension.
} {
- foreach extension [split [string tolower [string trim [ad_parameter -package_id [apm_package_id_from_key static-pages] AllowedExtensions]]] " "] {
- rp_register_extension_handler $extension sp_serve_html_page
- rp_register_extension_handler [string toupper $extension] sp_serve_html_page
+ set proc_name {sp_register_extension}
+
+ set package_key [sp_package_key_is]
+ set package_ids [db_list all_static_pages_package_instances {
+ select package_id
+ from apm_packages
+ where package_key = :package_key
+ }]
+
+ # Generate unique list of all file-name extensions used by all
+ # package instances:
+
+ array set extensions_arr [list]
+ foreach package_id $package_ids {
+ foreach extension [split [string tolower [string trim [ad_parameter -package_id $package_id AllowedExtensions]]] " "] {
+ set extensions_arr($extension) {}
+ }
}
+
+ foreach extension [array names extensions_arr] {
+ # TODO: Are we supposed to use the sp_serve_html_page proc for
+ # ALL file-name extensions, even if they're PDF or MS Word
+ # documents? I think not! Need a better way to map file-name
+ # extensions to proper static-pages extension handler procs.
+ # --atp@piskorski.com, 2002/12/11 22:55 EST
+
+ if { [regexp {htm} $extension] } {
+ set handler_proc {sp_serve_html_page}
+ rp_register_extension_handler $extension $handler_proc
+ rp_register_extension_handler [string toupper $extension] $handler_proc
+ } else {
+ ns_log Notice "$proc_name: NOT registering any proc to handle files with extension '$extension'."
+
+ # TODO: Add a PDF or other extension handler? Necessary
+ # only if you want to be able to make comments on non-HTML
+ # files, I think.
+ # --atp@piskorski.com, 2002/12/11 22:55 EST
+ }
+ }
}
-# Register the handler for each static page file extension.
-sp_register_extension
Index: openacs-4/packages/static-pages/tcl/static-pages-procs.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/tcl/static-pages-procs.xql,v
diff -u -r1.7 -r1.8
--- openacs-4/packages/static-pages/tcl/static-pages-procs.xql 3 Dec 2001 16:58:46 -0000 1.7
+++ openacs-4/packages/static-pages/tcl/static-pages-procs.xql 16 Jan 2003 14:01:59 -0000 1.8
@@ -1,7 +1,7 @@
-
+
insert into sp_extant_folders (session_id,folder_id)
@@ -10,15 +10,15 @@
-
+
select storage_type from cr_items
where item_id = :static_page_id
-
+
insert into sp_extant_files (session_id,static_page_id)
@@ -28,7 +28,7 @@
-
+
insert into sp_extant_files (session_id,static_page_id)
Index: openacs-4/packages/static-pages/www/page-visit.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/page-visit.tcl,v
diff -u -r1.4 -r1.5
--- openacs-4/packages/static-pages/www/page-visit.tcl 18 Sep 2002 12:03:33 -0000 1.4
+++ openacs-4/packages/static-pages/www/page-visit.tcl 16 Jan 2003 14:02:32 -0000 1.5
@@ -19,11 +19,27 @@
# characters will then be stripped off to produce the URL.
# DaveB: not anymore! We chop off that part and just stuff the relative
# path in the database to allow leaving the static-pages in the filesystem
-#
-#if { [string first "[acs_root_dir]/www" $filename] != 0 } {
-# ad_return_error "Error in filename" "This page has an invalid filename."
-#}
-ad_returnredirect $filename
+# There are two possiblities: Either the static page is beneath the
+# site global www/ directory (and the filename starts "/www/"), or it
+# is beneath one of the package www directories (and the filename
+# starts "/packages/":
+if { [string first "/www/" $filename] == 0 } {
+ set redirect_to "/[string range $filename [string length "/www/"] end]"
+} elseif { [regexp "^/packages/(\[^/\]+)" $filename match package_dir] } {
+ # TODO: We are assuming that the package directory name $package_dir
+ # is in fact always the package key. Is this really true?
+
+ if { ![regexp "^/packages/$package_dir/www/(.+)" $filename match url_part] } {
+ ad_return_error "Error in filename" "This page has an invalid filename: '$filename'."
+ }
+ set redirect_to "[sp_package_url $package_dir]$url_part"
+
+} else {
+ ad_return_error "Error in filename" "This page has an invalid filename: '$filename'."
+ return
+}
+
+ad_returnredirect $redirect_to
Index: openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl,v
diff -u -r1.2 -r1.3
--- openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl 6 Sep 2002 12:30:13 -0000 1.2
+++ openacs-4/packages/static-pages/www/admin/fs-scan-progress.tcl 16 Jan 2003 14:03:04 -0000 1.3
@@ -18,20 +18,23 @@
# sp_sync_cr_with_filesystem callbacks to fill file_items with info.
#
proc sp_old_item { path id } {
- upvar file_items file_items
- ns_write "
$path
: unchanged"
+ ns_write "\n
$path
: unchanged"
}
proc sp_new_item { path id } {
- upvar file_items file_items
- ns_write "
$path
: added"
+ ns_write "\n
$path
: added"
}
proc sp_changed_item { path id } {
- upvar file_items file_items
- ns_write "
$path
: updated"
+ ns_write "\n
$path
: updated"
# The title may have changed:
sp_flush_page $id
}
+proc sp_error_item { path id msg } {
+ ns_write "\n
+
$path
: Error:
+$msg
"
+}
+
set title "Filesystem search"
set context_bar [ad_context_bar $title]
@@ -41,18 +44,23 @@
$title
$context_bar
-Starting scan
"
-set root_folder_id [sp_root_folder_id [ad_conn package_id]]
+set package_id [ad_conn package_id]
+set root_folder_id [sp_root_folder_id $package_id]
+set fs_root "[acs_root_dir][ad_parameter -package_id $package_id {fs_root}]"
-sp_sync_cr_with_filesystem \
+ns_write "
+
+[sp_sync_cr_with_filesystem \
-file_unchanged_proc sp_old_item \
-file_add_proc sp_new_item \
-file_change_proc sp_changed_item \
+ -file_read_error_proc sp_error_item \
-folder_add_proc sp_new_item \
-folder_unchanged_proc sp_old_item \
- "[acs_root_dir]/www" $root_folder_id
+ $fs_root $root_folder_id]
+
+"
-
-ns_write "
Finished updating static pages