-- Data model to support content repository of the ArsDigita Community
-- System
-- Copyright (C) 1999-2000 ArsDigita Corporation
-- Author: Karl Goldstein (karlg@arsdigita.com)
-- $Id: content-folder.sql,v 1.53.2.3 2020/03/14 17:17:16 gustafn Exp $
-- This is free software distributed under the terms of the GNU Public
-- License. Full text of the license is available from the GNU Project:
-- http://www.fsf.org/copyleft/gpl.html
-- create or replace package body content_folder
--
-- procedure content_folder__new/5
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer, -- default null
new__package_id integer -- default null
) RETURNS integer AS $$
--
-- content_folder__new/5 maybe obsolete, when we define proper defaults for /11
--
DECLARE
BEGIN
return content_folder__new(new__name,
new__label,
new__description,
new__parent_id,
null,
null,
now(),
null,
null,
new__package_id
);
END;
$$ LANGUAGE plpgsql;
--
-- procedure content_folder__new/4
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer -- default null
) RETURNS integer AS $$
--
-- content_folder__new/4 maybe obsolete, when we define proper defaults for /11
--
DECLARE
BEGIN
return content_folder__new(new__name,
new__label,
new__description,
new__parent_id,
null,
null,
now(),
null,
null,
't',
null
);
END;
$$ LANGUAGE plpgsql;
-- function new
--
-- procedure content_folder__new/9
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer, -- default null
new__context_id integer, -- default null
new__folder_id integer, -- default null
new__creation_date timestamptz, -- default now()
new__creation_user integer, -- default null
new__creation_ip varchar -- default null
) RETURNS integer AS $$
--
-- content_folder__new/9 maybe obsolete, when we define proper defaults for /11
--
DECLARE
BEGIN
return content_folder__new(new__name,
new__label,
new__description,
new__parent_id,
new__context_id,
new__folder_id,
new__creation_date,
new__creation_user,
new__creation_ip,
't',
null::integer
);
END;
$$ LANGUAGE plpgsql;
-- function new
--
-- procedure content_folder__new/10
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer, -- default null
new__context_id integer, -- default null
new__folder_id integer, -- default null
new__creation_date timestamptz, -- default now()
new__creation_user integer, -- default null
new__creation_ip varchar, -- default null
new__package_id integer -- default null
) RETURNS integer AS $$
--
-- content_folder__new/10 maybe obsolete, when we define proper defaults for /11
--
DECLARE
v_folder_id cr_folders.folder_id%TYPE;
v_context_id acs_objects.context_id%TYPE;
v_package_id acs_objects.package_id%TYPE;
BEGIN
return content_folder__new(new__name,
new__label,
new__description,
new__parent_id,
new__context_id,
new__folder_id,
new__creation_date,
new__creation_user,
new__creation_ip,
't',
new__package_id
);
END;
$$ LANGUAGE plpgsql;
--
-- procedure content_folder__new/10
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer, -- default null
new__context_id integer, -- default null
new__folder_id integer, -- default null
new__creation_date timestamptz, -- default now()
new__creation_user integer, -- default null
new__creation_ip varchar, -- default null
new__security_inherit_p boolean -- default true
) RETURNS integer AS $$
--
-- content_folder__new/10 maybe obsolete, when we define proper defaults for /11
--
DECLARE
v_package_id acs_objects.package_id%TYPE;
v_folder_id cr_folders.folder_id%TYPE;
v_context_id acs_objects.context_id%TYPE;
BEGIN
return content_folder__new (
new__name,
new__label,
new__description,
new__parent_id,
new__context_id,
new__folder_id,
new__creation_date,
new__creation_user,
new__creation_ip,
new__security_inherit_p,
null
);
END;
$$ LANGUAGE plpgsql;
-- function new -- accepts security_inherit_p DaveB
-- old define_function_args('content_folder__new','name,label,description,parent_id,context_id,folder_id,creation_date;now,creation_user,creation_ip,security_inherit_p;t,package_id')
-- new
select define_function_args('content_folder__new','name,label,description;null,parent_id;null,context_id;null,folder_id;null,creation_date;now,creation_user;null,creation_ip;null,security_inherit_p;t,package_id;null');
--
-- procedure content_folder__new/11
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer, -- default null
new__context_id integer, -- default null
new__folder_id integer, -- default null
new__creation_date timestamptz, -- default now() -- default 'now'
new__creation_user integer, -- default null
new__creation_ip varchar, -- default null
new__security_inherit_p boolean, -- default true -- default 't'
new__package_id integer -- default null
) RETURNS integer AS $$
DECLARE
v_folder_id cr_folders.folder_id%TYPE;
v_context_id acs_objects.context_id%TYPE;
BEGIN
-- set the context_id
if new__context_id is null then
v_context_id := new__parent_id;
else
v_context_id := new__context_id;
end if;
-- parent_id = security_context_root means that this is a mount point
if new__parent_id != -4 and
content_folder__is_folder(new__parent_id) and
content_folder__is_registered(new__parent_id,'content_folder','f') = 'f' then
raise EXCEPTION '-20000: This folder does not allow subfolders to be created';
return null;
else
v_folder_id := content_item__new(
new__folder_id,
new__name,
new__parent_id,
null,
new__creation_date,
new__creation_user,
new__context_id,
new__creation_ip,
'f',
'text/plain',
null,
'text',
new__security_inherit_p,
'CR_FILES',
'content_folder',
'content_folder',
new__package_id
);
insert into cr_folders (
folder_id, label, description, package_id
) values (
v_folder_id, new__label, new__description, new__package_id
);
-- set the correct object title
update acs_objects
set title = new__label
where object_id = v_folder_id;
-- inherit the attributes of the parent folder
if new__parent_id is not null then
insert into cr_folder_type_map
select
v_folder_id as folder_id, content_type
from
cr_folder_type_map
where
folder_id = new__parent_id;
end if;
-- update the child flag on the parent
update cr_folders set has_child_folders = 't'
where folder_id = new__parent_id;
return v_folder_id;
end if;
return v_folder_id;
END;
$$ LANGUAGE plpgsql;
--
-- procedure content_folder__new/10
--
CREATE OR REPLACE FUNCTION content_folder__new(
new__name varchar,
new__label varchar,
new__description varchar, -- default null
new__parent_id integer, -- default null
new__context_id integer, -- default null
new__folder_id integer, -- default null
new__creation_date timestamptz, -- default now()
new__creation_user integer, -- default null
new__creation_ip varchar, -- default null
new__security_inherit_p boolean -- default true
) RETURNS integer AS $$
--
-- content_folder__new/10 maybe obsolete, when we define proper defaults for /11
--
DECLARE
BEGIN
return content_folder__new(new__name,
new__label,
new__description,
new__parent_id,
new__context_id,
new__folder_id,
new__creation_date,
new__creation_user,
new__creation_ip,
new__security_inherit_p,
null::integer
);
END;
$$ LANGUAGE plpgsql;
-- procedure delete
select define_function_args('content_folder__del','folder_id,cascade_p;f');
--
-- procedure content_folder__del/2
--
CREATE OR REPLACE FUNCTION content_folder__del(
delete__folder_id integer,
p_cascade_p boolean -- default 'f'
) RETURNS integer AS $$
DECLARE
v_count integer;
v_child_row record;
v_parent_id integer;
v_path varchar;
v_folder_sortkey varbit;
BEGIN
if p_cascade_p = 'f' then
select count(*) into v_count from cr_items
where parent_id = delete__folder_id;
-- check if the folder contains any items
if v_count > 0 then
v_path := content_item__get_path(delete__folder_id, null);
raise EXCEPTION '-20000: Folder ID % (%) cannot be deleted because it is not empty.', delete__folder_id, v_path;
end if;
else
-- delete children
select into v_folder_sortkey tree_sortkey
from cr_items where item_id=delete__folder_id;
for v_child_row in select
item_id, tree_sortkey, name
from cr_items
where tree_sortkey between v_folder_sortkey and tree_right(v_folder_sortkey)
and tree_sortkey != v_folder_sortkey
order by tree_sortkey desc
loop
if content_folder__is_folder(v_child_row.item_id) then
perform content_folder__delete(v_child_row.item_id);
else
perform content_item__delete(v_child_row.item_id);
end if;
end loop;
end if;
PERFORM content_folder__unregister_content_type(
delete__folder_id,
'content_revision',
't'
);
delete from cr_folder_type_map
where folder_id = delete__folder_id;
select parent_id into v_parent_id from cr_items
where item_id = delete__folder_id;
raise notice 'deleting folder %',delete__folder_id;
PERFORM content_item__delete(delete__folder_id);
-- check if any folders are left in the parent
update cr_folders set has_child_folders = 'f'
where folder_id = v_parent_id and not exists (
select 1 from cr_items
where parent_id = v_parent_id and content_type = 'content_folder');
return 0;
END;
$$ LANGUAGE plpgsql;
select define_function_args('content_folder__delete','folder_id,cascade_p;f');
--
-- procedure content_folder__delete/2
--
CREATE OR REPLACE FUNCTION content_folder__delete(
delete__folder_id integer,
p_cascade_p boolean -- default 'f'
) RETURNS integer AS $$
DECLARE
BEGIN
PERFORM content_folder__del(delete__folder_id,p_cascade_p);
return 0;
END;
$$ LANGUAGE plpgsql;
--
-- procedure content_folder__delete/1
--
CREATE OR REPLACE FUNCTION content_folder__delete(
delete__folder_id integer
) RETURNS integer AS $$
--
-- content_folder__delete/1 maybe obsolete, when we define proper defaults for /2
--
DECLARE
v_count integer;
v_parent_id integer;
v_path varchar;
BEGIN
return content_folder__del(
delete__folder_id,
'f'
);
END;
$$ LANGUAGE plpgsql;
-- procedure rename
-- old define_function_args('content_folder__edit_name','folder_id,name,label,description')
-- new
select define_function_args('content_folder__edit_name','folder_id,name;null,label;null,description;null');
--
-- procedure content_folder__edit_name/4
--
CREATE OR REPLACE FUNCTION content_folder__edit_name(
edit_name__folder_id integer,
edit_name__name varchar, -- default null
edit_name__label varchar, -- default null
edit_name__description varchar -- default null
) RETURNS integer AS $$
DECLARE
v_name_already_exists_p integer;
BEGIN
if edit_name__name is not null and edit_name__name != '' then
PERFORM content_item__edit_name(edit_name__folder_id, edit_name__name);
end if;
if edit_name__label is not null and edit_name__label != '' then
update acs_objects
set title = edit_name__label
where object_id = edit_name__folder_id;
end if;
if edit_name__label is not null and edit_name__label != '' and
edit_name__description is not null and edit_name__description != '' then
update cr_folders
set label = edit_name__label,
description = edit_name__description
where folder_id = edit_name__folder_id;
else if(edit_name__label is not null and edit_name__label != '') and
(edit_name__description is null or edit_name__description = '') then
update cr_folders
set label = edit_name__label
where folder_id = edit_name__folder_id;
end if; end if;
return 0;
END;
$$ LANGUAGE plpgsql;
-- 1) make sure we are not moving the folder to an invalid location:
-- a. destination folder exists
-- b. folder is not the webroot (folder_id = -1)
-- c. destination folder is not the same as the folder
-- d. destination folder is not a subfolder
-- 2) make sure subfolders are allowed in the target_folder
-- 3) update the parent_id for the folder
-- procedure move
select define_function_args('content_folder__move','folder_id,target_folder_id,name;null');
--
-- procedure content_folder__move/3
--
CREATE OR REPLACE FUNCTION content_folder__move(
move__folder_id integer,
move__target_folder_id integer,
move__name varchar -- default null
) RETURNS integer AS $$
DECLARE
v_source_folder_id integer;
v_valid_folders_p integer;
BEGIN
select
count(*)
into
v_valid_folders_p
from
cr_folders
where
folder_id = move__target_folder_id
or
folder_id = move__folder_id;
if v_valid_folders_p != 2 then
raise EXCEPTION '-20000: content_folder.move - Not valid folder(s)';
end if;
if move__folder_id = content_item__get_root_folder(null) or
move__folder_id = content_template__get_root_folder() then
raise EXCEPTION '-20000: content_folder.move - Cannot move root folder';
end if;
if move__target_folder_id = move__folder_id then
raise EXCEPTION '-20000: content_folder.move - Cannot move a folder to itself';
end if;
if content_folder__is_sub_folder(move__folder_id, move__target_folder_id) = 't' then
raise EXCEPTION '-20000: content_folder.move - Destination folder is subfolder';
end if;
if content_folder__is_registered(move__target_folder_id,'content_folder','f') != 't' then
raise EXCEPTION '-20000: content_folder.move - Destination folder does not allow subfolders';
end if;
select parent_id into v_source_folder_id from cr_items
where item_id = move__folder_id;
-- update the parent_id for the folder
update cr_items
set parent_id = move__target_folder_id,
name = coalesce ( move__name, name )
where item_id = move__folder_id;
-- update the has_child_folders flags
-- update the source
update cr_folders set has_child_folders = 'f'
where folder_id = v_source_folder_id and not exists (
select 1 from cr_items
where parent_id = v_source_folder_id
and content_type = 'content_folder');
-- update the destination
update cr_folders set has_child_folders = 't'
where folder_id = move__target_folder_id;
return 0;
END;
$$ LANGUAGE plpgsql;
--
-- procedure content_folder__move/2
--
CREATE OR REPLACE FUNCTION content_folder__move(
move__folder_id integer,
move__target_folder_id integer
) RETURNS integer AS $$
--
-- content_folder__move/2 maybe obsolete, when we define proper defaults for /3
--
DECLARE
BEGIN
perform content_folder__move (
move__folder_id,
move__target_folder_id,
NULL
);
return null;
END;
$$ LANGUAGE plpgsql;
-- procedure copy
-- added
select define_function_args('content_folder__copy','folder_id,target_folder_id,creation_user,creation_ip;null,name;null,label;null');
--
-- procedure content_folder__copy/6
--
CREATE OR REPLACE FUNCTION content_folder__copy(
copy__folder_id integer,
copy__target_folder_id integer,
copy__creation_user integer,
copy__creation_ip varchar default null,
copy__name cr_items.name%TYPE default null,
copy__label cr_folders.label%TYPE default null
) RETURNS integer AS $$
DECLARE
v_valid_folders_p integer;
v_current_folder_id cr_folders.folder_id%TYPE;
v_name cr_items.name%TYPE;
v_label cr_folders.label%TYPE;
v_description cr_folders.description%TYPE;
v_new_folder_id cr_folders.folder_id%TYPE;
v_folder_contents_val record;
BEGIN
if copy__folder_id = content_item__get_root_folder(null)
or copy__folder_id = content_template__get_root_folder() then
raise EXCEPTION '-20000: content_folder.copy - Not allowed to copy root folder';
end if;
select
count(*)
into
v_valid_folders_p
from
cr_folders
where
folder_id = copy__target_folder_id
or
folder_id = copy__folder_id;
if v_valid_folders_p != 2 then
raise EXCEPTION '-20000: content_folder.copy - Invalid folder(s)';
end if;
if copy__target_folder_id = copy__folder_id then
raise EXCEPTION '-20000: content_folder.copy - Cannot copy folder to itself';
end if;
if content_folder__is_sub_folder(copy__folder_id, copy__target_folder_id) = 't' then
raise EXCEPTION '-20000: content_folder.copy - Destination folder is subfolder';
end if;
if content_folder__is_registered(copy__target_folder_id,'content_folder','f') != 't' then
raise EXCEPTION '-20000: content_folder.copy - Destination folder does not allow subfolders';
end if;
-- get the source folder info
select
name, label, description, parent_id
into
v_name, v_label, v_description, v_current_folder_id
from
cr_items i, cr_folders f
where
f.folder_id = i.item_id
and
f.folder_id = copy__folder_id;
-- would be better to check if the copy__name already exists in the destination folder.
if v_current_folder_id = copy__target_folder_id and (v_name = copy__name or copy__name is null) then
raise EXCEPTION '-20000: content_folder.copy - Destination folder is parent folder and folder already exists';
end if;
-- create the new folder
v_new_folder_id := content_folder__new(
coalesce (copy__name, v_name),
coalesce (copy__label, v_label),
v_description,
copy__target_folder_id,
copy__target_folder_id,
null,
now(),
copy__creation_user,
copy__creation_ip,
't',
null
);
-- copy attributes of original folder
insert into cr_folder_type_map
select
v_new_folder_id as folder_id, content_type
from
cr_folder_type_map map
where
folder_id = copy__folder_id
and
-- do not register content_type if it is already registered
not exists ( select 1 from cr_folder_type_map
where folder_id = v_new_folder_id
and content_type = map.content_type ) ;
-- for each item in the folder, copy it
for v_folder_contents_val in select
item_id
from
cr_items
where
parent_id = copy__folder_id
LOOP
PERFORM content_item__copy(
v_folder_contents_val.item_id,
v_new_folder_id,
copy__creation_user,
copy__creation_ip,
null
);
end loop;
return 0;
END;
$$ LANGUAGE plpgsql;
--
-- procedure content_folder__is_folder/1
--
select define_function_args('content_folder__is_folder','item_id');
CREATE OR REPLACE FUNCTION content_folder__is_folder(
item_id integer
) RETURNS boolean AS $$
SELECT EXISTS (
SELECT 1 from cr_folders where folder_id = item_id
);
$$ LANGUAGE sql stable strict;
--
-- procedure content_folder__is_sub_folder/2
--
select define_function_args('content_folder__is_sub_folder','folder_id,target_folder_id');
CREATE OR REPLACE FUNCTION content_folder__is_sub_folder(
is_sub_folder__folder_id integer,
is_sub_folder__target_folder_id integer
) RETURNS boolean AS $$
WITH RECURSIVE parents AS (
select item_id, parent_id from cr_items where item_id = is_sub_folder__target_folder_id
UNION ALL
select cr_items.item_id, cr_items.parent_id from cr_items, parents
where cr_items.item_id = parents.parent_id
)
SELECT EXISTS (
SELECT 1 FROM parents WHERE parent_id = is_sub_folder__folder_id
);
$$ LANGUAGE sql stable strict;
--
-- procedure content_folder__is_empty/1
--
select define_function_args('content_folder__is_empty','folder_id');
CREATE OR REPLACE FUNCTION content_folder__is_empty(
is_empty__folder_id integer
) RETURNS boolean AS $$
SELECT NOT EXISTS (
SELECT 1 from cr_items where parent_id = is_empty__folder_id
);
$$ LANGUAGE sql stable strict;
-- procedure register_content_type
select define_function_args('content_folder__register_content_type','folder_id,content_type,include_subtypes;f');
--
-- procedure content_folder__register_content_type/3
--
CREATE OR REPLACE FUNCTION content_folder__register_content_type(
register_content_type__folder_id integer,
register_content_type__content_type varchar,
register_content_type__include_subtypes boolean -- default 'f'
) RETURNS integer AS $$
DECLARE
v_is_registered boolean;
BEGIN
if register_content_type__include_subtypes = 'f' then
v_is_registered := content_folder__is_registered(
register_content_type__folder_id,
register_content_type__content_type,
'f'
);
if v_is_registered = 'f' then
insert into cr_folder_type_map (
folder_id, content_type
) values (
register_content_type__folder_id,
register_content_type__content_type
);
end if;
else
-- insert into cr_folder_type_map
-- select
-- register_content_type__folder_id as folder_id,
-- object_type as content_type
-- from
-- acs_object_types
-- where
-- object_type <> 'acs_object'
-- and
-- not exists (select 1 from cr_folder_type_map
-- where folder_id = register_content_type__folder_id
-- and content_type = acs_object_types.object_type)
-- connect by
-- prior object_type = supertype
-- start with
-- object_type = register_content_type__content_type;
insert into cr_folder_type_map
select register_content_type__folder_id as folder_id,
o.object_type as content_type
from acs_object_types o, acs_object_types o2
where o.object_type <> 'acs_object'
and not exists (select 1
from cr_folder_type_map
where folder_id = register_content_type__folder_id
and content_type = o.object_type)
and o2.object_type = register_content_type__content_type
and o.tree_sortkey between o2.tree_sortkey and tree_right(o2.tree_sortkey);
end if;
return 0;
END;
$$ LANGUAGE plpgsql;
-- procedure unregister_content_type
select define_function_args('content_folder__unregister_content_type','folder_id,content_type,include_subtypes;f');
--
-- procedure content_folder__unregister_content_type/3
--
CREATE OR REPLACE FUNCTION content_folder__unregister_content_type(
unregister_content_type__folder_id integer,
unregister_content_type__content_type varchar,
unregister_content_type__include_subtypes boolean -- default 'f'
) RETURNS integer AS $$
DECLARE
BEGIN
if unregister_content_type__include_subtypes = 'f' then
delete from cr_folder_type_map
where folder_id = unregister_content_type__folder_id
and content_type = unregister_content_type__content_type;
else
-- delete from cr_folder_type_map
-- where folder_id = unregister_content_type__folder_id
-- and content_type in (select object_type
-- from acs_object_types
-- where object_type <> 'acs_object'
-- connect by prior object_type = supertype
-- start with
-- object_type = unregister_content_type__content_type);
delete from cr_folder_type_map
where folder_id = unregister_content_type__folder_id
and content_type in (select o.object_type
from acs_object_types o, acs_object_types o2
where o.object_type <> 'acs_object'
and o2.object_type = unregister_content_type__content_type
and o.tree_sortkey between o2.tree_sortkey and tree_right(o2.tree_sortkey));
end if;
return 0;
END;
$$ LANGUAGE plpgsql;
-- function is_registered
select define_function_args('content_folder__is_registered','folder_id,content_type,include_subtypes;f');
--
-- procedure content_folder__is_registered/3
--
CREATE OR REPLACE FUNCTION content_folder__is_registered(
is_registered__folder_id integer,
is_registered__content_type varchar,
is_registered__include_subtypes boolean -- default 'f'
) RETURNS boolean AS $$
DECLARE
v_is_registered integer;
v_subtype_val record;
BEGIN
if is_registered__include_subtypes = 'f' or is_registered__include_subtypes is null then
select
count(1)
into
v_is_registered
from
cr_folder_type_map
where
folder_id = is_registered__folder_id
and
content_type = is_registered__content_type;
else
-- select
-- object_type
-- from
-- acs_object_types
-- where
-- object_type <> 'acs_object'
-- connect by
-- prior object_type = supertype
-- start with
-- object_type = is_registered.content_type
v_is_registered := 1;
for v_subtype_val in select o.object_type
from acs_object_types o, acs_object_types o2
where o.object_type <> 'acs_object'
and o2.object_type = is_registered__content_type
and o.tree_sortkey between o2.tree_sortkey and tree_right(o2.tree_sortkey)
order by o.tree_sortkey
LOOP
if content_folder__is_registered(is_registered__folder_id,
v_subtype_val.object_type, 'f') = 'f' then
v_is_registered := 0;
end if;
end loop;
end if;
if v_is_registered = 0 then
return 'f';
else
return 't';
end if;
END;
$$ LANGUAGE plpgsql stable;
-- function get_label
select define_function_args('content_folder__get_label','folder_id');
--
-- procedure content_folder__get_label/1
--
CREATE OR REPLACE FUNCTION content_folder__get_label(
get_label__folder_id integer
) RETURNS varchar AS $$
DECLARE
v_label cr_folders.label%TYPE;
BEGIN
select
label into v_label
from
cr_folders
where
folder_id = get_label__folder_id;
return v_label;
END;
$$ LANGUAGE plpgsql stable strict;
-- function get_index_page
select define_function_args('content_folder__get_index_page','folder_id');
--
-- procedure content_folder__get_index_page/1
--
CREATE OR REPLACE FUNCTION content_folder__get_index_page(
get_index_page__folder_id integer
) RETURNS integer AS $$
DECLARE
v_folder_id cr_folders.folder_id%TYPE;
v_index_page_id cr_items.item_id%TYPE;
BEGIN
-- if the folder is a symlink, resolve it
if content_symlink__is_symlink(get_index_page__folder_id) = 't' then
v_folder_id := content_symlink__resolve(get_index_page__folder_id);
else
v_folder_id := get_index_page__folder_id;
end if;
select
item_id into v_index_page_id
from
cr_items
where
parent_id = v_folder_id
and
name = 'index'
and
content_item__is_subclass(
content_item__get_content_type(content_symlink__resolve(item_id)),
'content_folder') = 'f'
and
content_item__is_subclass(
content_item__get_content_type(content_symlink__resolve(item_id)),
'content_template') = 'f';
if NOT FOUND then
return null;
end if;
return v_index_page_id;
END;
$$ LANGUAGE plpgsql stable strict;
-- function is_root
select define_function_args('content_folder__is_root','folder_id');
--
-- procedure content_folder__is_root/1
--
CREATE OR REPLACE FUNCTION content_folder__is_root(
is_root__folder_id integer
) RETURNS boolean AS $$
DECLARE
v_is_root boolean;
BEGIN
select parent_id = -4 into v_is_root
from cr_items where item_id = is_root__folder_id;
return v_is_root;
END;
$$ LANGUAGE plpgsql;
-- show errors