Index: openacs-4/packages/ams/ams.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/ams.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/ams.info 20 Oct 2004 21:40:01 -0000 1.1 @@ -0,0 +1,31 @@ + + + + + Attribute Management System + Attributes Management System + f + t + ams + + + Matthew Geddert + Store attributes via the Content Repository, and auto generate input forms + AMS (Attribute Management System) uses the content repository to store attribute history for any object on the system. It has an admin interface that lets applications dynamically add fields to their forms. + + + + + + + + + + + + + + + + + Index: openacs-4/packages/ams/sql/postgresql/ams-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/sql/postgresql/ams-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/sql/postgresql/ams-create.sql 20 Oct 2004 21:40:04 -0000 1.1 @@ -0,0 +1,406 @@ +-- +-- packages/ams/sql/postgresql/ams-create.sql +-- +-- @author Matthew Geddert openacs@geddert.com +-- @creation-date 2004-09-07 +-- @cvs-id $Id: ams-create.sql,v 1.1 2004/10/20 21:40:04 matthewg Exp $ +-- +-- + + +------ Widgets +-------------------------------------------------------------------- + +create table ams_storage_types ( + storage_type varchar(20) + constraint ams_storage_type_nn not null + constraint ams_storage_type_pk primary key +); + +create table ams_widgets ( + widget_name varchar(100) + constraint ams_widgets_name_pk primary key, + pretty_name varchar(100) + constraint ams_widgets_pretty_name_nn not null, + pretty_plural varchar(100) + constraint ams_widgets_pretty_plural_nn not null, + storage_type varchar(20) + constraint ams_widgets_storage_type_nn not null + constraint contact_widgets_storage_type_fk references ams_storage_types(storage_type), + acs_datatype varchar(50) + constraint ams_widgets_acs_datatype_nn not null + constraint ams_widgets_acs_datatype_fk references acs_datatypes(datatype), + widget varchar(20) + constraint ams_widgets_widget_nn not null, + datatype varchar(20) + constraint ams_widgets_datatype_nn not null, + parameters varchar(1000) +); + + + +------ Attributes +-------------------------------------------------------------------- + +create table ams_attributes ( + ams_attribute_id integer + constraint ams_attributes_ams_attribute_id_fk references acs_objects(object_id) + constraint ams_attributes_ams_attribute_id_pk primary key, + attribute_id integer + constraint ams_attributes_attribute_id_fk references acs_attributes(attribute_id) + constraint ams_attributes_attribute_id_nn not null, + widget_name varchar(100) + constraint ams_attributes_widget_name_fk references ams_widgets(widget_name) + constraint ams_attributes_widget_name_nn not null, + deprecated_p boolean default 'f' + constraint ams_attributes_deprecated_nn not null +); + +select acs_object_type__create_type ( + 'ams_attribute', -- object_type + 'AMS Attribute', -- pretty_name + 'AMS Attributes ', -- pretty_plural + 'acs_object', -- supertype + 'ams_attributes', -- table_name + 'ams_attribute_id', -- id_column + 'ams_attribute', -- package_name + 'f', -- abstract_p + null, -- type_extension_table + 'ams_attribute__name' -- name_method +); + +select acs_attribute__create_attribute ( + 'ams_attribute', -- object_type + 'attribute_id', -- attribute_name + 'integer', -- datatype + 'ACS Attribute ID', -- pretty_name + 'ACS Attribute IDs', -- pretty_plural -- default null + null, -- table_name -- default null + 'attribute_id', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_attribute', -- object_type + 'widget_name', -- attribute_name + 'string', -- datatype + 'Widget Name', -- pretty_name + 'Widget Name', -- pretty_plural -- default null + null, -- table_name -- default null + 'widget_name', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_attribute', -- object_type + 'deprecated_p', -- attribute_name + 'boolean', -- datatype + 'Deprecated', -- pretty_name + 'Deprecated', -- pretty_plural -- default null + null, -- table_name -- default null + 'deprecated_p', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + + +------ Objects +-------------------------------------------------------------------- + +-- In order to allow for an acs_object to become a cr_item +-- we need to do a one to one cr_item to acs_object map. This +-- allows for no content repository controlled acs_objects +-- to get revisions, via their associated ams_object + +create table ams_objects ( + ams_object_id integer + constraint ams_objects_ams_object_id_fk references cr_items(item_id) on delete cascade + constraint ams_objects_ams_object_id_pk primary key, + object_id integer + constraint ams_object_revisions_object_id_fk references acs_objects(object_id) + constraint ams_object_revisions_object_id_nn not null, + unique(object_id) +); + +create table ams_object_revisions ( + ams_object_revision_id integer + constraint ams_object_revisions_revision_id_fk references cr_revisions(revision_id) on delete cascade + constraint ams_object_revisions_revision_id_pk primary key +); + +-- create the CR content type + +select content_type__create_type ( + 'ams_object_revision', -- content_type + 'content_revision', -- supertype + 'AMS Object', -- pretty_name + 'AMS Objects', -- pretty_plural + 'ams_object_revisions', -- table_name + 'ams_object_revision_id', -- id_column + 'ams_object_revision__name' -- name_method +); + + + +------ Options +-------------------------------------------------------------------- + + +create sequence ams_options_id_seq; +create table ams_options ( + option_id integer + constraint ams_options_option_id_nn not null + constraint ams_options_option_id_nn primary key, + ams_attribute_id integer + constraint ams_options_ams_attribute_id_nn not null + constraint ams_options_ams_attribute_id_nn references ams_attributes (ams_attribute_id), + option varchar(200) + constraint ams_options_option_nn not null, + sort_order integer, + unique (ams_attribute_id,sort_order) +); + +create sequence ams_option_map_id_seq; +create table ams_option_map_ids ( + option_map_id integer + constraint ams_option_map_ids_option_map_id_pk primary key +); + +create table ams_option_map ( + option_map_id integer + constraint ams_option_map_option_map_id_nn not null + constraint ams_option_map_option_map_id_fk references ams_option_map_ids(option_map_id), + option_id integer + constraint ams_option_map_option_id_fk references ams_options(option_id) + constraint ams_option_map_option_id_nn not null +); + + + +------ Attribute Values +-------------------------------------------------------------------- + + + +create table ams_attribute_values ( + revision_id integer + constraint ams_attribute_values_revision_id_fk references cr_revisions(revision_id) + constraint ams_attribute_values_revision_id_nn not null, + superseed_revision_id integer + constraint ams_attribute_values_superseed_revision_id_fk references cr_revisions(revision_id), + ams_attribute_id integer + constraint ams_attribute_values_ams_attribute_id_fk references ams_attributes(ams_attribute_id) + constraint ams_attribute_values_ams_attribute_id_nn not null, + option_map_id integer + constraint ams_attribute_values_option_id_fk references ams_option_map_ids(option_map_id), + address_id integer + constraint ams_attribute_values_address_id_fk references postal_addresses(address_id), + number_id integer + constraint ams_attribute_values_number_id_fk references telecom_numbers(number_id), + time timestamptz, + value text, + value_mime_type character varying(50) default 'text/plain' + constraint ams_attribute_values_mime_type_fk references cr_mime_types(mime_type) +); + + + + + +------ Lists +-------------------------------------------------------------------- + +-- We now create groupings of ams attributes, we call them lists +-- since these groupings will be used to create lists of elements +-- for ad_form as well as lists of certain attributes to be used +-- by other applications. +-- +-- Note: the ams_lists table copies the workflows table in the +-- workflow package since it has a similar function and it helps +-- to ensure consistency amongst openacs packages. There are some +-- minor discrepencies since AMS uses acs_lang for any and all +-- human readable text in the package. + + +create table ams_lists ( + list_id integer + constraint ams_lists_list_id_fk references acs_objects(object_id) + constraint ams_lists_list_id_pk primary key, + short_name varchar(100) + constraint ams_lists_short_name_nn not null, + pretty_name varchar(200) + constraint ams_lists_pretty_name_nn not null, + object_id integer + constraint ams_lists_object_id_fk references acs_objects(object_id), + package_key varchar(100) + constraint ams_lists_package_key_fk references apm_package_types(package_key) + constraint ams_lists_package_key_nn not null, + object_type varchar(1000) + constraint ams_lists_object_type_fk references acs_object_types(object_type) + constraint ams_lists_object_type_nn not null, + description varchar(200), + description_mime_type varchar(200) + constraint ams_lists_description_mime_type_fk references cr_mime_types(mime_type), + UNIQUE(short_name,package_key,object_type) +); + +select acs_object_type__create_type ( + 'ams_list', -- object_type + 'AMS List', -- pretty_name + 'AMS Lists ', -- pretty_plural + 'acs_object', -- supertype + 'ams_lists', -- table_name + 'list_id', -- id_column + 'ams_list', -- package_name + 'f', -- abstract_p + null, -- type_extension_table + 'ams_list__name' -- name_method +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'short_name', -- attribute_name + 'string', -- datatype + 'Short Name', -- pretty_name + 'Short Names', -- pretty_plural -- default null + null, -- table_name -- default null + 'short_name', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'pretty_name', -- attribute_name + 'string', -- datatype + 'Pretty Name', -- pretty_name + 'Pretty Names', -- pretty_plural -- default null + null, -- table_name -- default null + 'pretty_name', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'object_id', -- attribute_name + 'integer', -- datatype + 'Object ID', -- pretty_name + 'Object ID', -- pretty_plural -- default null + null, -- table_name -- default null + 'object_type', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'package_key', -- attribute_name + 'string', -- datatype + 'Package Key', -- pretty_name + 'Package Keys', -- pretty_plural -- default null + null, -- table_name -- default null + 'object_type', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'object_type', -- attribute_name + 'string', -- datatype + 'Object Type', -- pretty_name + 'Object Types', -- pretty_plural -- default null + null, -- table_name -- default null + 'object_type', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'description', -- attribute_name + 'text', -- datatype + 'Description', -- pretty_name + 'Descriptions', -- pretty_plural -- default null + null, -- table_name -- default null + 'description', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +select acs_attribute__create_attribute ( + 'ams_list', -- object_type + 'description_mime_type', -- attribute_name + 'text', -- datatype + 'Descriptions', -- pretty_name + 'Description Mime Types', -- pretty_plural -- default null + null, -- table_name -- default null + 'description_mime_type', -- column_name -- default null + null, -- default_value -- default null + '1', -- min_n_values -- default 1 + '1', -- max_n_values -- default 1 + null, -- sort_order -- default null + 'type_specific', -- storage -- default 'type_specific' + null -- static_p -- default 'f' +); + +create sequence ams_list_attribute_sort_order_seq; + +create table ams_list_attribute_map ( + list_id integer + constraint ams_list_attribute_map_list_id_fk references ams_lists(list_id) + constraint ams_list_attribute_map_list_id_nn not null, + ams_attribute_id integer + constraint ams_list_attribute_map_ams_attribute_id_fk references ams_attributes(ams_attribute_id) + constraint ams_list_attribute_map_ams_attribute_id_nn not null, + sort_order integer + constraint ams_list_attribute_map_sort_order_nn not null, + required_p boolean + constraint ams_list_attribute_map_required_p_nn not null, + section_heading varchar(200), + UNIQUE(list_id,ams_attribute_id), + UNIQUE(list_id,sort_order) +); + +\i ams-package-create.sql +\i populate.sql +\i telecom-number-missing-plsql.sql Index: openacs-4/packages/ams/sql/postgresql/ams-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/sql/postgresql/ams-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/sql/postgresql/ams-drop.sql 20 Oct 2004 21:40:04 -0000 1.1 @@ -0,0 +1,53 @@ +-- +-- packages/ams/sql/postgresql/ams-drop.sql +-- +-- @author Matthew Geddert openacs@geddert.com +-- @creation-date 2004-09-07 +-- @cvs-id $Id: ams-drop.sql,v 1.1 2004/10/20 21:40:04 matthewg Exp $ +-- +-- + + +select content_folder__delete (folder_id, 't') + from cr_folders + where label = 'AMS Objects' + and description = 'AMS Object Repository'; + +delete from cr_folder_type_map where content_type = 'ams_object_revision'; +delete from acs_attribute_descriptions where description_key = 'ams_attribute_description'; + +select drop_package('ams_option'); +select drop_package('ams_attribute'); +select drop_package('ams_attribute_value'); +select drop_package('ams_object_revision'); + +drop function ams_object__new (integer,integer,timestamptz,integer,varchar); +drop function ams_object_id (integer); +-- select drop_package('ams_object_id'); +select drop_package('ams_list'); + + +drop sequence ams_options_id_seq; +drop sequence ams_option_map_id_seq; +drop sequence ams_list_attribute_sort_order_seq; + +drop table ams_list_attribute_map; +drop table ams_lists; +drop view ams_object_revisionsx; +drop view ams_object_revisionsi; +drop table ams_object_revisions cascade; +drop table ams_objects cascade; +drop table ams_attribute_values cascade; +drop table ams_option_map cascade; +drop table ams_option_map_ids cascade; +drop table ams_options cascade; +drop table ams_attributes cascade; +drop table ams_widgets cascade; +drop table ams_storage_types cascade; +update cr_items set live_revision = null, latest_revision = null where content_type = 'ams_object_revision'; +delete from cr_revisions where item_id in ( select item_id from cr_items where content_type = 'ams_object_revision' ); +delete from cr_items where content_type = 'ams_object_revision'; +delete from acs_objects where object_type in ('ams_list','ams_object_revision','ams_attribute'); +select acs_object_type__drop_type('ams_list','f'); +select acs_object_type__drop_type('ams_object_revision','f'); +select acs_object_type__drop_type('ams_attribute','f'); Index: openacs-4/packages/ams/sql/postgresql/ams-package-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/sql/postgresql/ams-package-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/sql/postgresql/ams-package-create.sql 20 Oct 2004 21:40:03 -0000 1.1 @@ -0,0 +1,692 @@ +-- +-- packages/ams/sql/postgresql/ams-package-create.sql +-- +-- @author Matthew Geddert openacs@geddert.com +-- @creation-date 2004-09-07 +-- @cvs-id $Id: ams-package-create.sql,v 1.1 2004/10/20 21:40:03 matthewg Exp $ +-- +-- + + +------ Attributes +-------------------------------------------------------------------- + + + +select define_function_args('ams_attribute__new','ams_attribute_id,object_type,attribute_name,pretty_name,pretty_plural,default_value,description,widget_name,deprecated_p;f,creation_date,creation_user,creation_ip,context_id'); + +create or replace function ams_attribute__new (integer,varchar,varchar,varchar,varchar,varchar,text,varchar,boolean,timestamptz,integer,varchar,integer) +returns integer as ' +declare + p_ams_attribute_id alias for $1; -- the AMS Attribute ID + p_object_type alias for $2; + p_attribute_name alias for $3; + p_pretty_name alias for $4; + p_pretty_plural alias for $5; + p_default_value alias for $6; + p_description alias for $7; + p_widget_name alias for $8; + p_deprecated_p alias for $9; + p_creation_date alias for $10; + p_creation_user alias for $11; + p_creation_ip alias for $12; + p_context_id alias for $13; + v_attribute_id integer; + v_acs_datatype varchar; + v_ams_attribute_id integer; +begin + + v_acs_datatype := acs_datatype from ams_widgets where widget_name = p_widget_name; + + v_attribute_id := acs_attribute__create_attribute ( + p_object_type, + p_attribute_name, + v_acs_datatype, + p_pretty_name, + p_pretty_plural, + null, -- p_table_name + null, -- p_column_name + p_default_value, + ''0'', -- p_min_n_values + ''1'', -- p_max_n_values + null, -- p_sort_order + ''type_specific'', -- p_storage + ''f'' -- p_static_p + ); + + if p_description is not null then + PERFORM acs_attribute__add_description ( + p_object_type, + p_attribute_name, + ''ams_attribute_description'', + p_description + ); + end if; + + v_ams_attribute_id := acs_object__new ( + p_ams_attribute_id, + ''ams_attribute'', + p_creation_date, + p_creation_user, + P_creation_ip, + p_context_id + ); + + insert into ams_attributes + (ams_attribute_id,attribute_id,widget_name,deprecated_p) + values + (v_ams_attribute_id,v_attribute_id,p_widget_name,p_deprecated_p); + + return v_ams_attribute_id; +end;' language 'plpgsql'; + + + +create or replace function ams_attribute__name (integer) +returns varchar as ' +declare + p_ams_attribute_id alias for $1; + v_name varchar; +begin + v_name := acs_attributes.attribute_name + from acs_attributes, ams_attributes + where ams_attributes.ams_attribute_id = p_ams_attribute_id + and ams_attributes.attribute_id = acs_attributes.attribute_id; + + return v_name; +end;' language 'plpgsql'; + +create or replace function ams_attribute__pretty_name (integer) +returns varchar as ' +declare + p_ams_attribute_id alias for $1; + v_name varchar; +begin + v_name := acs_attributes.pretty_name + from acs_attributes, ams_attributes + where ams_attributes.ams_attribute_id = p_ams_attribute_id + and ams_attributes.attribute_id = acs_attributes.attribute_id; + + return v_name; +end;' language 'plpgsql'; + +create or replace function ams_attribute__delete (integer) +returns integer as ' +declare + p_ams_attribute_id alias for $1; + v_object_type varchar; + v_attribute_name varchar; +begin + select acs_attributes.attribute_name, acs_attributes.object_type + into v_object_type, v_attribute_name + from acs_attributes, ams_attributes + where ams_attributes.attribute_id = acs_attributes.attribute_id; + + delete from ams_attribute_values where ams_attribute_id = p_ams_attribute_id; + + PERFORM acs_object__delete ( + p_ams_attribute_id + ); + + PERFORM acs_attribute__drop_description ( + v_object_type, + v_attribute_name, + ''ams_attribute_description'' + ); + + PERFORM acs_attribute__drop_attribute ( + v_object_type, + v_attribute_name + ); + + return 0; +end;' language 'plpgsql'; + + + + + + +------ Objects +-------------------------------------------------------------------- + + +create or replace function ams_object_revision__root_folder (integer) +returns integer as ' +declare + p_package_id alias for $1; + v_folder_id integer; + v_count integer; + v_folder_name varchar; +begin + v_count := count(*) from cr_folders where package_id = p_package_id; + + if v_count = 0 then + + v_folder_name := package_key || ''_'' || p_package_id from apm_packages + where package_id = p_package_id; + + -- create a new root folder + v_folder_id := content_folder__new ( + v_folder_name, -- name + ''AMS Objects'', -- label + ''AMS Object Repository'', -- description + null, -- parent_id + p_package_id, -- parent_id + null, -- folder_id + null, -- creation_date + null, -- creation_user + null -- creation_ip + ); + + -- register folder content types + PERFORM content_folder__register_content_type ( + v_folder_id, -- folder_id + ''ams_object_revision'', -- content_type + ''f'' -- include_subtypes + ); + + -- there is no facility in the API for adding in the package_id, + -- so we have to do it ourselves + + update cr_folders + set package_id = p_package_id + where folder_id = v_folder_id; + + else + v_folder_id := folder_id from cr_folders where package_id = p_package_id; + end if; + + return v_folder_id; + +end; ' language 'plpgsql'; + + + +-- select define_function_args('ams_object_id','object_id,package_id,creation_date;now(),creation_user,creation_ip'); +-- get the ams_object_id, and none exists create a new content item + +create or replace function ams_object__new (integer,integer,timestamptz,integer,varchar) +returns integer as ' +declare + p_object_id alias for $1; + p_package_id alias for $2; + p_creation_date alias for $3; + p_creation_user alias for $4; + p_creation_ip alias for $5; + v_ams_object_id integer; + v_count integer; +begin + v_count := count(*) from ams_objects where object_id = p_object_id; + + if v_count = 0 then + + -- create a new item + v_ams_object_id := content_item__new ( + p_object_id::varchar, -- name + ams_object_revision__root_folder(p_package_id), -- parent_id + null, -- item_id + null, -- locale + p_creation_date, -- creation_date + p_creation_user, -- creation_user + p_object_id, -- context_id + p_creation_ip, -- creation_ip + ''content_item'', -- item_subtype + ''ams_object_revision'', -- content_type + null, -- title + null, -- description + null, -- mime_type + null, -- nls_language + null -- data + ); + + insert into ams_objects + (ams_object_id,object_id) + values + (v_ams_object_id,p_object_id); + + else + v_ams_object_id := ams_object_id(p_object_id); + end if; + + return v_ams_object_id; +end;' language 'plpgsql'; + + + +create or replace function ams_object_id (integer) +returns integer as ' +declare + p_object_id alias for $1; + v_ams_object_id integer; +begin + return ams_object_id from ams_objects where object_id = p_object_id; +end;' language 'plpgsql'; + + + +select define_function_args('ams_object_revision__new','object_id,package_id,creation_date;now(),creation_user,creation_ip'); + +create or replace function ams_object_revision__new (integer,integer,timestamptz,integer,varchar) +returns integer as ' +declare + p_object_id alias for $1; + p_package_id alias for $2; + p_creation_date alias for $3; + p_creation_user alias for $4; + p_creation_ip alias for $5; + v_ams_object_id integer; + v_ams_object_revision_id integer; +begin + + -- get the ams_object_id and create the content item if necessary + v_ams_object_id := ams_object__new ( + p_object_id, + p_package_id, + p_creation_date, + p_creation_user, + p_creation_ip + ); + + v_ams_object_revision_id := content_revision__new ( + null, -- title + null, -- description + now(), -- publish_date + null, -- mime_type + null, -- nls_language + null, -- data + v_ams_object_id, -- item_id + null, -- revision_id + p_creation_date, -- creation_date + p_creation_user, -- creation_user + p_creation_ip -- creation_ip + ); + + PERFORM content_item__set_live_revision (v_ams_object_revision_id); + + insert into ams_object_revisions + (ams_object_revision_id) + values + (v_ams_object_revision_id); + + return v_ams_object_revision_id; +end;' language 'plpgsql'; + + + +------ Options +-------------------------------------------------------------------- + +create or replace function ams_option__new (integer,varchar,integer) +returns integer as ' +declare + p_ams_attribute_id alias for $1; + p_option alias for $2; + p_sort_order alias for $3; + v_option_id integer; +begin + + v_option_id := nextval(''ams_options_seq''); + + insert into ams_options + (option_id,ams_attribute_id,option,sort_order) + values + (v_option_id,p_ams_attribute_id,p_option,p_sort_order); + + return v_option_id; +end;' language 'plpgsql'; + + +create or replace function ams_option__delete(integer) +returns integer as ' +declare + p_option_id alias for $1; +begin + delete from ams_options where object_id = p_option_id; + + return 0; +end;' language 'plpgsql'; + +create or replace function ams_option__map (integer,integer) +returns integer as ' +declare + p_option_map_id alias for $1; + p_option_id alias for $2; + v_option_map_id integer; +begin + + if count(*) from ams_option_map where option_map_id = p_option_map_id = ''0'' then + + v_option_map_id := nextval(''ams_option_map_id_seq''); + insert into ams_option_map_ids(option_map_id) value (v_option_map_id); + + else + v_option_map_id := p_option_map_id; + + end if; + + insert into ams_option_map + (option_map_id,option_id) + values + (v_option_map_id,p_option_id); + + return v_option_map_id; +end;' language 'plpgsql'; + + + + + +------ Attribute Values +-------------------------------------------------------------------- + +-- Unlike the ams_attribute_value__save proc below this one, +-- ams_attribute_value__new will save null entries (i.e. when +-- no value was given for an attribute). this will chew up +-- database space (with non-value rows). but it can be called +-- upon by content repository managed objects to store attribute +-- values with that objects revision_id (as opposed to the ams +-- managed revision_id). This is useful when permissions are not +-- set to hide certain attributes from users. If the attributes +-- for an object are restrict based on permissions the ams_object +-- container is preferred since it is made to deal with the +-- retrieval and display of this more complex form of content +-- revision. Note, this proc does not mark previous revisions as +-- superseeded, so if another objects revisions are used you must +-- make sure that the attribute has not already been entered for +-- this particular revision. + + + +create or replace function ams_attribute_value__new (integer,integer,integer,integer,integer,timestamptz,text,varchar) +returns integer as ' +declare + p_revision_id alias for $1; + p_ams_attribute_id alias for $2; + p_option_map_id alias for $3; + p_address_id alias for $4; + p_number_id alias for $5; + p_time alias for $6; + p_value alias for $7; + p_value_mime_type alias for $8; +begin + insert into ams_attribute_values + (revision_id,ams_attribute_id,option_map_id,address_id,number_id,time,value,value_mime_type) + values + (p_revision_id,p_ams_attribute_id,p_option_map_id,p_address_id,p_number_id,p_time,p_value,p_value_mime_type); + + return 0; +end;' language 'plpgsql'; + + + +create or replace function ams_attribute_value__superseed (integer,integer,integer) +returns integer as ' +declare + p_revision_id alias for $1; + p_ams_attribute_id alias for $2; + p_ams_object_id alias for $3; +begin + + update ams_attribute_values + set superseed_ams_attribute_id = p_revision_id + where ams_attribute_id = p_ams_attribute_id + and superseed_revision_id is null + and revision_id in ( select revision_id + from cr_revisions + where item_id = p_ams_object_id ); + + + return 0; +end;' language 'plpgsql'; + + + +create or replace function ams_attribute_value__save (integer,integer,integer,integer,integer,timestamptz,text,varchar) +returns integer as ' +declare + p_revision_id alias for $1; + p_ams_attribute_id alias for $2; + p_option_map_id alias for $3; + p_address_id alias for $4; + p_number_id alias for $5; + p_time alias for $6; + p_value alias for $7; + p_value_mime_type alias for $8; + v_ams_object_id integer; + v_count integer; + v_option_map_id integer; + v_address_id integer; + v_number_id integer; + v_time timestamptz; + v_value text; + v_value_mime_type varchar; + v_insert_new_p boolean; + v_duplicate_p boolean; +begin + + v_ams_object_id := item_id from cr_revisions where revision_id = p_revision_id; + + v_count := count(*) from ams_attribute_values + where superseed_revision_id is null + and revision_id in ( select revision_id + from cr_revisions + where item_id = v_ams_object_id ); + + if v_count > 0 then + select option_map_id, + address_id, + number_id, + time, + value, + value_mime_type + into v_option_map_id, + v_address_id, + v_number_id, + v_time, + v_value, + v_value_mime_type + from ams_attribute_values + where ams_attribute_id = p_ams_attribute_id + and revision_id in ( select revision_id + from cr_items + where item_id = v_ams_object_id ) + and superseed_revision_id is not null; + + if v_option_map_id != p_option_map_id + or v_address_id != p_address_id + or v_number_id != p_number_id + or v_time != p_time + or v_value != p_value + then + PERFORM ams_attribute_value__superseed ( + p_revision_id, + p_ams_attribute_id, + v_ams_object_id + ); + + v_duplicate_p := ''f''; + else + v_duplicate_p := ''t''; + + end if; + else + v_duplicate_p := ''f''; + end if; + + + if not v_duplicate_p then + -- we know that this is not duplicate + + if p_option_map_id is not null + or p_address_id is not null + or p_number_id is not null + or p_time is not null + or p_value is not null + then + -- there is a not null value to this attribute + PERFORM ams_attribute_value__new ( + p_revision_id, + p_ams_attribute_id, + p_option_map_id, + p_address_id, + p_number_id, + p_time, + p_value, + p_value_mime_type + ); + end if; + + end if; + + + return 0; +end;' language 'plpgsql'; + + + +------ Groups +-------------------------------------------------------------------- + + + +select define_function_args('ams_list__new','list_id,short_name,pretty_name,object_id,package_key,object_type,description,description_mime_type,creation_date,creation_user,creation_ip,context_id'); + +create or replace function ams_list__new (integer,varchar,varchar,integer,varchar,varchar,varchar,varchar,timestamptz,integer,varchar,integer) +returns integer as ' +declare + p_list_id alias for $1; + p_short_name alias for $2; + p_pretty_name alias for $3; + p_object_id alias for $4; + p_package_key alias for $5; + p_object_type alias for $6; + p_description alias for $7; + p_description_mime_type alias for $8; + p_creation_date alias for $9; + p_creation_user alias for $10; + p_creation_ip alias for $11; + p_context_id alias for $12; + v_list_id integer; +begin + + v_list_id := acs_object__new ( + p_list_id, + ''ams_list'', + p_creation_date, + p_creation_user, + P_creation_ip, + p_context_id + ); + + insert into ams_lists + (list_id,short_name,pretty_name,object_id,package_key,object_type,description,description_mime_type) + values + (v_list_id,p_short_name,p_pretty_name,p_object_id,p_package_key,p_object_type,p_description,p_description_mime_type); + + return v_list_id; +end;' language 'plpgsql'; + +create or replace function ams_list__attribute_map (integer,integer,integer,boolean,varchar) +returns integer as ' +declare + p_list_id alias for $1; + p_ams_attribute_id alias for $2; + p_sort_order alias for $3; + p_required_p alias for $4; + p_section_heading alias for $5; + v_sort_order integer; +begin + + if p_sort_order is null then + v_sort_order := nextval(''ams_list_attribute_sort_order_seq''); + else + v_sort_order := p_sort_order; + end if; + + delete from ams_list_attribute_map + where ams_attribute_id = p_ams_attribute_id + and list_id = p_list_id; + + insert into ams_list_attribute_map + (list_id,ams_attribute_id,sort_order,required_p,section_heading) + values + (p_list_id,p_ams_attribute_id,v_sort_order,p_required_p,p_section_heading); + + return ''1''; +end;' language 'plpgsql'; + + + + + + + + + + + + + + +------ Postal Address +-------------------------------------------------------------------- + +create or replace function ams_attribute__postal_address_string (integer) +returns varchar as ' +declare + p_address_id alias for $1; + v_name text; +begin + + if p_address_id is not null then + v_name := ''{'' || + CASE WHEN delivery_address is not null THEN delivery_address ELSE '''' END || ''} {'' || + CASE WHEN municipality is not null THEN municipality ELSE '''' END || ''} {'' || + CASE WHEN region is not null THEN region ELSE '''' END || ''} {'' || + CASE WHEN postal_code is not null THEN postal_code ELSE '''' END || ''} {'' || + CASE WHEN country_code is not null THEN country_code::varchar ELSE '''' END || ''} {'' || + CASE WHEN additional_text is not null THEN additional_text ELSE '''' END || ''} {'' || + CASE WHEN postal_type is not null THEN postal_type ELSE '''' END || ''}'' + from postal_addresses + where address_id = p_address_id; + else + v_name := NULL; + end if; + + return v_name; +end;' language 'plpgsql'; + + + +------ Telecom Number +-------------------------------------------------------------------- + + +create or replace function ams_attribute__telecom_number_string (integer) +returns varchar as ' +declare + p_number_id alias for $1; + v_name text; +begin + + if p_number_id is not null then + v_name := ''{'' || + CASE WHEN itu_id is not null THEN itu_id ELSE '''' END || ''} {'' || + CASE WHEN national_number is not null THEN national_number ELSE '''' END || ''} {'' || + CASE WHEN area_city_code is not null THEN area_city_code ELSE '''' END || ''} {'' || + CASE WHEN subscriber_number is not null THEN subscriber_number ELSE '''' END || ''} {'' || + CASE WHEN extension is not null THEN extension ELSE '''' END || ''} {'' || + CASE WHEN sms_enabled_p is not null THEN CASE WHEN sms_enabled_p THEN ''1'' ELSE ''0'' END ELSE '''' END || ''} {'' || + CASE WHEN best_contact_time is not null THEN best_contact_time ELSE '''' END || ''} {'' || + CASE WHEN location is not null THEN location ELSE '''' END || ''} {'' || + CASE WHEN phone_type_id is not null THEN phone_type_id ELSE '''' END || ''}'' + from telecom_numbers + where number_id = p_number_id; + else + v_name := NULL; + end if; + + return v_name; +end;' language 'plpgsql'; + Index: openacs-4/packages/ams/sql/postgresql/populate.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/sql/postgresql/populate.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/sql/postgresql/populate.sql 20 Oct 2004 21:40:04 -0000 1.1 @@ -0,0 +1,450 @@ +-- +-- packages/ams/sql/postgresql/populate.sql +-- +-- @author Matthew Geddert openacs@geddert.com +-- @creation-date 2004-09-07 +-- @cvs-id $Id: populate.sql,v 1.1 2004/10/20 21:40:04 matthewg Exp $ +-- +-- + +insert into ams_storage_types ( storage_type ) values ( 'telecom_number' ); +insert into ams_storage_types ( storage_type ) values ( 'postal_address' ); +insert into ams_storage_types ( storage_type ) values ( 'ams_options' ); +insert into ams_storage_types ( storage_type ) values ( 'time' ); +insert into ams_storage_types ( storage_type ) values ( 'value' ); +insert into ams_storage_types ( storage_type ) values ( 'value_with_mime_type' ); + +-- +-- Note, I am very open to adding new unique widgets. +-- I am simply adding those I personally could imagine +-- needing in the near future for my projects. I am sure +-- that there will be others that other programmers need. +-- So, If you would like a new widget and possibly a new +-- storage type added to the default configuration of +-- this package please contact me. +-- -- Matthew +-- + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'postal_address', + '#ams.Address#', + '#ams.Addresses#', + 'postal_address', + 'string', + 'address', + 'address', + null +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'telecom_number', + '#ams.Telecom_Number#', + '#ams.Telecom_Numbers#', + 'telecom_number', + 'string', + 'telecom_number', + 'telecom_number', + '{html {size 12 maxlenth 50}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'date', + '#ams.Date#', + '#ams.Date#', + 'time', + 'date', + 'date', + 'date', + '{help}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'select', + '#ams.Select# - #ams.One_Option_Allowed#', + '#ams.Selects# - #ams.One_Option_Allowed#', + 'ams_options', + 'string', + 'select', + 'integer', + null +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'radio', + '#ams.Radio# - #ams.One_Option_Allowed#', + '#ams.Radios# - #ams.One_Option_Allowed#', + 'ams_options', + 'string', + 'radio', + 'integer', + null +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'checkbox', + '#ams.Checkboxes# - #ams.Multiple_Options_Allowed#', + '#ams.Checkboxes# - #ams.Multiple_Options_Allowed#', + 'ams_options', + 'string', + 'checkbox', + 'integer', + '{multiple}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'multiselect', + '#ams.Multiselect# - #ams.Multiple_Options_Allowed#', + '#ams.Multiselects# - #ams.Multiple_Options_Allowed#', + 'ams_options', + 'string', + 'multiselect', + 'integer', + '{multiple}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'multiselect_single', + '#ams.Multiselect# - #ams.One_Option_Allowed#', + '#ams.Multiselects# - #ams.One_Option_Allowed#', + 'ams_options', + 'string', + 'multiselect', + 'integer', + null +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'number', + '#ams.Number#', + '#ams.Numbers#', + 'value', + 'number', + 'text', + 'numeric', + '{html {size 6}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'integer', + '#ams.Integer#', + '#ams.Integers#', + 'value', + 'integer', + 'text', + 'integer', + '{html {size 6}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textbox_small', + '#ams.Textbox# - #ams.Small#', + '#ams.Textboxes# - #ams.Small#', + 'value', + 'string', + 'text', + 'text', + '{html {size 18}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textbox_medium', + '#ams.Textbox# - #ams.Medium#', + '#ams.Textboxes# - #ams.Medium#', + 'value', + 'string', + 'text', + 'text', + '{html {size 30}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textbox_large', + '#ams.Textbox# - #ams.Large#', + '#ams.Textboxes# - #ams.Large#', + 'value', + 'string', + 'text', + 'text', + '{html {size 50}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textarea_small', + '#ams.Textarea# - #ams.Small#', + '#ams.Textareas# - #ams.Small#', + 'value', + 'text', + 'textarea', + 'text', + '{html {cols 60 rows 6}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textarea_small_nospell', + '#ams.Textarea# - #ams.Small# - #ams.No_Spellcheck#', + '#ams.Textareas# - #ams.Small# - #ams.No_Spellcheck#', + 'value', + 'text', + 'textarea', + 'text', + '{html {cols 60 rows 6}} {nospell}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textarea_medium', + '#ams.Textarea# - #ams.Medium#', + '#ams.Textareas# - #ams.Medium#', + 'value', + 'text', + 'textarea', + 'text', + '{html {cols 80 rows 10}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'textarea_large', + '#ams.Textarea# - #ams.Large#', + '#ams.Textareas# - #ams.Large#', + 'value', + 'text', + 'textarea', + 'text', + '{html {cols 80 rows 24}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'richtext_medium', + '#ams.Richtext# - #ams.Medium#', + '#ams.Richtexts# - #ams.Medium#', + 'value_with_mime_type', + 'text', + 'richtext', + 'richtext', + '{html {cols 80 rows 10}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'richtext_large', + '#ams.Richtext# - #ams.Large#', + '#ams.Richtexts# - #ams.Large#', + 'value_with_mime_type', + 'text', + 'richtext', + 'richtext', + '{html {cols 80 rows 24}}' +); + + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'email', + '#ams.Email_Address#', + '#ams.Email_Addresses#', + 'value', + 'email', + 'text', + 'email', + '{html {size 30}}' +); + +insert into ams_widgets ( + widget_name, + pretty_name, + pretty_plural, + storage_type, + acs_datatype, + widget, + datatype, + parameters +) values ( + 'url', + '#ams.Url#', + '#ams.Urls#', + 'value', + 'url', + 'text', + 'url', + '{html {size 30}}' +); + + + Index: openacs-4/packages/ams/sql/postgresql/telecom-number-missing-plsql.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/sql/postgresql/telecom-number-missing-plsql.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/sql/postgresql/telecom-number-missing-plsql.sql 20 Oct 2004 21:40:04 -0000 1.1 @@ -0,0 +1,43 @@ +-- +-- packages/ams/sql/postgresql/telecom-number-missing-plsql.sql +-- +-- @author Matthew Geddert openacs@geddert.com +-- @creation-date 2004-09-07 +-- @cvs-id $Id: telecom-number-missing-plsql.sql,v 1.1 2004/10/20 21:40:04 matthewg Exp $ +-- +-- + +-- +-- This file can safely be deleted once telecom number fixes a bug #2099 +-- I filed that has this code commented out +-- + +create function inline_0 () +returns integer as ' +declare + v_telecom_number_p boolean; +begin + v_telecom_number_p := ''1'' from acs_object_types where object_type = ''telecom_number''; + + if v_telecom_number_p then + else + PERFORM acs_object_type__create_type ( + ''telecom_number'', -- object_type + ''Telecom Number'', -- pretty_name + ''Telecom Number'', -- pretty_plural + ''acs_object'', -- supertype + ''telecom_numbers'', -- table_name + ''number_id'', -- id_column + ''telecom_number'', -- package_name + ''f'', -- abstract_p + null, -- type_extension_table + null -- name_method + ); + end if; + + return 0; +end;' language 'plpgsql'; + +select inline_0 (); + +drop function inline_0 (); Index: openacs-4/packages/ams/tcl/address-widget-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/tcl/address-widget-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/tcl/address-widget-procs-postgresql.xql 20 Oct 2004 21:40:02 -0000 1.1 @@ -0,0 +1,19 @@ + + + + + + + select default_name, iso from countries order by default_name + + + + + + + select 1 from us_states where abbrev = upper(:region) or state_name = upper(:region) + + + + + Index: openacs-4/packages/ams/tcl/address-widget-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/tcl/address-widget-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/tcl/address-widget-procs.tcl 20 Oct 2004 21:40:03 -0000 1.1 @@ -0,0 +1,338 @@ +ad_library { + + Address input widget and datatype for the OpenACS templating system. + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-09-28 + @cvs-id $Id: address-widget-procs.tcl,v 1.1 2004/10/20 21:40:03 matthewg Exp $ + +} + +namespace eval template {} +namespace eval template::data {} +namespace eval template::data::transform {} +namespace eval template::data::validate {} +namespace eval template::util {} +namespace eval template::util::address {} +namespace eval template::widget {} + +ad_proc -public template::util::address { command args } { + Dispatch procedure for the address object +} { + eval template::util::address::$command $args +} + +ad_proc -public template::util::address::create { + {delivery_address {}} + {municipality {}} + {region {}} + {postal_code {}} + {country_code {}} + {additional_text {}} + {postal_type {}} +} { + return [list $delivery_address $municipality $region $postal_code $country_code $additional_text $postal_type] +} + +ad_proc -public template::util::address::html_view { + {delivery_address {}} + {municipality {}} + {region {}} + {postal_code {}} + {country_code {}} + {additional_text {}} + {postal_type {}} +} { + # MGEDDERT TODO, convert country code to country name via cached proc + set country $country_code + set address "$delivery_address +$municipality, $region $postal_code +$country" + return [ad_text_to_html $address] +} + +ad_proc -public template::util::address::acquire { type { value "" } } { + Create a new address value with some predefined value + Basically, create and set the address value +} { + set address_list [template::util::address::create] + return [template::util::address::set_property $type $address_list $value] +} + +ad_proc -public template::util::address::formats {} { + Returns a list of valid address formats +} { +# MGEDDERT NOTE: there needs to be a way to implement a way to portray addresses differently by country + return { US CA DE } +} + +ad_proc -public template::util::address::country_options {} { + Returns the country list. Cached. +} { + return [util_memoize [list template::util::address::country_options_not_cached]] +} + +ad_proc -public template::util::address::country_options_not_cached {} { + Returns the country list. +} { + return [db_list_of_lists get_countries {}] +} + +ad_proc -public template::data::validate::address { value_ref message_ref } { + + upvar 2 $message_ref message $value_ref address_list + + set delivery_address [template::util::address::get_property delivery_address $address_list] + set municipality [template::util::address::get_property municipality $address_list] + set region [template::util::address::get_property region $address_list] + set postal_code [template::util::address::get_property postal_code $address_list] + set country_code [template::util::address::get_property country_code $address_list] + set additional_text [template::util::address::get_property additional_text $address_list] + set postal_type [template::util::address::get_property postal_type $address_list] + + set message "" + # this is used to make sure there are no invalid characters in the address + set address_temp "$delivery_address $municipality $region $postal_code $country_code $additional_text $postal_type" + if { [::string match "\{" $address_temp] || [::string match "\}" $address_temp] } { + # for built in display purposes these characters are not allowed, if you need it + # to be allowed make SURE that retrieval procs in AMS are also updated + # to deal with this change + if { [exists_and_not_null message_temp] } { append message " " } + append message "[_ ams.Your_entry_must_not_contain_the_following_characters]: \{ \}." + } + if { $country_code == "US" } { + # this should check a cached list + if { ![db_0or1row validate_state {} ] } { + if { [exists_and_not_null message_temp] } { append message " " } + append message "\"$region\" [_ ams.is_not_a_valid_US_state]." + } + } + if { [exists_and_not_null message_temp] } { + return 0 + } else { + return 1 + } +} + + +ad_proc -public template::data::transform::address { element_ref } { + + upvar $element_ref element + set element_id $element(id) + +# set contents [ns_queryget $element_id] +# set format [ns_queryget $element_id.format] + + set delivery_address [ns_queryget $element_id.delivery_address] + set municipality [ns_queryget $element_id.municipality] + set region [ns_queryget $element_id.region] + set postal_code [ns_queryget $element_id.postal_code] + set country_code [ns_queryget $element_id.country_code] + set additional_text [ns_queryget $element_id.additional_text] + set postal_type [ns_queryget $element_id.postal_type] + + + + if { [empty_string_p $delivery_address] } { + # We need to return the empty list in order for form builder to think of it + # as a non-value in case of a required element. + return [list] + } else { + return [list [list $delivery_address $municipality $region $postal_code $country_code $additional_text $postal_type]] + } +} + +ad_proc -public template::util::address::set_property { what address_list value } { + Set a property of the address datatype. + + @param what One of + + + @param address_list the address list to modify + @param value the new value + + @return the modified list +} { + + set delivery_address [template::util::address::get_property delivery_address $address_list] + set postal_code [template::util::address::get_property postal_code $address_list] + set municipality [template::util::address::get_property municipality $address_list] + set region [template::util::address::get_property region $address_list] + set country_code [template::util::address::get_property country_code $address_list] + set additional_text [template::util::address::get_property additional_text $address_list] + set postal_type [template::util::address::get_property postal_type $address_list] + + switch $what { + delivery_address - street_address - street { + return [list $value $municipality $region $postal_code $country_code $additional_text $postal_type] + } + municipality - city - town { + return [list $delivery_address $value $region $postal_code $country_code $additional_text $postal_type] + } + region - state - province { + return [list $delivery_address $municipality $value $postal_code $country_code $additional_text $postal_type] + } + postal_code - zip_code - zip { + return [list $delivery_address $municipality $region $value $country_code $additional_text $postal_type] + } + country_code - country { + return [list $delivery_address $municipality $region $postal_code $value $additional_text $postal_type] + } + additional_text { + return [list $delivery_address $municipality $region $postal_code $country_code $value $postal_type] + } + postal_type { + return [list $delivery_address $municipality $region $postal_code $country_code $additional_text $value ] + } + default { + error "Parameter supplied to util::address::set_property 'what' must be one of: 'delivery_address', 'postal_code', 'municipality', 'region', 'country_code', 'additional_text', 'postal_type'. You specified: '$what'." + } + } +} + +ad_proc -public template::util::address::get_property { what address_list } { + + Get a property of the address datatype. Valid properties are: + + @param what the name of the property. Must be one of: + + @param address_list a address datatype value, usually created with ad_form. +} { + + switch $what { + delivery_address - street_address - street { + return [lindex $address_list 0] + } + municipality - city - town { + return [lindex $address_list 1] + } + region - state - province { + return [lindex $address_list 2] + } + postal_code - zip_code - zip { + return [lindex $address_list 3] + } + country_code - country { + return [lindex $address_list 4] + } + additional_text { + return [lindex $address_list 5] + } + postal_type { + return [lindex $address_list 6] + } + html_view { + set delivery_address [template::util::address::get_property delivery_address $address_list] + set postal_code [template::util::address::get_property postal_code $address_list] + set municipality [template::util::address::get_property municipality $address_list] + set region [template::util::address::get_property region $address_list] + set country_code [template::util::address::get_property country_code $address_list] + set additional_text [template::util::address::get_property additional_text $address_list] + set postal_type [template::util::address::get_property postal_type $address_list] + return [template::util::address::html_view $delivery_address $postal_code $municipality $region $country_code $additional_text $postal_type] + } + default { + error "Parameter supplied to util::address::get_property 'what' must be one of: 'delivery_address', 'postal_code', 'municipality', 'region', 'country_code', 'additional_text', 'postal_type'. You specified: '$what'." + } + + } +} + +ad_proc -public template::widget::address { element_reference tag_attributes } { + Implements the address widget. + +} { + + upvar $element_reference element + +# if { [info exists element(html)] } { +# array set attributes $element(html) +# } + +# array set attributes $tag_attributes + + if { [info exists element(value)] } { + set delivery_address [template::util::address::get_property delivery_address $element(value)] + set postal_code [template::util::address::get_property postal_code $element(value)] + set municipality [template::util::address::get_property municipality $element(value)] + set region [template::util::address::get_property region $element(value)] + set country_code [template::util::address::get_property country_code $element(value)] + set additional_text [template::util::address::get_property additional_text $element(value)] + set postal_type [template::util::address::get_property postal_type $element(value)] + } else { + set delivery_address {} + set postal_code {} + set municipality {} + set region {} + set country_code [parameter::get -parameter "DefaultISOCountryCode" -default "US"] + set additional_text {} + set postal_type {} + } + + set output {} + + if { [string equal $element(mode) "edit"] } { + + + set attributes(id) \"address__$element(form_id)__$element(id)\" + + append output " + + + + + + + + + + + + + + + + + + + + + + + +
[_ ams.delivery_address]
      
[_ ams.municipality][_ ams.region][_ ams.postal_code]
[menu $element(id).country_code [template::util::address::country_options] $country_code attributes]
[_ ams.country]
+" + + } else { + # Display mode + if { [info exists element(value)] } { + append output [template::util::address::get_property html_view $element(value)] + append output "" + append output "" + append output "" + append output "" + append output "" + append output "" + append output "" + } + } + + return $output +} Index: openacs-4/packages/ams/tcl/ams-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/tcl/ams-procs-postgresql.xql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/tcl/ams-procs-postgresql.xql 20 Oct 2004 21:40:03 -0000 1.1 @@ -0,0 +1,676 @@ + + + + + + select ams_object_id(:object_id) + + + + + + select ams_object__new( + :object_id, + :package_id, + now(), + :creation_user, + :creation_ip + ); + + + + + + select ams_option__new (:ams_attribute_id,:option,:sort_order) + + + + + + select ams_option__delete (:option_id) + + + + + + + select ams_option__map (:option_map_id,:option_id) + + + + + + select ac.attribute_name, + ac.pretty_name, + ac.object_type, + aw.widget, + aw.datatype, + aw.parameters, + aw.storage_type + from ams_attributes aa, + acs_attributes ac, + ams_widgets aw + where aa.ams_attribute_id = :ams_attribute_id + and aa.attribute_id = ac.attribute_id + and aa.widget_name = aw.widget_name + + + + + + select option, option_id + from ams_options + where ams_attribute_id = :ams_attribute_id + order by sort_order + + + + + + select '1' from acs_attributes where object_type = :object_type and attribute_name = :attribute_name + + + + + + select ams.ams_attribute_id + from ams_attributes ams, acs_attributes acs + where acs.object_type = :object_type + and acs.attribute_name = :attribute_name + and acs.attribute_id = ams.attribute_id + + + + + + select ams_attribute__name (:ams_attribute_id) + + + + + + select aw.storage_type + from ams_widgets aw, ams_attributes aa + where aa.ams_attribute_id = :ams_attribute_id + and aw.widget_name = aa.widget_name + + + + + + select ams_attribute__delete (:ams_attribute_id) + + + + + + select aav.*, + ao.object_id, + ams_attribute__postal_address_string(address_id) as address_string, + ams_attribute__telecom_number_string(number_id) as telecom_number_string + from ams_attribute_values aav, cr_revisions cr, ams_objects ao + where ao.object_id in ($sql_object_id_list) + and ao.ams_object_id = cr.item_id + and cr.revision_id = aav.revision_id + and aav.superseed_revision_id is null + order by ao.object_id, aav.ams_attribute_id + + + + + + select ams_attribute_value__new ( + :revision_id, + :ams_attribute_id, + :option_map_id, + :address_id, + :number_id, + :time, + :value, + :value_mime_type + ) + + + + + + + select ams_attribute_value__save ( + :revision_id, + :ams_attribute_id, + :option_map_id, + :address_id, + :number_id, + :time, + :value, + :value_mime_type + ) + + + + + + select acs_object__new ( + null, + 'telecom_number', + ( select creation_date from acs_objects where object_id = :revision_id ), + ( select creation_user from acs_objects where object_id = :revision_id ), + ( select creation_ip from acs_objects where object_id = :revision_id ), + :revision_id + ) + + + + + + insert into telecom_numbers ( + number_id, + itu_id, + national_number, + area_city_code, + subscriber_number, + extension, + sms_enabled_p, + best_contact_time, + location, + phone_type_id + ) values ( + :number_id, + :itu_id, + :national_number, + :area_city_code, + :subscriber_number, + :extension, + :sms_enabled_p, + :best_contact_time, + :location, + :phone_type_id + ) + + + + + + select acs_object__new ( + null, + 'postal_address', + ( select creation_date from acs_objects where object_id = :revision_id ), + ( select creation_user from acs_objects where object_id = :revision_id ), + ( select creation_ip from acs_objects where object_id = :revision_id ), + :revision_id + ) + + + + + + insert into postal_addresses ( + address_id, + delivery_address, + municipality, + region, + postal_code, + country_code, + additional_text, + postal_type + ) values ( + :address_id, + :delivery_address, + :municipality, + :region, + :postal_code, + :country_code, + :additional_text, + :postal_type + ) + + + + + + insert into ams_attribute_values + (revision_id,ams_attribute_id,option_map_id,address_id,number_id,time,value,value_mime_type) + values + (:revision_id,:ams_attribute_id,:option_map_id,:address_id,:number_id,:time,:value,:value_mime_type) + + + + + + update ams_attribute_values + set superseed_revision_id = :revision_id + where ams_attribute_id = :ams_attribute_id + and superseed_revision_id is null + and revision_id in ( select revision_id + from cr_revisions + where item_id = :ams_object_id + and revision_id <> :revision_id ) + + + + + + select ams_attribute_id + from ams_list_attribute_map + where list_id = :list_id + + + + + + + select '1' + from ams_lists + where short_name = :short_name + and package_key = :package_key + and object_type = :object_type + + + + + + select list_id + from ams_lists + where short_name = :short_name + and package_key = :package_key + and object_type = :object_type + + + + + + + select ams_list__attribute_map ( + :list_id, + :ams_attribute_id, + :sort_order, + :required_p, + :section_heading + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select * from postal_addresses where address_id = :address_id + + + + + + + select telecom_number__new ( + :area_city_code, + :best_contact_time, + :extension, + :itu_id, + :location, + :national_number, + null, + null, + null, + :sms_enabled_p, + :subscriber_number, + :creation_user, + :creation_ip, + null + ) + + + + + + + select * from telecom_numbers where number_id = :number_id + + + + + + + select * + from contact_attributes ca, + contact_widgets cw, + contact_attribute_object_map caom, + contact_attribute_names can + where caom.object_id = :object_id + and ca.ams_attribute_id = can.ams_attribute_id + and can.locale = :locale + and caom.ams_attribute_id = ca.ams_attribute_id + and ca.widget_id = cw.widget_id + and not ca.depreciated_p + and acs_permission__permission_p(ca.ams_attribute_id,:user_id,'write') + order by caom.sort_order + + + + + + + + select ca.ams_attribute_id, + ca.attribute, + cav.option_map_id, + cav.address_id, + cav.number_id, + to_char(cav.time,'YYYY MM DD') as time, + cav.value, + cav.value_format, + cw.storage_column + from contact_attributes ca, + contact_widgets cw, + contact_attribute_object_map caom left join + ( select * + from contact_attribute_values + where party_id = :party_id + and not deleted_p ) cav + on (caom.ams_attribute_id = cav.ams_attribute_id) + where caom.object_id = '$object_id' + and caom.ams_attribute_id = ca.ams_attribute_id + and ca.widget_id = cw.widget_id + and not ca.depreciated_p + and ( + cav.option_map_id is not null + or cav.address_id is not null + or cav.number_id is not null + or cav.value is not null + or cav.time is not null + or ca.attribute in ($custom_field_sql_list) + ) + and acs_permission__permission_p(ca.ams_attribute_id,'$user_id','$permission') + order by caom.sort_order + + + + + + + select name + from organizations + where organization_id = :party_id + + + + + + + select legal_name + from organizations + where organization_id = :party_id + + + + + + + select reg_number + from organizations + where organization_id = :party_id + + + + + + + select first_names + from persons + where person_id = :party_id + + + + + + + select cao.option_id, cao.option + from contact_attribute_options cao, + organization_types ot, + organization_type_map otm + where cao.option = ot.type + and cao.ams_attribute_id = :ams_attribute_id + and otm.organization_type_id = ot.organization_type_id + and otm.organization_id = :party_id + + + + + + + select first_names + from persons + where person_id = :party_id + + + + + + + select last_name + from persons + where person_id = :party_id + + + + + + + select email + from parties + where party_id = :party_id + + + + + + + select url + from parties + where party_id = :party_id + + + + + + + select cao.option, cao.option_id + from contact_attribute_options cao, + contact_attribute_option_map caom + where caom.option_id = cao.option_id + and caom.option_map_id = :option_map_id + + + + + + select * + from contact_attributes ca, + contact_widgets cw, + contact_attribute_object_map caom, + contact_attribute_names can + where caom.object_id = :object_id + and ca.ams_attribute_id = can.ams_attribute_id + and can.locale = :locale + and caom.ams_attribute_id = ca.ams_attribute_id + and ca.widget_id = cw.widget_id + and not ca.depreciated_p + and acs_permission__permission_p(ca.ams_attribute_id,:user_id,'write') + order by caom.sort_order + + + + + + + select cav.address_id as old_address_id + from contact_attribute_values cav, + postal_addresses pa + where cav.party_id = :party_id + and cav.ams_attribute_id = :ams_attribute_id + and not cav.deleted_p + and cav.address_id = pa.address_id + and pa.delivery_address = :delivery_address + and pa.municipality = :municipality + and pa.region = :region + and pa.postal_code = :postal_code + and pa.country_code = :country_code + + + + + + + select cav.number_id as old_number_id + from contact_attribute_values cav, + telecom_numbers tn + where cav.party_id = :party_id + and cav.ams_attribute_id = :ams_attribute_id + and not cav.deleted_p + and cav.number_id = tn.number_id + and tn.subscriber_number = :attribute_value_temp + + + + + + + select option_map_id + from contact_attribute_values + where party_id = :party_id + and ams_attribute_id = :ams_attribute_id and not deleted_p + + + + + + + select option_id + from contact_attribute_option_map + where option_map_id = :option_map_id + + + + + + + select nextval('contact_attribute_option_map_id_seq') as option_map_id + + + + + + + insert into contact_attribute_option_map + (option_map_id,party_id,option_id) + values + (:option_map_id,:party_id,:option_id) + + + + + + + update parties set email = :attribute_value_temp where party_id = :party_id + + + + + + + update parties set url = :attribute_value_temp where party_id = :party_id + + + + + + + update organizations set name = :attribute_value_temp where organization_id = :party_id + + + + + + + update organizations set legal_name = :attribute_value_temp where organization_id = :party_id + + + + + + + update organizations set reg_number = :attribute_value_temp where organization_id = :party_id + + + + + + + delete from organization_type_map where organization_id = :party_id + + + + + + + select organization_type_id + from contact_attribute_options cao, + organization_types ot + where cao.option = ot.type + and cao.option_id = :option_id + + + + + + + insert into organization_type_map + (organization_id, organization_type_id) + values + (:party_id, :organization_type_id) + + + + + + + update persons set first_names = :attribute_value_temp where person_id = :party_id + + + + + + + update persons set last_name = :attribute_value_temp where person_id = :party_id + + + + + Index: openacs-4/packages/ams/tcl/ams-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/tcl/ams-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/tcl/ams-procs.tcl 20 Oct 2004 21:40:02 -0000 1.1 @@ -0,0 +1,994 @@ +ad_library { + + Support procs for the ams package + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-09-28 + @cvs-id $Id: ams-procs.tcl,v 1.1 2004/10/20 21:40:02 matthewg Exp $ + +} + + +ad_proc -private ams_object_id_not_cached { object_id } { + @param object_id + Returns the revision controlled ams_object_id for the given openacs object_id. + @return ams_object_id +} { + set ams_object_id [db_string select_ams_object_id {} -default {}] + if { [exists_and_not_null ams_object_id] } { + return $ams_object_id + } else { + set package_id [ams::package_id] + set creation_user [ad_conn user_id] + set creation_ip [ad_conn peeraddr] + return [db_string create_and_select_ams_object_id {}] + } +} + +ad_proc -public ams_object_id { object_id } { + @param object_id + Returns the revision controlled ams_object_id for the given openacs object_id. Cached. + @return ams_object_id +} { + return [util_memoize [list ams_object_id_not_cached $object_id]] +} + +namespace eval ams:: {} + +ad_proc -public ams::define_list { + {-reset_order:boolean} + {-object_id ""} + {-description ""} + {-description_mime_type ""} + short_name + pretty_name + package_key + object_type + attributes +} { + TODO: Need Documentation + + @param object_type the acs object_type these attributes are to belong to + @param attributes An array of attributes, if the attribute exists for this object this proc will make sure a duplicate is not created + + @see ams::define_attributes +} { + + # now we check to see if this list already exists + if { ![ams::list::exists_p $short_name $package_key $object_type] } { + set list_id [ams::list::new -short_name $short_name \ + -pretty_name $pretty_name \ + -package_key $package_key \ + -object_type $object_type \ + -description $description \ + -description_mime_type $description_mime_type] + + } else { + set list_id [ams::list::get_list_id $short_name $package_key $object_type] + } + + foreach { attribute } $attributes { + # the attribute follows this order + # attribute_name widget_name pretty_name pretty_plural default_value description + set attribute_name [lindex $attribute 0] + + set ams_attribute_id [ams::attribute::new -object_type $object_type \ + -attribute_name $attribute_name \ + -widget_name [lindex $attribute 1] \ + -pretty_name [lindex $attribute 2] \ + -pretty_plural [lindex $attribute 3] \ + -default_value [lindex $attribute 4] \ + -description [lindex $attribute 5] \ + -no_complain] + + if { ![exists_and_not_null ams_attribute_id] && $reset_order_p } { + set ams_attribute_id [ams::attribute::get_ams_attribute_id $object_type $attribute_name] + } + if { [lindex $attribute 6] == "required" } { + set required_p "t" + } else { + set required_p "f" + } + if { [exists_and_not_null ams_attribute_id] } { + ams::list::attribute_map -list_id $list_id \ + -ams_attribute_id $ams_attribute_id \ + -required_p $required_p + } + } +} + + +ad_proc -public ams::define_attributes { object_type attributes } { + TODO: Need Documentation + TODO: Verify the attributes passed in + + @param object_type the acs object_type these attributes are to belong to + @param attributes An array of attributes, if the attribute exists for this object this proc will make sure a duplicate is not created + + @see ams::define_list + + + + + + + + +

+ This Procedure implements a high level declarative syntax for the generation of ams_attributes + and attribute lists. Those attribute lists can then be used to create ad_form elements, columns + in a listbuilder array or via your own custom choosing by integrating with an ams generated + multirow that you can use however you want in your package. +

+

+

+
+ + Here is an example of the ams::define_list proc used by the contacts package: + +
+    ams::define_list contact_person_ae "The Fields used to Add/Edit a Contact Person" contacts ct_contact {
+        {first_names textbox {First Name(s)} {First Names} {} {} required}
+        {middle_names textbox {Middle Name(s)} {Middle Names} {} {}}
+        {last_name textbox {Last Name} {Last Names} {} {} required}
+        {email email {Email Address} {Email Addresses} {} {}}
+        {url url {Website} {Websites} {} {}}
+        {home_address address {Home Address} {Home Addresses}}
+        {organization_address address {Organization Address} {Organization Addresses}}
+    }
+    
+ + +

+ + Some form builder datatypes build values that do not directly correspond to database types. When using + the form builder directly these are converted by calls to datatype::get_property and datatype::acquire. + When using ad_form, "to_html(property)", "to_sql(property)" and "from_sql(property)" declare the appropriate + properties to be retrieved or set before calling code blocks that require the converted values. The "to_sql" + operation is performed before any on_submit, new_data or edit_data block is executed. The "from_sql" operation + is performed after a select_query or select_query_name query is executed. No automatic conversion is performed + for edit_request blocks (which manually set form values). The "to_html" operation is performed before execution + of a confirm template. + +

+ + Currently only the date and currency datatypes require these conversion operations. + +

+ + In the future the form builder will be enhanced so that ad_form can determine the proper conversion operation + automatically, freeing the programmer from the need to specify them. When this is implemented the current notation + will be retained for backwards compatibility. + +

+ + +} { + set returner "" + foreach { attribute } $attributes { + # the attribute follows this order + # attribute_name widget_name pretty_name pretty_plural default_value description + + ams::attribute::new -object_type $object_type \ + -attribute_name [lindex $attribute 0] \ + -widget_name [lindex $attribute 1] \ + -pretty_name [lindex $attribute 2] \ + -pretty_plural [lindex $attribute 3] \ + -default_value [lindex $attribute 4] \ + -description [lindex $attribute 5] \ + -no_complain + + } + return $returner +} + +ad_proc -public ams::package_id {} { + + Get the package_id of the ams instance + + @return package_id + +} { + return [ad_conn package_id] +} + + +ad_proc -public ams::lang_key_encode { + {-len "175"} + string +} { + @param len the default value was chosen because the lang key length must be less than 200 due to a character limit on the lang_messages.message_key column and because ams depends on using some of that length for key definitions. + + @return an acs_lang encoded message key string +} { + # we add the space at the end to prevent ellipsis at the and then remove it with string trim in order to prevent ellipsis + return [string trim [string_truncate -len [expr $len + 1] -ellipsis " " [ad_urlencode $string]]] +} + + +namespace eval ams::option {} + + + +ad_proc -public ams::option::new { + {-ams_attribute_id:required} + {-option:required} + {-locale ""} + {-sort_order ""} +} { + Create a new ams option for an attribute + + TODO validate that the attribute is in fact one that accepts options.
+ TODO auto input sort order if none is supplied
+ TODO validate that option from the the string input from ams::lang_key_encode is equal to a pre-existing ams message if it is we need conflict resolution. + + @param ams_attribute_id + @param option This a pretty name option + @param locale This is the locale the option name is in + @param sort_order if null, this option will be sorted after last previously entered option for this attribute + + @return option_id +} { + + set lang_key "ams.option:[ams::lang_key_encode $option]" + _mr en $lang_key $option + set option $lang_key + + return [db_exec_plsql ams_option_new {}] +} + + +ad_proc -public ams::option::delete { + {-option_id:required} +} { + Delete an ams option + + @param option_id +} { + db_exec_plsql ams_option_delete {} +} + + +ad_proc -public ams::option::map { + {-option_map_id ""} + {-option_id:required} +} { + Map an ams option for an attribute to an option_map_id, if no value is supplied for option_map_id a new option_map_id will be created. + + @param option_map_id + @param option_id + + @return option_map_id +} { + return [db_exec_plsql ams_option_map {}] +} + + +namespace eval ams::attribute {} + +ad_proc -public ams::attribute::widget { + {-required:boolean} + ams_attribute_id +} { + @return an ad_form encoded attribute widget +} { + set attribute_widget [ams::attribute::widget_cached $ams_attribute_id] + + if { [string is false $required_p] } { + # we need to add the optional flag + set optional_attribute_widget "" + set i "0" + while { $i < [llength $attribute_widget] } { + if { $i == "0" } { + # it is the first element in the list, so we add optional + lappend optional_attribute_widget "[lindex $attribute_widget $i],optional" + } else { + # this is not the first element in the list so we simple add + # it back to the list + lappend optional_attribute_widget [lindex $attribute_widget $i] + } + incr i + } + set attribute_widget $optional_attribute_widget + } + + return $attribute_widget + +} + +ad_proc -private ams::attribute::widget_not_cached { ams_attribute_id } { + Returns an ad_form encoded attribute widget list, as used by other procs. + @see ams::attribute::widget_cached +} { + db_1row select_attribute {} + + set attribute_widget "${attribute_name}:${datatype}(${widget})" + + lappend attribute_widget [list "label" "\#${pretty_name}\#"] + + if { [exists_and_not_null parameters] } { + # the parameters are already stored in list format + # in the database so we just add them to the list + append attribute_widget " ${parameters}" + } + + if { $storage_type == "ams_options" } { + set options [list "options" [db_list_of_lists select_options {}]] + append attribute_widget " ${options}" + } +# ns_log debug "attribute used: $attribute_widget" + return $attribute_widget + +} + +ad_proc -private ams::attribute::widget_cached { ams_attribute_id } { + Returns an ad_form encoded attribute widget list, as used by other procs. Cached. + @see ams::attribute::widget_not_cached +} { + return [util_memoize [list ams::attribute::widget_not_cached $ams_attribute_id]] +} + + + + + + + + +ad_proc -private ams::attribute::exists_p { object_type attribute_name } { + + does an attribute with this given attribute_name for this object type exists? + + @return 1 if the attribute_name exists for this object_type and 0 if the attribute_name does not exist +} { + if { [string is true [db_0or1row attribute_exists_p {}]] } { + return 1 + } else { + return 0 + } +} + + +ad_proc -private ams::attribute::get_ams_attribute_id { object_type attribute_name } { + + return the ams_attribute_id for the given ams_attriubte_name belonging to this object_type + + @return ams_attribute_id if none exists then it returns blank +} { + + return [db_string get_ams_attribute_id {} -default {}] +} + +ad_proc -public ams::attribute::new { + {-ams_attribute_id ""} + {-object_type:required} + {-attribute_name:required} + {-pretty_name:required} + {-pretty_plural:required} + {-default_value ""} + {-description ""} + {-widget_name:required} + {-deprecated:boolean} + {-context_id ""} + {-no_complain:boolean} +} { + create a new ams_attribute + +

widget_name

+

+ This should be a widget_name used by ams. Currently the valid widget names are: +
+       Text Widgets
+       ------------
+
+       textbox (shorthand for textbox_medium)
+       textbox_small
+       textbox_medium
+       textbox_large
+
+       textarea (shorthand for textarea_medium)
+       textarea_small
+       textarea_small_nospell
+       textarea_medium
+       textarea_large
+
+       richtext (shorthand for richtext_medium)
+       richtext_medium
+       richtext_large
+
+
+       Telephone Widgets
+       -----------------
+
+       phone (shorthand for telecom_number)
+       telecom_number
+
+       Postal Address Widgets
+       ----------------------
+
+       address (shorthand for postal_address)
+       postal_address
+
+
+       Multiple Choice Widgets
+       -----------------------
+
+       select             (one option allowed)
+       radio              (one option allowed)
+       checkbox           (multiple options allowed)
+       multiselect        (multiple options allowed)
+       multiselect_single (one option allowed)
+       
+
+       Other Widgets
+       -------------
+    
+       date
+       integer
+       number
+       email
+       url
+       
+
+ + + + @param context_id defaults to package_id + @param no_complain silently ignore attributes that already exist. + @return ams_attribute_id +} { + + switch $widget_name { + textbox { set widget_name "textbox_medium" } + textarea { set widget_name "textarea_medium" } + richtext { set widget_name "richtext_medium" } + address { set widget_name "postal_address" } + phone { set widget_name "telecom_number" } + } + + if { [ams::attribute::exists_p $object_type $attribute_name] } { + if { !$no_complain_p } { + error "Attribute $attribute_name Already Exists" "The attribute \"$attribute_name\" already exists for object_type \"$object_type\"" + } else { + return {} + } + } else { + set lang_key "ams.$object_type\:$attribute_name\:" + set pretty_name_key "$lang_key\pretty_name" + set pretty_plural_key "$lang_key\pretty_plural" + # register lang messages + _mr en $pretty_name_key $pretty_name + _mr en $pretty_plural_key $pretty_plural + + set pretty_name $pretty_name_key + set pretty_plural $pretty_plural_key + + + if { [exists_and_not_null description] } { + set description_key "$lang_key\description" + # register lang messages + _mr en $description_key $description + set description $description_key + } + + + if { [empty_string_p $context_id] } { + set context_id [ams::package_id] + } + set extra_vars [ns_set create] + oacs_util::vars_to_ns_set -ns_set $extra_vars -var_list {ams_attribute_id object_type attribute_name pretty_name pretty_plural default_value description widget_name deprecated_p context_id} + set ams_attribute_id [package_instantiate_object -extra_vars $extra_vars ams_attribute] + + return $ams_attribute_id + } +} + + +ad_proc -private ams::attribute::name_not_cached { ams_attribute_id } { + get the name of an ams_attribute + + @return attribute_name + + @see ams::attribute::name + @see ams::attribute::name_flush +} { + return [db_string ams_attribute_name {}] +} + + +ad_proc -public ams::attribute::name { ams_attribute_id } { + get the name of an ams_attribute. Cached. + + @return attribute pretty_name + + @see ams::attribute::name_not_cached + @see ams::attribute::name_flush +} { + return [util_memoize [list ams::attribute::name_not_cached $ams_attribute_id]] +} + + +ad_proc -private ams::attribute::name_flush { ams_attribute_id } { + Flush the storage_type of an ams_attribute. + + @return attribute pretty_name + + @see ams::attribute::name_not_cached + @see ams::attribute::name_flush +} { + util_memoize_flush [list ams::attribute::name_not_cached -ams_attribute_id $ams_attribute_id] +} + + +ad_proc -public ams::attribute::delete { + {-ams_attribute_id:required} +} { + Delete an ams attribute, and all associated attribute values + + @param option_id +} { + db_exec_plsql ams_attribute_delete {} +} + + +ad_proc -private ams::attribute::storage_type_not_cached { ams_attribute_id } { + get the storage_type of an ams_attribute + + @return storage_type + + @see ams::attribute::storage_type + @see ams::attribute::storage_type_flush +} { + return [db_string ams_attribute_storage_type {}] +} + + +ad_proc -public ams::attribute::storage_type { ams_attribute_id } { + get the storage_type of an ams_attribute. Cached. + + @return attribute pretty_name + + @see ams::attribute::storage_type_not_cached + @see ams::attribute::storage_type_flush +} { + return [util_memoize [list ams::attribute::storage_type_not_cached $ams_attribute_id]] +} + + +ad_proc -private ams::attribute::storage_type_flush { ams_attribute_id } { + Flush the storage_type of a cached ams_attribute. + + @return attribute pretty_name + + @see ams::attribute::storage_type_not_cached + @see ams::attribute::storage_type_flush +} { + util_memoize_flush [list ams::attribute::storage_type_not_cached -ams_attribute_id $ams_attribute_id] +} + +ad_proc -public ams::attribute::value { object_id ams_attribute_id } { + this code returns the cached attribute value for a specific ams_attribute +} { + set attribute_values_and_ids [ams::object::attributes::list_format $object_id] + set attribute_value "" + foreach attribute_value_and_id $attribute_values_and_ids { + if { [lindex $attribute_value_and_id 0] == $ams_attribute_id } { + set attribute_value [lindex $attribute_value_and_id 1] + } + } + return $attribute_value +} + +ad_proc -public ams::attribute::value_from_name { object_id object_type attribute_name } { + this code returns the cached attribute value for a specific ams_attribute +} { + return [ams::attribute::value $object_id [ams::attribute::get_ams_attribute_id $object_type $attribute_name]] +} + + +namespace eval ams::attribute::value {} + +ad_proc -public ams::attribute::value::new { + revision_id + ams_attribute_id + attribute_value +} { + this code saves attributes input in a form +} { + set storage_type [ams::attribute::storage_type $ams_attribute_id] + set option_map_id "" + set address_id "" + set number_id "" + set time "" + set value "" + set value_mime_type "" + + switch $storage_type { + telecom_number { + # i'm not using the telecom_number plsql code here + # since it creates unnecessary permissions by explicitly + # granting the address creation_user admin rights, This + # is taken care of the the ams_attribute permissions. + # + # plus we want this info to be the bound to the revision_id + # not the associated address_id so we pull it from the database + set itu_id [template::util::telecom_number::get_property itu_id $attribute_value] + set national_number [template::util::telecom_number::get_property national_number $attribute_value] + set area_city_code [template::util::telecom_number::get_property area_city_code $attribute_value] + set subscriber_number [template::util::telecom_number::get_property subscriber_number $attribute_value] + set extension [template::util::telecom_number::get_property extension $attribute_value] + set sms_enabled_p [template::util::telecom_number::get_property sms_enabled_p $attribute_value] + set best_contact_time [template::util::telecom_number::get_property best_contact_time $attribute_value] + set location [template::util::telecom_number::get_property location $attribute_value] + set phone_type_id [template::util::telecom_number::get_property phone_type_id $attribute_value] + + set number_id [db_string create_telecom_object {}] + + db_dml create_telecom_number {} + + } + + postal_address { + # i'm not using the postal_address plsql code here + # since it creates unnecessary permissions by explicitly + # granting the address creation_user admin rights, This + # is taken care of the the ams_attribute permissions. + # + # plus we want this info to be the bound to the revision_id + # not the associated address_id so we pull it from the database + set delivery_address [template::util::address::get_property delivery_address $attribute_value] + set postal_code [template::util::address::get_property postal_code $attribute_value] + set municipality [template::util::address::get_property municipality $attribute_value] + set region [template::util::address::get_property region $attribute_value] + set country_code [template::util::address::get_property country_code $attribute_value] + set additional_text [template::util::address::get_property additional_text $attribute_value] + set postal_type [template::util::address::get_property postal_type $attribute_value] + + set address_id [db_string create_postal_address_object {}] + + db_dml create_postal_address {} + } + + ams_options { + } + + time { + set value $attribute_value + } + + value { + set value $attribute_value + } + + value_with_mime_type { + set value [template::util::richtext::get_property contents $attribute_value] + set value_mime_type [template::util::richtext::get_property format $attribute_value] + } + } + + db_dml insert_attribute_value {} +} + + +ad_proc -public ams::attribute::value::superseed { + revision_id + ams_attribute_id + ams_object_id +} { + superseed an attribute value +} { + db_dml superseed_attribute_value {} +} + + + + + +namespace eval ams::object {} + +namespace eval ams::object::attribute {} + +ad_proc -private ams::object::attribute::value_memoize { object_id ams_attribute_id attribute_value } { + memoize an ams::object::attribute::value +} { + if { [string is true [util_memoize_cached_p [list ams::object::attribute::values_not_cached $object_id]]] } { + array set $object_id [util_memoize [list ams::object::attribute::values_not_cached $object_id]] + } + # if a value previously existed it will be superseeded + set ${object_id}($ams_attribute_id) $attribute_value + util_memoize_seed [list ams::object::attribute::values_not_cached $object_id] [array get ${object_id}] +} + +ad_proc -public ams::object::attribute::value { + object_id + ams_attribute_id +} { +} { + ams::object::attribute::values -array $object_id $object_id + if { [info exists ${object_id}($ams_attribute_id)] } { + return ${object_id}($ams_attribute_id) + } else { + return {} + } +} + +ad_proc -public ams::object::attribute::values { + {-names:boolean} + {-varenv:boolean} + {-array ""} + object_id +} { + @param names - if specified we will convert ams_attribute_id to the attribute_name + @param array - if specified the attribute values are returned in the given array + @param varenv - if sepecified the attribute values vars are returned to the calling environment + + if neither array nor varnames are specified then a list is returned +} { + set attribute_values_list [util_memoize [list ams::object::attribute::values_not_cached $object_id]] + if { $names_p } { + set attribute_values_list_with_names "" + foreach { key value } $attribute_values_list { + lappend attribute_values_list_with_names [ams::attribute::name $key] + lappend attribute_values_list_with_names $value + } + set attribute_values_list $attribute_values_list_with_names + } + if { [exists_and_not_null array] } { + upvar $array row + array set row $attribute_values_list + } elseif { $varenv_p } { + set attribute_value_info [ns_set create] + foreach { key value } $attribute_values_list { + ns_set put $attribute_value_info $key $value + } + # Now, set the variables in the caller's environment + ad_ns_set_to_tcl_vars -level 2 $attribute_value_info + ns_set free $attribute_value_info + } else { + return $attribute_values_list + } +} + + +ad_proc -private ams::object::attribute::values_not_cached { object_id } { +} { + ams::object::attribute::values_batch_process $object_id + if { [string is true [util_memoize_cached_p [list ams::object::attribute::values_not_cached $object_id]]] } { + return [util_memoize [list ams::object::attribute::values_not_cached $object_id]] + } else { + return {} + } +} + + +ad_proc -private ams::object::attribute::values_flush { object_id } { +} { + return [util_memoize_flush [list ams::object::attribute::values_not_cached $object_id]] +} + + +ad_proc -private ams::object::attribute::values_batch_process { object_ids } { + @param object_ids a list of object_ids for which to save attributes in their respective caches. + get these objects attribute values in a list format +} { + set objects_to_cache "" + foreach object_id_from_list $object_ids { + if { [string is false [util_memoize_cached_p [list ams::object::attribute::values $object_id_from_list]]] } { + lappend objects_to_cache $object_id_from_list + } + } + if { [exists_and_not_null objects_to_cache] } { + set sql_object_id_list [ams::util::sqlify_list $objects_to_cache] + db_foreach get_attr_values "" { + switch [ams::attribute::storage_type $ams_attribute_id] { + telecom_number { + set attribute_value $telecom_number_string + } + postal_address { + set attribute_value $address_string + } + ams_options { + set attribute_value "" + } + time { + set attribute_value $time + } + value { + set attribute_value $value + } + value_with_mime_type { + set attribute_value [list $value $value_mime_type] + } + } + set ${object_id}($ams_attribute_id) $attribute_value + } + foreach object_id_from_list $object_ids { + util_memoize_seed [list ams::object::attribute::values_not_cached $object_id_from_list] [array get ${object_id}] + } + } +} + + + +namespace eval ams::object::revision {} + + +ad_proc -public ams::object::revision::new { + {-package_id ""} + object_id +} { + create a new ams_object_revision + + @return revision_id +} { + if { [empty_string_p $package_id] } { + set package_id [ams::package_id] + } + set extra_vars [ns_set create] + oacs_util::vars_to_ns_set -ns_set $extra_vars -var_list { object_id package_id } + set revision_id [package_instantiate_object -extra_vars $extra_vars ams_object_revision] + + return $revision_id +} + + + + + + + + + + + + +namespace eval ams::list {} + +ad_proc -private ams::list::ams_attribute_ids_not_cached { list_id } { + Get a list of ams_attributes. + + @return list of ams_attribute_ids, in the correct order + + @see ams::list::ams_attribute_ids + @see ams::list::ams_attribute_ids_flush +} { + return [db_list ams_attribute_name {}] +} + +ad_proc -private ams::list::ams_attribute_ids { list_id } { + get this lists ams_attribute_ids. Cached. + + @return list of ams_attribute_ids, in the correct order + + @see ams::list::ams_attribute_ids_not_cached + @see ams::list::ams_attribute_ids_flush +} { + return [util_memoize [list ams::list::ams_attribute_ids_not_cached $list_id]] +} + +ad_proc -private ams::list::ams_attribute_ids_flush { list_id } { + Flush this lists ams_attribute_ids cache. + + @return list of ams_attribute_ids, in the correct order + + @see ams::list::ams_attribute_ids_not_cached + @see ams::list::ams_attribute_ids +} { + return [util_memoize_flush [list ams::list::ams_attribute_ids_not_cached $list_id]] +} + + + +ad_proc -private ams::list::exists_p { short_name package_key object_type } { + + does an ams list like this exist? + + @return 1 if the list exists for this object_type and package_key and 0 if the does not exist +} { + if { [string is true [db_0or1row list_exists_p {}]] } { + return 1 + } else { + return 0 + } +} + + +ad_proc -private ams::list::get_list_id { short_name package_key object_type } { + + return the list_id for the given parameters + + @return list_id if none exists then it returns blank +} { + + return [db_string get_list_id {} -default {}] +} + + + +ad_proc -public ams::list::new { + {-list_id ""} + {-short_name:required} + {-pretty_name:required} + {-object_id ""} + {-package_key:required} + {-object_type:required} + {-description ""} + {-description_mime_type "text/plain"} + {-context_id ""} +} { + create a new ams_group + + @return group_id +} { + if { [empty_string_p $context_id] } { + set context_id [ams::package_id] + } + if { ![exists_and_not_null description] } { + set description_mime_type "" + } + set lang_key "ams.$package_key\:$object_type\:$short_name" + _mr en $lang_key $pretty_name + set pretty_name $lang_key + + if { [exists_and_not_null description] } { + set lang_key "ams.$package_key\:$object_type\:$short_name\:description" + _mr en $lang_key $description + set description $lang_key + + } + + set extra_vars [ns_set create] + oacs_util::vars_to_ns_set -ns_set $extra_vars -var_list { list_id short_name pretty_name object_id package_key object_type description description_mime_type } + set list_id [package_instantiate_object -extra_vars $extra_vars ams_list] + + return $list_id +} + + + +ad_proc -public ams::list::attribute_map { + {-list_id:required} + {-ams_attribute_id:required} + {-sort_order ""} + {-required_p "f"} + {-section_heading ""} +} { + Map an ams option for an attribute to an option_map_id, if no value is supplied for option_map_id a new option_map_id will be created. + + @param sort_order if null then the attribute will be placed as the last attribute in this groups sort order + + @return option_map_id +} { + return [db_exec_plsql ams_list_attribute_map {}] +} + + + + + + + + + + + + + + + +namespace eval ams::util {} + + + +ad_proc -public ams::util::sqlify_list { + variable_list +} { + set output_list {} + foreach item $variable_list { + if { [exists_and_not_null output_list] } { + append output_list ", " + } + append output_list "'$item'" + } + return $output_list +} Index: openacs-4/packages/ams/tcl/telecom-number-widget-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/tcl/telecom-number-widget-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/tcl/telecom-number-widget-procs.tcl 20 Oct 2004 21:40:02 -0000 1.1 @@ -0,0 +1,384 @@ +ad_library { + + Telecom_Number input widget and datatype for the OpenACS templating system. + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-09-28 + @cvs-id $Id: telecom-number-widget-procs.tcl,v 1.1 2004/10/20 21:40:02 matthewg Exp $ + +} + +namespace eval template {} +namespace eval template::data {} +namespace eval template::data::transform {} +namespace eval template::data::validate {} +namespace eval template::util {} +namespace eval template::util::telecom_number {} +namespace eval template::widget {} + +ad_proc -public template::util::telecom_number { command args } { + Dispatch procedure for the telecom_number object +} { + eval template::util::telecom_number::$command $args +} + +ad_proc -public template::util::telecom_number::create { + {itu_id {}} + {national_number {}} + {area_city_code {}} + {subscriber_number {}} + {extension {}} + {sms_enabled_p {}} + {best_contact_time {}} + {location {}} + {phone_type_id {}} +} { + return [list $itu_id $national_number $area_city_code $subscriber_number $extension $sms_enabled_p $best_contact_time] +} + +ad_proc -public template::util::telecom_number::html_view { + {itu_id {}} + {national_number {}} + {area_city_code {}} + {subscriber_number {}} + {extension {}} + {sms_enabled_p {}} + {best_contact_time {}} + {location {}} + {phone_type_id {}} +} { + set telecom_number "$national_number $area_city_code-$subscriber_number\x$extension" + return [ad_text_to_html $telecom_number] +} + +ad_proc -public template::util::telecom_number::acquire { type { value "" } } { + Create a new telecom_number value with some predefined value + Basically, create and set the telecom_number value +} { + set telecom_number_list [template::util::telecom_number::create] + return [template::util::telecom_number::set_property $type $telecom_number_list $value] +} + +ad_proc -public template::util::telecom_number::formats {} { + Returns a list of valid telecom_number formats +} { +# MGEDDERT NOTE: there needs to be a way to implement a way to portray telecom_numberes differently by country + return { US CA DE } +} + +ad_proc -public template::util::telecom_number::itu_codes {} { + Returns the country list. Cached. +} { + # This needs to be implemented if needed in the UI + return [util_memoize [list template::util::telecom_number::country_options_not_cached]] +} + +ad_proc -public template::util::telecom_number::itu_codes_not_cached {} { + Returns the country list. +} { + # This needs to be implemented if needed in the UI + return 0 +} + +ad_proc -public template::data::validate::telecom_number { value_ref message_ref } { + + upvar 2 $message_ref message $value_ref telecom_number_list + + set itu_id [template::util::telecom_number::get_property itu_id $telecom_number_list] + set national_number [template::util::telecom_number::get_property national_number $telecom_number_list] + set area_city_code [template::util::telecom_number::get_property area_city_code $telecom_number_list] + set subscriber_number [template::util::telecom_number::get_property subscriber_number $telecom_number_list] + set extension [template::util::telecom_number::get_property extension $telecom_number_list] + set sms_enabled_p [template::util::telecom_number::get_property sms_enabled_p $telecom_number_list] + set best_contact_time [template::util::telecom_number::get_property best_contact_time $telecom_number_list] + set location [template::util::telecom_number::get_property location $telecom_number_list] + set phone_type_id [template::util::telecom_number::get_property phone_type_id $telecom_number_list] + + set code_one_p [parameter::get -parameter "ForceCountryCodeOneFormatting" -default "0"] + if { !code_one_p } { + # we need to verify that the number is formatted correctly + # if yes we seperate the number into various elements + } + +# set fred_p [::string match {^[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]} $subscriber_number] + + ns_log Notice "regnum: $fred_p :$subscriber_number" +# set fred_p [::string match {[0-9][0-9][0-9]- +# [0-9][0-9][0-9]- +# [0-9][0-9][0-9][0-9]x +# [0-9]+? +# } $subscriber_number] + ns_log Notice "numwithext: $fred_p :$subscriber_number" + + set message_temp "" + # this is used to make sure there are no invalid characters in the telecom_number + set telecom_number_temp "$itu_id$national_number$area_city_code$subscriber_number$extension$sms_enabled_p$best_contact_time" + # we can't use string match since this is containted within the template::data::validate:: namespace +# if { ![string is integer $telecom_number_temp] } { +# append message_temp " [_ ams.Telecom_numbers_must_only_contain_numbers_dashes_and_x_es]" +# } elseif { $national_number == "1" } { + append message_temp " [_ ams.Country_code_1_telecom_numbers_must_follow_the_AAA-BBB-CCCCxDDDD_format]" +# } else { +# append message_temp "int number" +# } + ns_log Notice "TCLEVEL: [info level]" + if { [exists_and_not_null message_temp] } { + set message [string trim $message_temp] + return 0 + } else { + return 1 + } +} + + +ad_proc -public template::data::transform::telecom_number { element_ref } { + + upvar $element_ref element + set element_id $element(id) + +# set contents [ns_queryget $element_id] +# set format [ns_queryget $element_id.format] + + set itu_id [ns_queryget $element_id.itu_id] + set national_number [ns_queryget $element_id.national_number] + set area_city_code [ns_queryget $element_id.area_city_code] + set subscriber_number [ns_queryget $element_id.subscriber_number] + set extension [ns_queryget $element_id.extension] + set sms_enabled_p [ns_queryget $element_id.sms_enabled_p] + set best_contact_time [ns_queryget $element_id.best_contact_time] + set location [ns_queryget $element_id.location] + set phone_type_id [ns_queryget $element_id.phone_type_id] + + # we need to seperate out the returned value into individual elements + set number [ns_queryget $element_id.summary_number] +# if { [parameter::get -parameter "ForceCountryCodeOneFormatting" -default "0"] } { + # set need to seperate number into elements - if the formatting is correct +# set number_main [lindex [split $number "x"] 0] +# set number_extension [lindex [split $number "x"] 1] +# set fred_p [string match {[0-9]{1,}?} $number_extension] +# set subscriber_number $number +# } else { + set subscriber_number $number +# } + + if { [empty_string_p $subscriber_number] } { + # We need to return the empty list in order for form builder to think of it + # as a non-value in case of a required element. + return [list] + } else { + return [list [list $itu_id $national_number $area_city_code $subscriber_number $extension $sms_enabled_p $best_contact_time $location $phone_type_id]] + } +} + +ad_proc -public template::util::telecom_number::set_property { what telecom_number_list value } { + Set a property of the telecom_number datatype. + + @param what One of + + + @param telecom_number_list the telecom_number list to modify + @param value the new value + + @return the modified list +} { + + set itu_id [template::util::telecom_number::get_property itu_id $telecom_number_list] + set subscriber_number [template::util::telecom_number::get_property subscriber_number $telecom_number_list] + set national_number [template::util::telecom_number::get_property national_number $telecom_number_list] + set area_city_code [template::util::telecom_number::get_property area_city_code $telecom_number_list] + set extension [template::util::telecom_number::get_property extension $telecom_number_list] + set sms_enabled_p [template::util::telecom_number::get_property sms_enabled_p $telecom_number_list] + set best_contact_time [template::util::telecom_number::get_property best_contact_time $telecom_number_list] + set location [template::util::telecom_number::get_property location $telecom_number_list] + set phone_type_id [template::util::telecom_number::get_property phone_type_id $telecom_number_list] + + switch $what { + itu_id { + return [list $value $national_number $area_city_code $subscriber_number $extension $sms_enabled_p $best_contact_time $location $phone_type_id] + } + national_number { + return [list $itu_id $value $area_city_code $subscriber_number $extension $sms_enabled_p $best_contact_time $location $phone_type_id] + } + area_city_code { + return [list $itu_id $national_number $value $subscriber_number $extension $sms_enabled_p $best_contact_time $location $phone_type_id] + } + subscriber_number { + return [list $itu_id $national_number $area_city_code $value $extension $sms_enabled_p $best_contact_time $location $phone_type_id] + } + extension { + return [list $itu_id $national_number $area_city_code $subscriber_number $value $sms_enabled_p $best_contact_time $location $phone_type_id] + } + sms_enabled_p { + return [list $itu_id $national_number $area_city_code $subscriber_number $extension $value $best_contact_time $location $phone_type_id] + } + best_contact_time { + return [list $itu_id $national_number $area_city_code $subscriber_number $extension $sms_enabled_p $value $location $phone_type_id] + } + location { + return [list $itu_id $national_number $area_city_code $subscriber_number $extension $sms_enabled_p $best_contact_time $value $phone_type_id] + } + phone_type_id { + return [list $itu_id $national_number $area_city_code $subscriber_number $extension $sms_enabled_p $best_contact_time $location $value] + } + default { + error "Parameter supplied to util::telecom_number::set_property 'what' must be one of: 'itu_id', 'subscriber_number', 'national_number', 'area_city_code', 'extension', 'sms_enabled_p', 'best_contact_time', 'location', 'phone_type_id'. You specified: '$what'." + } + } +} + +ad_proc -public template::util::telecom_number::get_property { what telecom_number_list } { + + Get a property of the telecom_number datatype. Valid properties are: + + @param what the name of the property. Must be one of: + + @param telecom_number_list a telecom_number datatype value, usually created with ad_form. +} { + + switch $what { + itu_id { + return [lindex $telecom_number_list 0] + } + national_number { + return [lindex $telecom_number_list 1] + } + area_city_code { + return [lindex $telecom_number_list 2] + } + subscriber_number { + return [lindex $telecom_number_list 3] + } + extension { + return [lindex $telecom_number_list 4] + } + sms_enabled_p { + return [lindex $telecom_number_list 5] + } + best_contact_time { + return [lindex $telecom_number_list 6] + } + location { + return [lindex $telecom_number_list 7] + } + phone_type_id { + return [lindex $telecom_number_list 8] + } + html_view { + set itu_id [template::util::telecom_number::get_property itu_id $telecom_number_list] + set subscriber_number [template::util::telecom_number::get_property subscriber_number $telecom_number_list] + set national_number [template::util::telecom_number::get_property national_number $telecom_number_list] + set area_city_code [template::util::telecom_number::get_property area_city_code $telecom_number_list] + set extension [template::util::telecom_number::get_property extension $telecom_number_list] + set sms_enabled_p [template::util::telecom_number::get_property sms_enabled_p $telecom_number_list] + set best_contact_time [template::util::telecom_number::get_property best_contact_time $telecom_number_list] + set location [template::util::telecom_number::get_property location $telecom_number_list] + set phone_type_id [template::util::telecom_number::get_property phone_type_id $telecom_number_list] + return [template::util::telecom_number::html_view $itu_id $subscriber_number $national_number $area_city_code $extension $sms_enabled_p $best_contact_time $location $phone_type_id] + } + default { + error "Parameter supplied to util::telecom_number::get_property 'what' must be one of: 'itu_id', 'subscriber_number', 'national_number', 'area_city_code', 'extension', 'sms_enabled_p', 'best_contact_time', 'location', 'phone_type_id'. You specified: '$what'." + } + + } +} + +ad_proc -public template::widget::telecom_number { element_reference tag_attributes } { + Implements the telecom_number widget. + +} { + + upvar $element_reference element + +# if { [info exists element(html)] } { +# array set attributes $element(html) +# } + +# array set attributes $tag_attributes + + if { [info exists element(value)] } { + set itu_id [template::util::telecom_number::get_property itu_id $element(value)] + set subscriber_number [template::util::telecom_number::get_property subscriber_number $element(value)] + set national_number [template::util::telecom_number::get_property national_number $element(value)] + set area_city_code [template::util::telecom_number::get_property area_city_code $element(value)] + set extension [template::util::telecom_number::get_property extension $element(value)] + set sms_enabled_p [template::util::telecom_number::get_property sms_enabled_p $element(value)] + set best_contact_time [template::util::telecom_number::get_property best_contact_time $element(value)] + set location [template::util::telecom_number::get_property location $element(value)] + set phone_type_id [template::util::telecom_number::get_property phone_type_id $element(value)] + } else { + set itu_id {} + set subscriber_number {} + set national_number {} + set area_city_code {} + set extension {} + set sms_enabled_p {} + set best_contact_time {} + set location {} + set phone_type_id {} + } + + set output {} + + if { [string equal $element(mode) "edit"] } { + + + + set attributes(id) \"telecom_number__$element(form_id)__$element(id)\" + set summary_number "" + if { [exists_and_not_null national_number] } { + if { $national_number != "1" } { + append summary_number "011-$national_number" + } + } + if { [exists_and_not_null area_city_code] } { + if { [exists_and_not_null summary_number] } { append summary_number "-" } + append summary_number $area_city_code + } + if { [exists_and_not_null subscriber_number] } { + if { [exists_and_not_null summary_number] } { append summary_number "-" } + append summary_number $subscriber_number + } + if { [exists_and_not_null extension] } { + if { [exists_and_not_null summary_number] } { append summary_number "x" } + append summary_number $extension + } +# set summary_number "$national_number\-$area_city_code\-$subscriber_number\x$extension" + append output "" + + } else { + # Display mode + if { [info exists element(value)] } { + append output [template::util::telecom_number::get_property html_view $element(value)] + append output "" + append output "" + append output "" + append output "" + append output "" + append output "" + append output "" + append output "" + append output "" + } + } + + return $output +} Index: openacs-4/packages/ams/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/www/index.adp 20 Oct 2004 21:40:04 -0000 1.1 @@ -0,0 +1,15 @@ + +@title@ +@context@ + +

This is currently a testing page for the save and retrieval procs

+ +
+@attr_list@
+
+ + + + + + Index: openacs-4/packages/ams/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/ams/www/index.tcl 20 Oct 2004 21:40:04 -0000 1.1 @@ -0,0 +1,169 @@ +ad_page_contract { + + @author Matthew Geddert openacs@geddert.com + @creation-date 2004-07-28 + @cvs-id $Id: index.tcl,v 1.1 2004/10/20 21:40:04 matthewg Exp $ + + +} { +} + +ad_proc -public ams_ad_form_save { + {-name} + {-list_id} + {-object_id} +} { + this code saves attributes input in a form +} { + ams::object::attribute::values -array oldvalues $object_id + set ams_attribute_ids [ams::list::ams_attribute_ids $list_id] + foreach ams_attribute_id $ams_attribute_ids { + set storage_type [ams::attribute::storage_type $ams_attribute_id] + set attribute_name [ams::attribute::name $ams_attribute_id] + set attribute_value [template::element::get_value $name $attribute_name] + if { $storage_type == "ams_options" } { + set attribute_value [template::element::get_values $name $attribute_name] + } + if { [info exists oldvalues($ams_attribute_id)] } { + if { $attribute_value != $oldvalues($ams_attribute_id) } { + lappend variables $ams_attribute_id $attribute_value + } + } else { + if { [exists_and_not_null attribute_value] } { + lappend variables $ams_attribute_id $attribute_value + } + } + } + if { [exists_and_not_null variables] } { + ns_log Notice "$object_id changed vars: $variables" +# ams_attributes_save $object_id $variables + } + db_transaction { + ams::object::attribute::values_flush $object_id + set revision_id [ams::object::revision::new $object_id] + set ams_object_id [ams_object_id $object_id] + ams::attribute::value::superseed $revision_id $ams_attribute_id $ams_object_id + foreach { ams_attribute_id attribute_value } $variables { + if { [exists_and_not_null attribute_value] } { + ams::attribute::value::new $revision_id $ams_attribute_id $attribute_value + } + } + } + ams::object::attribute::values $object_id + return 1 +} + +ad_proc -public ams_attributes_save { + object_id + attribute_value_list +} { + this code saves attributes input in a form +} { + db_transaction { + set revision_id [ams::object::revision::new $object_id] + set ams_object_id [ams_object_id $object_id] + foreach attribute_id_value $attribute_value_list { + # TODO find those that need to be updated (since its cached) and put them in attribute_values_to_update + set ams_attribute_id [lindex $attribute_id_value 0] + set new_attribute_value [lindex $attribute_id_value 1] + set old_attribute_value [ams::attribute::value $object_id $ams_attribute_id] + ns_log Notice "AMS: $ams_attribute_id , old: $old_attribute_value , new: $new_attribute_value" + if { [string compare $old_attribute_value $new_attribute_value] != "0" } { +# ams::attribute::value::superseed $revision_id $ams_attribute_id $ams_object_id + } else { + if { [exists_and_not_null new_attribute_value] } { + ams::attribute::value::new $revision_id $ams_attribute_id $attribute_value + } + } + } + } + ams::object::attribute::values_flush $object_id + ams::object::attribute::values $object_id +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ad_proc -private ams_form { + {-name} + {-key} + {-list_id} + {-return_message} + {-return_url} +} { +} { + + ad_form \ + -name $name \ + -form [ams::ad_form::elements_from_list_id -key $key $list_id] \ + -edit_request { + ams::object::attribute::values -names -varenv $object_id + } -validate { + } -on_submit { + ams_ad_form_save -name $name -list_id $list_id -object_id $object_id + } -after_submit { + if { [exists_and_not_null $message] } { + ad_returnredirect $message $return_url + } else { + ad_returnredirect $return_url + } + } +} + + +set object_id 1931 + + +set title "Attribute Management System" +set context {} + +ad_form -name entry \ + -form [ams::ad_form::elements_from_list_id -key object_id 1935] + +ad_form -extend -name entry \ + -new_request { + } -edit_request { + ams::object::attribute::values -names -varenv $object_id + } -validate { + } -on_submit { + ams_ad_form_save -name entry -list_id 1935 -object_id $object_id + } -after_submit { + if { ![exists_and_not_null return_url] } { + set return_url "./" + } +# ad_returnredirect -message "[acs_object_name $object_id] Updated" $return_url +# ad_script_abort +# set attr_list [ams_ad_form_save -name entry -list_id 1935 -object_id $object_id] + + } + +#ams::object::attributes::flush $object_id +#set attr_list "" +set attr_list [ams::object::attribute::values -names $object_id] +#set attr_list $fred(last_name) + +ad_return_template