Index: openacs-4/packages/ams/ams.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/ams.info,v diff -u -r1.2 -r1.2.2.1 --- openacs-4/packages/ams/ams.info 30 Oct 2004 00:23:54 -0000 1.2 +++ openacs-4/packages/ams/ams.info 30 Nov 2005 16:21:52 -0000 1.2.2.1 @@ -8,23 +8,30 @@ t ams - + Matthew Geddert Store attributes via the Content Repository, and auto generate input forms + 2005-11-21 AMS (Attribute Management System) helps in customizing your website. It lets you adjust what information is collected and displayed for any package that is integrated with it. AMS allows you to easily and dynamically add attributes to forms and display pages, using a Tcl API or an admin interface. AMS uses the content repository to store attribute history for any object on the system. + 0 - + + - + + - + + + + 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 -r1.4 -r1.4.2.1 --- openacs-4/packages/ams/sql/postgresql/ams-create.sql 30 Oct 2004 00:23:54 -0000 1.4 +++ openacs-4/packages/ams/sql/postgresql/ams-create.sql 30 Nov 2005 16:21:52 -0000 1.4.2.1 @@ -10,58 +10,58 @@ ------ Widgets -------------------------------------------------------------------- +-- +-- each widget needs to have a ams::widget::${widget} proc associated with it +-- +-- the value_method is a reference to a proc that will convert the value_id into a useable string for +-- the tcl procs. If possible it is best to have a value_method, since this substantailly decreases +-- the number of trips that are needed to go the the database. See the example of widgets that come +-- with AMS for more details. -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) + widget 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) + value_method varchar(100), + active_p boolean ); - ------ 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, +create table ams_attribute_items ( 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, + constraint ams_attribute_items_attribute_id_fk references acs_attributes(attribute_id) + constraint ams_attribute_items_attribute_id_nn not null, + ams_attribute_id integer + constraint ams_attribute_items_ams_attribute_id_fk references acs_objects(object_id) + constraint ams_attribute_items_ams_attribute_id_pk primary key, + widget varchar(100) + constraint ams_attribute_items_widget_fk references ams_widgets(widget) + constraint ams_attribute_items_widget_nn not null, + dynamic_p boolean default 'f' + constraint ams_attribute_items_dynamic_p_nn not null, deprecated_p boolean default 'f' - constraint ams_attributes_deprecated_nn not null + constraint ams_attribute_items_deprecated_nn not null, + UNIQUE(attribute_id) ); +create view ams_attributes as + select acs_attributes.*, + ams_attribute_items.ams_attribute_id, + ams_attribute_items.widget, + ams_attribute_items.dynamic_p, + ams_attribute_items.deprecated_p + from acs_attributes left join ams_attribute_items on ( acs_attributes.attribute_id = ams_attribute_items.attribute_id ); + select acs_object_type__create_type ( 'ams_attribute', -- object_type - 'AMS Attribute', -- pretty_name - 'AMS Attributes ', -- pretty_plural + '#ams.AMS_Attribute#', -- pretty_name + '#ams.AMS_Attributes#', -- pretty_plural 'acs_object', -- supertype - 'ams_attributes', -- table_name + 'ams_attribute_items', -- table_name 'ams_attribute_id', -- id_column 'ams_attribute', -- package_name 'f', -- abstract_p @@ -73,8 +73,8 @@ 'ams_attribute', -- object_type 'attribute_id', -- attribute_name 'integer', -- datatype - 'ACS Attribute ID', -- pretty_name - 'ACS Attribute IDs', -- pretty_plural -- default null + '#ams.ACS_Attribute_ID#', -- pretty_name + '#ams.ACS_Attribute_IDs#', -- pretty_plural -- default null null, -- table_name -- default null 'attribute_id', -- column_name -- default null null, -- default_value -- default null @@ -87,12 +87,12 @@ select acs_attribute__create_attribute ( 'ams_attribute', -- object_type - 'widget_name', -- attribute_name + 'widget', -- attribute_name 'string', -- datatype - 'Widget Name', -- pretty_name - 'Widget Name', -- pretty_plural -- default null + '#ams.Widget_1#', -- pretty_name + '#ams.Widgets#', -- pretty_plural -- default null null, -- table_name -- default null - 'widget_name', -- column_name -- default null + 'widget', -- column_name -- default null null, -- default_value -- default null '1', -- min_n_values -- default 1 '1', -- max_n_values -- default 1 @@ -101,12 +101,32 @@ null -- static_p -- default 'f' ); +-- if uninstalled we can delete acs_attributes dynamically created by +-- the ams ui. Howerver we cannot remove attributes added by other +-- packages because it could break those packages. + select acs_attribute__create_attribute ( 'ams_attribute', -- object_type + 'dynamic_p', -- attribute_name + 'boolean', -- datatype + '#ams.lt_Dynamic_added_by_AMS_#', -- pretty_name + '#ams.lt_Dynamic_added_by_AMS_#', -- 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' +); + +select acs_attribute__create_attribute ( + 'ams_attribute', -- object_type 'deprecated_p', -- attribute_name 'boolean', -- datatype - 'Deprecated', -- pretty_name - 'Deprecated', -- pretty_plural -- default null + '#ams.Deprecated#', -- pretty_name + '#ams.Deprecated#', -- pretty_plural -- default null null, -- table_name -- default null 'deprecated_p', -- column_name -- default null null, -- default_value -- default null @@ -118,104 +138,176 @@ ); ------- Objects + +------ Attribute Values -------------------------------------------------------------------- --- 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, +create table ams_attribute_values ( 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) + constraint ams_attribute_values_object_id_fk references acs_objects(object_id) + constraint ams_attribute_values_object_id_nn not null, + attribute_id integer + constraint ams_attribute_values_attribute_id_fk references acs_attributes(attribute_id) + constraint ams_attribute_values_attribute_id_nn not null, + value_id integer + constraint ams_attribute_values_nn not null ); -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 index ams_attribute_values_attribute_idx on ams_attribute_values(attribute_id); --- 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_seq; - replace with object key -create sequence ams_options_seq; -create table ams_options ( +create table ams_option_types ( 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), + constraint ams_options_option_id_fk references acs_objects(object_id) + constraint ams_options_option_id_pk primary key, + attribute_id integer + constraint ams_options_attribute_id_nn not null + constraint ams_options_attribute_id_nn references acs_attributes (attribute_id), option varchar(200) constraint ams_options_option_nn not null, sort_order integer constraint ams_options_sort_order not null, - unique (ams_attribute_id,sort_order) + deprecated_p boolean default 'f' + constraint ams_options_deprecated_nn not null, + unique (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 + +select acs_object_type__create_type ( + 'ams_option', -- object_type + '#ams.AMS_Option#', -- pretty_name + '#ams.AMS_Options#', -- pretty_plural + 'acs_object', -- supertype + 'ams_option_types', -- table_name + 'option_id', -- id_column + 'ams_option', -- package_name + 'f', -- abstract_p + null, -- type_extension_table + 'ams_option__name' -- name_method ); -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), +select acs_attribute__create_attribute ( + 'ams_option', -- object_type + 'attribute_id', -- attribute_name + 'integer', -- datatype + '#ams.AMS_Attribute_ID#', -- pretty_name + '#ams.AMS_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_option', -- object_type + 'option', -- attribute_name + 'string', -- datatype + '#ams.Option#', -- pretty_name + '#ams.Options#', -- pretty_plural -- default null + null, -- table_name -- default null + 'option', -- 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_option', -- object_type + 'sort_order', -- attribute_name + 'integer', -- datatype + '#ams.Sort_Order#', -- pretty_name + '#ams.Sort_Orders#', -- pretty_plural -- default null + null, -- table_name -- default null + 'sort_order', -- 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_option', -- object_type + 'deprecated_p', -- attribute_name + 'boolean', -- datatype + '#ams.Deprecated#', -- pretty_name + '#ams.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' +); + +create table ams_option_ids ( + value_id integer + constraint ams_options_map_ids_value_id_pk primary key +); + +create table ams_options ( + value_id integer + constraint ams_options_value_id_fk references ams_option_ids(value_id) + constraint ams_options_value_id_nn not null, option_id integer - constraint ams_option_map_option_id_fk references ams_options(option_id) - constraint ams_option_map_option_id_nn not null + constraint ams_option_option_id_fk references ams_option_types(option_id) + constraint ams_option_map_option_id_nn not null, + unique (value_id,option_id) ); +------ AMS Texts +-------------------------------------------------------------------- +-- use object_id sequence with object_id this allows +-- for future use of option values being converted into objects. ------- Attribute Values +create table ams_texts ( + value_id integer + constraint ams_texts_text_format_pk primary key, + text text + constraint ams_texts_text_format_nn not null, + text_format varchar(200) default 'text/plain' + constraint ams_texts_text_format_nn not null +); + +------ AMS Times -------------------------------------------------------------------- +-- use object_id sequence with object_id this allows +-- for future use of option values being converted into objects. +create table ams_times ( + value_id integer + constraint ams_times_id_pk primary key, + time timestamptz + constraint ams_times_time_nn not null +); -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) +------ AMS Numbers +-------------------------------------------------------------------- + +-- use object_id sequence with object_id this allows +-- for future use of option values being converted into objects. + +create table ams_numbers ( + value_id integer + constraint ams_numbers_id_pk primary key, + number numeric + constraint ams_numbers_number_nn not null ); @@ -252,8 +344,8 @@ select acs_object_type__create_type ( 'ams_list', -- object_type - 'AMS List', -- pretty_name - 'AMS Lists ', -- pretty_plural + '#ams.AMS_List#', -- pretty_name + '#ams.AMS_Lists#', -- pretty_plural 'acs_object', -- supertype 'ams_lists', -- table_name 'list_id', -- id_column @@ -267,8 +359,8 @@ 'ams_list', -- object_type 'package_key', -- attribute_name 'string', -- datatype - 'Package Key', -- pretty_name - 'Package Keys', -- pretty_plural -- default null + '#ams.Package_Key_1#', -- pretty_name + '#ams.Package_Keys#', -- pretty_plural -- default null null, -- table_name -- default null 'object_type', -- column_name -- default null null, -- default_value -- default null @@ -283,8 +375,8 @@ 'ams_list', -- object_type 'object_type', -- attribute_name 'string', -- datatype - 'Object Type', -- pretty_name - 'Object Types', -- pretty_plural -- default null + '#ams.Object_Type_1#', -- pretty_name + '#ams.Object_Types#', -- pretty_plural -- default null null, -- table_name -- default null 'object_type', -- column_name -- default null null, -- default_value -- default null @@ -299,8 +391,8 @@ 'ams_list', -- object_type 'list_name', -- attribute_name 'string', -- datatype - 'List Name', -- pretty_name - 'List Names', -- pretty_plural -- default null + '#ams.List_Name_1#', -- pretty_name + '#ams.List_Names#', -- pretty_plural -- default null null, -- table_name -- default null 'list_name', -- column_name -- default null null, -- default_value -- default null @@ -315,8 +407,8 @@ 'ams_list', -- object_type 'pretty_name', -- attribute_name 'string', -- datatype - 'Pretty Name', -- pretty_name - 'Pretty Names', -- pretty_plural -- default null + '#ams.Pretty_Name_1#', -- pretty_name + '#ams.Pretty_Names#', -- pretty_plural -- default null null, -- table_name -- default null 'pretty_name', -- column_name -- default null null, -- default_value -- default null @@ -331,8 +423,8 @@ 'ams_list', -- object_type 'description', -- attribute_name 'text', -- datatype - 'Description', -- pretty_name - 'Descriptions', -- pretty_plural -- default null + '#ams.Description#', -- pretty_name + '#ams.Descriptions#', -- pretty_plural -- default null null, -- table_name -- default null 'description', -- column_name -- default null null, -- default_value -- default null @@ -347,8 +439,8 @@ 'ams_list', -- object_type 'description_mime_type', -- attribute_name 'text', -- datatype - 'Description Mime Type', -- pretty_name - 'Descriptions Mime Types', -- pretty_plural -- default null + '#ams.lt_Description_Mime_Type#', -- pretty_name + '#ams.lt_Descriptions_Mime_Typ#', -- pretty_plural -- default null null, -- table_name -- default null 'description_mime_type', -- column_name -- default null null, -- default_value -- default null @@ -359,24 +451,25 @@ null -- static_p -- default 'f' ); -create sequence ams_list_attribute_sort_order_seq; +-- create sequence ams_list_attribute_sort_order_seq; create table ams_list_attribute_map ( - list_id integer + 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, + attribute_id integer + constraint ams_list_attribute_map_attribute_id_fk references acs_attributes(attribute_id) + constraint ams_list_attribute_map_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), + html_options varchar(1000), + UNIQUE(list_id,attribute_id), UNIQUE(list_id,sort_order) ); \i ams-package-create.sql -\i populate.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 -r1.3 -r1.3.2.1 --- openacs-4/packages/ams/sql/postgresql/ams-drop.sql 27 Oct 2004 02:04:18 -0000 1.3 +++ openacs-4/packages/ams/sql/postgresql/ams-drop.sql 30 Nov 2005 16:21:52 -0000 1.3.2.1 @@ -8,49 +8,20 @@ -- -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_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; - create or replace function inline_1 () returns varchar as ' declare rec RECORD; begin FOR rec IN - select address_id + select value_id from ams_attribute_values - where address_id is not null LOOP - delete from ams_attribute_values where address_id = rec.address_id; - PERFORM postal_address__del (rec.address_id); + delete from ams_attribute_values where address_id = rec.value_id; + PERFORM postal_address__del (rec.value_id); END LOOP; return ''All Postal Addresses associated with AMS have been deleted''; @@ -66,12 +37,12 @@ begin FOR rec IN - select number_id + select value_id from ams_attribute_values - where number_id is not null + where value_id is not null LOOP - delete from ams_attribute_values where number_id = rec.number_id; - PERFORM telecom_number__del (rec.number_id); + delete from ams_attribute_values where number_id = rec.value_id; + PERFORM telecom_number__del (rec.value_id); END LOOP; @@ -82,22 +53,34 @@ drop function inline_2(); +delete from ams_attribute_values; +select ams_attribute__delete(attribute_id) + from ams_attributes + where ams_attribute_id is not null; +select drop_package('ams_option'); +select drop_package('ams_attribute'); +select drop_package('ams_list'); +select drop_package('ams_value'); +select drop_package('ams_widget'); + -- select acs_object__delete(address_id) from ams_attribute_values where address_id is not null; -- select acs_object__delete(number_id) from ams_attribute_values where number_id is not null; +drop table ams_list_attribute_map; +drop table ams_lists; +drop table ams_options; +drop table ams_option_ids; +drop table ams_numbers; +drop table ams_times; +drop table ams_texts; +drop table ams_option_types; +drop table ams_attribute_values; +drop view ams_attributes; +drop table ams_attribute_items; +drop table ams_widgets; -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'); +delete from acs_objects where object_type in ('ams_attribute','ams_list','ams_option'); select acs_object_type__drop_type('ams_attribute','f'); +select acs_object_type__drop_type('ams_list','f'); +select acs_object_type__drop_type('ams_option','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 -r1.4 -r1.4.2.1 --- openacs-4/packages/ams/sql/postgresql/ams-package-create.sql 27 Oct 2004 02:04:18 -0000 1.4 +++ openacs-4/packages/ams/sql/postgresql/ams-package-create.sql 30 Nov 2005 16:21:52 -0000 1.4.2.1 @@ -6,63 +6,73 @@ -- @cvs-id $Id$ -- -- +-- object_id | integer | not null +-- object_type | character varying(100) | not null +-- context_id | integer | +-- security_inherit_p | boolean | not null default true +-- creation_user | integer | +-- creation_date | timestamp with time zone | not null default ('now'::text)::timestamp(6) with time zone +-- creation_ip | character varying(50) | +-- last_modified | timestamp with time zone | not null default ('now'::text)::timestamp(6) with time zone +-- modifying_user | integer | +-- modifying_ip | character varying(50) | +-- tree_sortkey | bit varying | not null +-- max_child_sortkey | bit varying | - ------- Attributes +------ Widgets -------------------------------------------------------------------- +create or replace function ams_widget__save (varchar,varchar,varchar,boolean) +returns integer as ' +declare + p_widget alias for $1; + p_pretty_name alias for $2; + p_value_method alias for $3; + p_active_p alias for $4; + v_exists_p boolean; +begin + v_exists_p := ''1'' from ams_widgets where widget = p_widget; + if v_exists_p then -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'); + update ams_widgets + set pretty_name = p_pretty_name, + value_method = p_value_method, + active_p = p_active_p + where widget = p_widget; -create or replace function ams_attribute__new (integer,varchar,varchar,varchar,varchar,varchar,text,varchar,boolean,timestamptz,integer,varchar,integer) + else + insert into ams_widgets + (widget,pretty_name,value_method,active_p) + values + (p_widget,p_pretty_name,p_value_method,p_active_p); + end if; + + return ''1''; +end;' language 'plpgsql'; + + + +------ Attributes +-------------------------------------------------------------------- + +select define_function_args('ams_attribute__new','attribute_id,ams_attribute_id,widget,dynamic_p;f,deprecated_p;f,creation_date;now(),creation_user,creation_ip,context_id'); + +create or replace function ams_attribute__new (integer,integer,varchar,boolean,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; + p_attribute_id alias for $1; + p_ams_attribute_id alias for $2; -- the Permissable AMS Attribute ID + p_widget alias for $3; + p_dynamic_p alias for $4; + p_deprecated_p alias for $5; + p_creation_date alias for $6; + p_creation_user alias for $7; + p_creation_ip alias for $8; + p_context_id alias for $9; v_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'', @@ -72,10 +82,10 @@ p_context_id ); - insert into ams_attributes - (ams_attribute_id,attribute_id,widget_name,deprecated_p) + insert into ams_attribute_items + (attribute_id,ams_attribute_id,widget,dynamic_p,deprecated_p) values - (v_ams_attribute_id,v_attribute_id,p_widget_name,p_deprecated_p); + (p_attribute_id,v_ams_attribute_id,p_widget,p_dynamic_p,p_deprecated_p); return v_ams_attribute_id; end;' language 'plpgsql'; @@ -86,59 +96,44 @@ returns varchar as ' declare p_ams_attribute_id alias for $1; - v_name varchar; + 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; + v_name := attribute_name + from ams_attributes + where ams_attribute_id = p_ams_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; + v_attribute_id integer; + v_object_type varchar; + v_attribute_name varchar; + v_dynamic_p boolean; 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; + select attribute_id, attribute_name, object_type, dynamic_p + info v_attribute_id, v_object_type, v_attribute_name, v_dynamic_p + from ams_attributes + where ams_attribute_id = :ams_attribute_id; - delete from ams_attribute_values where ams_attribute_id = p_ams_attribute_id; + delete from ams_attribute_values where attribute_id = v_attribute_id; PERFORM acs_object__delete ( p_ams_attribute_id ); - PERFORM acs_attribute__drop_description ( - v_object_type, - v_attribute_name, - ''ams_attribute_description'' - ); + if v_dynamic_p then PERFORM acs_attribute__drop_attribute ( v_object_type, v_attribute_name ); + end if; + return 0; end;' language 'plpgsql'; @@ -147,197 +142,107 @@ ------- 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; +------ Attribute Values +-------------------------------------------------------------------- - -- 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) +create or replace function ams_attribute_value__save (integer,integer,integer) 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; + p_object_id alias for $1; + p_attribute_id alias for $2; + p_value_id alias for $3; + v_count integer; begin - v_count := count(*) from ams_objects where object_id = p_object_id; - if v_count = 0 then + delete from ams_attribute_values + where object_id = p_object_id + and attribute_id = p_attribute_id; - -- 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) + if p_value_id is not null then + insert into ams_attribute_values + (object_id,attribute_id,value_id) values - (v_ams_object_id,p_object_id); + (p_object_id,p_attribute_id,p_value_id); + end if; - else - v_ams_object_id := ams_object_id(p_object_id); - end if; - - return v_ams_object_id; + return 0; end;' language 'plpgsql'; - -create or replace function ams_object_id (integer) -returns integer as ' +create or replace function ams_attribute_value__value (integer,integer) +returns text as ' declare - p_object_id alias for $1; - v_ams_object_id integer; + p_attribute_id alias for $1; + p_value_id alias for $2; + v_value_method varchar; + v_value text; + val record; begin - return ams_object_id from ams_objects where object_id = p_object_id; -end;' language 'plpgsql'; + v_value_method := value_method + from ams_widgets + where widget = ( select widget + from ams_attributes + where attribute_id = p_attribute_id ); + if v_value_method != '''' and v_value_method is NOT null then + for val in execute ''select '' || v_value_method || ''('' || p_value_id || '')::text as value'' loop + v_value := val.value; + exit; + end loop; + end if; -select define_function_args('ams_object_revision__new','object_id,package_id,creation_date;now(),creation_user,creation_ip'); + return v_value; + +end;' language 'plpgsql' stable strict; -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) +select define_function_args('ams_option__new','option_id,attribute_id,option,sort_order,depreacted_p;f,creation_date,creation_user,creation_ip,context_id,pretty_name'); + +create or replace function ams_option__new (integer,integer,varchar,integer,boolean,timestamptz,integer,varchar,integer,varchar) returns integer as ' declare - p_ams_attribute_id alias for $1; - p_option alias for $2; - p_sort_order alias for $3; + p_option_id alias for $1; + p_attribute_id alias for $2; + p_option alias for $3; + p_sort_order alias for $4; + p_deprecated_p alias for $5; + p_creation_date alias for $6; + p_creation_user alias for $7; + p_creation_ip alias for $8; + p_context_id alias for $9; + p_pretty_name alias for $10; v_option_id integer; v_sort_order integer; begin - v_option_id := nextval(''ams_options_seq''); + v_option_id := acs_object__new ( + p_option_id, + ''ams_option'', + p_creation_date, + p_creation_user, + P_creation_ip, + p_context_id, + ''t'', + p_pretty_name + ); + if p_sort_order is null then - v_sort_order := nextval(''ams_options_seq''); + v_sort_order := v_option_id; else v_sort_order := p_sort_order; end if; - insert into ams_options - (option_id,ams_attribute_id,option,sort_order) + insert into ams_option_types + (option_id,attribute_id,option,sort_order,deprecated_p) values - (v_option_id,p_ams_attribute_id,p_option,v_sort_order); + (v_option_id,p_attribute_id,p_option,v_sort_order,p_deprecated_p); return v_option_id; end;' language 'plpgsql'; @@ -349,206 +254,204 @@ p_option_id alias for $1; begin delete from ams_options where object_id = p_option_id; + PERFORM acs_object__delete ( + p_option_id + ); return 0; end;' language 'plpgsql'; +create or replace function ams_option__name (integer) +returns varchar as ' +declare + p_option_id alias for $1; + v_name varchar; +begin + v_name := option + from ams_option_types + where option_id = p_option_id; + + return v_name; +end;' language 'plpgsql'; + create or replace function ams_option__map (integer,integer) returns integer as ' declare - p_option_map_id alias for $1; + p_value_id alias for $1; p_option_id alias for $2; - v_option_map_id integer; + v_value_id integer; v_count integer; begin - v_count := count(*) from ams_option_map where option_map_id = p_option_map_id; + v_count := count(*) from ams_options where value_id = p_value_id; - if v_count = ''0'' then - v_option_map_id := nextval(''ams_option_map_id_seq''); - insert into ams_option_map_ids(option_map_id) values (v_option_map_id); + if v_count = ''0'' or p_value_id is null then + v_value_id := nextval from acs_object_id_seq; + insert into ams_option_ids(value_id) values (v_value_id); else - v_option_map_id := p_option_map_id; + v_value_id := p_value_id; end if; - insert into ams_option_map - (option_map_id,option_id) + insert into ams_options + (value_id,option_id) values - (v_option_map_id,p_option_id); + (v_value_id,p_option_id); - return v_option_map_id; + return v_value_id; end;' language 'plpgsql'; +create or replace function ams_value__options (integer) +returns text as ' +declare + p_value_id alias for $1; + v_name text; + rec RECORD; +begin + v_name := NULL; + if p_value_id is not null then + FOR rec IN + select option_id + from ams_options + where value_id = p_value_id + order by option_id + LOOP + IF v_name is null THEN + v_name := rec.option_id; + ELSE + v_name := v_name || '' '' || rec.option_id; + END IF; + END LOOP; + end if; ------- Attribute Values --------------------------------------------------------------------- + return v_name; +end;' language 'plpgsql'; --- 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) +create or replace function ams_value__asses (text) 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; + p_ams_value__options alias for $1; + v_value_id integer; 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; + v_value_id := value_id + from ams_options_ids + where ams_value__options(value_id) = p_ams_value__options; + + return v_value_id; end;' language 'plpgsql'; +------ AMS Texts +-------------------------------------------------------------------- - -create or replace function ams_attribute_value__superseed (integer,integer,integer) +create or replace function ams_value__text_save (text,varchar) returns integer as ' declare - p_revision_id alias for $1; - p_ams_attribute_id alias for $2; - p_ams_object_id alias for $3; + p_text alias for $1; + p_text_format alias for $2; + v_value_id integer; 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 ); + v_value_id := value_id + from ams_texts + where text = p_text + and text_format = p_text_format; + if v_value_id is null then + v_value_id := nextval from acs_object_id_seq; + insert into ams_texts + (value_id,text,text_format) + values + (v_value_id,p_text,p_text_format); + end if; - return 0; + return v_value_id; end;' language 'plpgsql'; +create or replace function ams_value__text(integer) +returns varchar as ' +declare + p_value_id alias for $1; + v_value text; +begin + v_value := ''{'' || text_format::text || ''} '' || text from ams_texts where value_id = p_value_id; + return v_value; +end;' language 'plpgsql'; +------ AMS Times +-------------------------------------------------------------------- -create or replace function ams_attribute_value__save (integer,integer,integer,integer,integer,timestamptz,text,varchar) +create or replace function ams_value__time_save (timestamptz) 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; + p_time alias for $1; + v_value_id integer; begin - v_ams_object_id := item_id from cr_revisions where revision_id = p_revision_id; + v_value_id := value_id + from ams_times + where time = p_time; - 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_value_id is null then + v_value_id := nextval from acs_object_id_seq; + insert into ams_times + (value_id,time) + values + (v_value_id,p_time); + end if; - 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; + return v_value_id; +end;' language 'plpgsql'; - 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''; +create or replace function ams_value__time(integer) +returns text as ' +declare + p_value_id alias for $1; + v_value text; +begin + v_value := to_char(time,''YYYY-MM-DD HH24:MI:SS TZ'')::text from ams_times where value_id = p_value_id; + return v_value; +end;' language 'plpgsql'; - 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; +------ AMS +-------------------------------------------------------------------- + +create or replace function ams_value__number_save (numeric) +returns integer as ' +declare + p_number alias for $1; + v_value_id integer; +begin + + v_value_id := value_id + from ams_numbers + where number = p_number; + + if v_value_id is null then + v_value_id := nextval from acs_object_id_seq; + insert into ams_numbers + (value_id,number) + values + (v_value_id,p_number); end if; + return v_value_id; +end;' language 'plpgsql'; - return 0; +create or replace function ams_value__number(integer) +returns text as ' +declare + p_value_id alias for $1; + v_value text; +begin + v_value := number::text from ams_numbers where value_id = p_value_id; + return v_value; end;' language 'plpgsql'; - ------- Groups +------ Lists -------------------------------------------------------------------- @@ -593,27 +496,27 @@ returns integer as ' declare p_list_id alias for $1; - p_ams_attribute_id alias for $2; + p_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''); + v_sort_order := nextval from acs_object_id_seq; else v_sort_order := p_sort_order; end if; delete from ams_list_attribute_map - where ams_attribute_id = p_ams_attribute_id + where attribute_id = p_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) + (list_id,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); + (p_list_id,p_attribute_id,v_sort_order,p_required_p,p_section_heading); return ''1''; end;' language 'plpgsql'; @@ -622,7 +525,16 @@ +create or replace function ams_list__name (integer) +returns varchar as ' +declare + p_list_id alias for $1; + v_name varchar; +begin + v_name := pretty_name from ams_lists where list_id = p_list_id; + return v_name; +end;' language 'plpgsql'; @@ -631,11 +543,12 @@ + ------ Postal Address -------------------------------------------------------------------- -create or replace function ams_attribute__postal_address_string (integer) -returns varchar as ' +create or replace function ams_value__postal_address (integer) +returns text as ' declare p_address_id alias for $1; v_name text; @@ -659,14 +572,74 @@ return v_name; end;' language 'plpgsql'; +create or replace function ams_value__postal_address_save (varchar,varchar,varchar,varchar,char(2),varchar,integer) +returns integer as ' +declare + p_delivery_address alias for $1; + p_municipality alias for $2; + p_region alias for $3; + p_postal_code alias for $4; + p_country_code alias for $5; + p_additional_text alias for $6; + p_postal_type alias for $7; + v_address_id integer; +begin + if p_additional_text is null and p_postal_type is null then + v_address_id := address_id + from postal_addresses + where delivery_address = p_delivery_address + and municipality = p_municipality + and region = p_region + and postal_code = p_postal_code + and country_code = p_country_code + and additional_text is NULL + and postal_type is NULL; + + else + + v_address_id := address_id + from postal_addresses + where delivery_address = p_delivery_address + and municipality = p_municipality + and region = p_region + and postal_code = p_postal_code + and country_code = p_country_code + and additional_text = p_additional_text + and postal_type = p_postal_type; + + end if; + + if v_address_id is null then + + v_address_id := acs_object__new ( + null, + ''postal_address'', + now(), + NULL, + NULL, + NULL + ); + + insert into postal_addresses + ( address_id, delivery_address, municipality, region, postal_code, country_code, additional_text, postal_type ) + values + ( v_address_id, p_delivery_address, p_municipality, p_region, p_postal_code, p_country_code, p_additional_text, p_postal_type ); + + end if; + + return v_address_id; +end;' language 'plpgsql'; + + + ------ Telecom Number -------------------------------------------------------------------- -create or replace function ams_attribute__telecom_number_string (integer) -returns varchar as ' +create or replace function ams_value__telecom_number (integer) +returns text as ' declare p_number_id alias for $1; v_name text; @@ -692,33 +665,69 @@ return v_name; end;' language 'plpgsql'; +create or replace function ams_value__telecom_number_save (integer,varchar,varchar,varchar,varchar,boolean,varchar,varchar,integer) +returns integer as ' +declare + p_itu_id alias for $1; + p_national_number alias for $2; + p_area_city_code alias for $3; + p_subscriber_number alias for $4; + p_extension alias for $5; + p_sms_enabled_p alias for $6; + p_best_contact_time alias for $7; + p_location alias for $8; + p_phone_type_id alias for $9; + v_number_id integer; +begin ------- AMS Options --------------------------------------------------------------------- + v_number_id := number_id + from telecom_numbers + where itu_id = p_itu_id + and national_number = p_national_number + and area_city_code = p_area_city_code + and subscriber_number = p_subscriber_number + and extension = p_extension + and sms_enabled_p = p_sms_enabled_p + and best_contact_time = p_best_contact_time + and location = p_location + and p_phone_type_id = p_phone_type_id; -create or replace function ams_attribute__options_string (integer) -returns varchar as ' -declare - p_option_map_id alias for $1; - v_name text; - rec RECORD; -begin + if v_number_id is null then - v_name := NULL; - if p_option_map_id is not null then - FOR rec IN - select aom.option_id - from ams_option_map aom - where aom.option_map_id = p_option_map_id - order by aom.option_id - LOOP - IF v_name is null THEN - v_name := rec.option_id; - ELSE - v_name := v_name || '' '' || rec.option_id; - END IF; - END LOOP; - end if; + v_number_id := acs_object__new ( + null, + ''telecom_number'', + now(), + NULL, + NULL, + NULL + ); + + 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 + ( v_number_id, p_itu_id, p_national_number, p_area_city_code, p_subscriber_number, p_extension, p_sms_enabled_p, p_best_contact_time, p_location, p_phone_type_id); - return v_name; + end if; + + return v_number_id; end;' language 'plpgsql'; + + + + + + + + + + + + + + + + + + + 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 -r1.2 -r1.2.2.1 --- openacs-4/packages/ams/tcl/address-widget-procs-postgresql.xql 27 Feb 2005 17:07:17 -0000 1.2 +++ openacs-4/packages/ams/tcl/address-widget-procs-postgresql.xql 30 Nov 2005 16:21:53 -0000 1.2.2.1 @@ -1,11 +1,10 @@ -postgresql7.2 - + - select default_name, iso from countries order by default_name + select iso from countries s 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 -r1.2 -r1.2.2.1 --- openacs-4/packages/ams/tcl/address-widget-procs.tcl 21 Oct 2004 01:53:49 -0000 1.2 +++ openacs-4/packages/ams/tcl/address-widget-procs.tcl 30 Nov 2005 16:21:53 -0000 1.2.2.1 @@ -44,10 +44,52 @@ {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 + if { [ad_conn isconnected] } { + # We are in an HTTP connection (request) so use that locale + set locale [ad_conn locale] + } else { + # There is no HTTP connection - resort to system locale + set locale [lang::system::locale] + } + set key "ams.country_${country_code}" + if { [string is true [lang::message::message_exists_p $locale $key]] } { + set country [lang::message::lookup $locale $key] + } else { + # cache the country codes + template::util::address::country_options_not_cached -locale $locale + + if { [string is true [lang::message::message_exists_p $locale $key]] } { + set country [lang::message::lookup $locale $key] + } else { + # we get the default en_US key which was created with the + # template::util::address::country_options_not_cached proc + set country [lang::message::lookup "en_US" $key] + } + } + + # Different formats depending on the country + switch $country_code { + "US" { + set address "$delivery_address +$municipality, $region $postal_code $country" + } + "DE" { + set address "$delivery_address +$postal_code $municipality" + } + default { + if { [parameter::get_from_package_key -package_key "ams" -parameter "DefaultAdressLayoutP" -default 1] } { + set address "$delivery_address +$municipality $region $postal_code +$country" + } else { + set address "$delivery_address +$postal_code $municipality $region +$country" + } + } + } return [ad_text_to_html $address] } @@ -62,20 +104,50 @@ 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 + # 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]] + if { [ad_conn isconnected] } { + # We are in an HTTP connection (request) so use that locale + set locale [ad_conn locale] + } else { + # There is no HTTP connection - resort to system locale + set locale [lang::system::locale] + } + return [util_memoize [list template::util::address::country_options_not_cached -locale $locale]] +# return [template::util::address::country_options_not_cached] } -ad_proc -public template::util::address::country_options_not_cached {} { +ad_proc -public template::util::address::country_options_not_cached { + {-locale "en_US"} +} { Returns the country list. } { - return [db_list_of_lists get_countries {}] + set country_code_list [db_list get_country_codes {}] + set return_country_list [list] + set reserved_country_codes [parameter::get_from_package_key -parameter "DefaultISOCountryCode" -package_key "ams" -default ""] + + foreach country $country_code_list { + if { [lsearch $reserved_country_codes $country] < 0 } { + lappend return_country_list [list [lang::message::lookup $locale "ref-countries.${country}"] $country] + } + } + set return_country_list [ams::util::sort_list_of_lists -list $return_country_list] + set country_code [list] + if { [exists_and_not_null reserved_country_codes] } { + foreach country $reserved_country_codes { + set country [string toupper $country] + lappend country_code [list [lang::message::lookup $locale "ref-countries.${country}"] $country] + } + set country_code [concat $country_code [list "--" ""] $return_country_list] + } else { + set country_code $return_country_list + } + return $country_code } ad_proc -public template::data::validate::address { value_ref message_ref } { @@ -90,27 +162,62 @@ 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 "" + set message [list] # 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]: \{ \}." + lappend message "[_ ams.Your_entry_must_not_contain_the_following_characters]: \{ \}." } - if { $country_code == "US" } { - # this should check a cached list - # this proc cannot for some reason go in the postgresql file... - if { ![db_0or1row validate_state { - select 1 from us_states where abbrev = upper(:region) or state_name = upper(:region) -} ] } { - if { [exists_and_not_null message_temp] } { append message " " } - append message "\"$region\" [_ ams.is_not_a_valid_US_state]." + + # Country Specific Validation + switch $country_code { + CA { + # Canada + if { ![exists_and_not_null region] } { + lappend message "\"[_ ams.region]\" is required." + } + if { [exists_and_not_null postal_code] } { + if { ![regexp {^([A-Z][0-9][A-Z] [0-9][A-Z][0-9])$} $postal_code] } { + lappend message "\"$postal_code\" [_ ams.is_not_a_valid_Canadian_postal_code]." + } + } else { + lappend message "\"[_ ams.postal_code]\" is required." + } + if { ![exists_and_not_null municipality] } { + lappend message "\"[_ ams.municipality]\" is required." + } } + US { + # United States + if { [exists_and_not_null region] } { + # this should check a cached list + # this query for some reason cannot go in the address-widget-procs.xql file... + if { ![db_0or1row validate_state { + select 1 from us_states where abbrev = upper(:region) or state_name = upper(:region) + } ] } { + lappend message "\"$region\" [_ ams.is_not_a_valid_US_state]." + } + } else { + lappend message "\"[_ ams.region]\" is required." + } + if { [exists_and_not_null postal_code] } { + if { ![regexp {^([0-9]{5})(-([0-9]{4}))??$} $postal_code] } { + lappend message "\"$postal_code\" [_ ams.is_not_a_valid_US_zip_code]." + } + } else { + lappend message "\"[_ ams.postal_code]\" is required." + } + if { ![exists_and_not_null municipality] } { + lappend message "\"[_ ams.municipality]\" is required." + } + } } - if { [exists_and_not_null message_temp] } { + set message [join $message " "] + ns_log notice "MESSAGE: $message" + if { [exists_and_not_null message] } { return 0 } else { return 1 @@ -141,6 +248,53 @@ # as a non-value in case of a required element. return [list] } else { + if { $country_code == "US" } { + # since we have reference data installed we can automatically fill in these values for + # US States and Cities + if { [regexp {^([0-9]{5})(-([0-9]{4}))??$} $postal_code] } { + regexp {^([0-9]{5})(-([0-9]{4}))??$} $postal_code match zipcode + if { ![exists_and_not_null region] } { + set region [db_string get_region { + select abbrev + from us_states + where us_states.fips_state_code = ( select us_zipcodes.fips_state_code + from us_zipcodes + where zipcode = :zipcode ) + } -default {}] + } + if { ![exists_and_not_null municipality] } { + set municipality [db_string get_municipality { + select name + from us_zipcodes + where zipcode = :zipcode} -default {}] + } + } + } + if { $country_code == "CA" && [string length $postal_code] == "6" } { + set postal_list [split $postal_code {}] + set postal_code_temp [string toupper "[join [lrange $postal_list 0 2] {}] [join [lrange $postal_list 3 5] {}]"] + if { [regexp {^([A-Z][0-9][A-Z] [0-9][A-Z][0-9])$} $postal_code_temp] } { + set postal_code $postal_code_temp + } + } + if { $country_code == "US" || $country_code == "CA" } { + # make the city pretty + set municipality_temp [list] + foreach word $municipality { + # I am sure there are more then "Mc" words when they come up add them here + if { [regexp {^MC([a-zA-Z]+?)} [string toupper $word]] } { + lappend municipality_temp [join "Mc[string toupper [lindex [split $word {}] 2]][string tolower [lrange [split $word {}] 3 [llength [split $word {}]]]]" {}] + } else { + lappend municipality_temp [string totitle $word] + } + } + set municipality [join $municipality_temp " "] + + } + + + set postal_code [string toupper $postal_code] + return [list [list $delivery_address $municipality $region $postal_code $country_code $additional_text $postal_type]] } } @@ -249,10 +403,12 @@ 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] + return [template::util::address::html_view $delivery_address $municipality $region $postal_code $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'." + error "Parameter supplied to template::util::address::get_property 'what' must be one of: 'delivery_address', 'postal_code', 'municipality', 'region', 'country_code', 'additional_text', 'postal_type'. You specified: '$what'." + ns_log "AMS Address Widget Error: on page [ad_conn url] template::util::address::get_property asked for $what" + return "" } } @@ -284,7 +440,7 @@ set postal_code {} set municipality {} set region {} - set country_code [parameter::get -parameter "DefaultISOCountryCode" -default "US"] + set country_code [lindex [parameter::get_from_package_key -parameter "DefaultISOCountryCode" -package_key "ams" -default ""] 0] set additional_text {} set postal_type {} } @@ -294,27 +450,44 @@ if { [string equal $element(mode) "edit"] } { - set attributes(id) \"address__$element(form_id)__$element(id)\" +# set attributes(id) "address__$element(form_id)__$element(id)" + set attributes(class) "address-widget-country-code" append output " - +
- + - - - - +" + if { [parameter::get_from_package_key -package_key "ams" -parameter "DefaultAdressLayoutP" -default 1] } { + append output " + + + + + + + + + " + } else { + append output " + + + + + + + + + " + } + append output " - - - - - Fisheye: Tag 1.4.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/ams-init.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/ams-install-procs.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.3.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/ams-list-procs-postgresql.xql'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.6.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/ams-list-procs.tcl'. Fisheye: No comparison available. Pass `N' to diff? 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 -r1.7 -r1.7.2.1 --- openacs-4/packages/ams/tcl/ams-procs-postgresql.xql 27 Feb 2005 17:07:17 -0000 1.7 +++ openacs-4/packages/ams/tcl/ams-procs-postgresql.xql 30 Nov 2005 16:21:53 -0000 1.7.2.1 @@ -1,748 +1,193 @@ -postgresql7.2 - + - select ams_attribute_id, required_p - from ams_list_attribute_map - where list_id = :list_id - order by sort_order + select pretty_name + from ams_attributes + where attribute_id = :attribute_id - + - select ams_object_id(:object_id) + select pretty_plural + from ams_attributes + where attribute_id = :attribute_id - + - select ams_object__new( - :object_id, - :package_id, - now(), - :creation_user, - :creation_ip - ); + select acs_attribute__create_attribute ( + :object_type, + :attribute_name, + :datatype, + :pretty_name, + :pretty_plural, + :table_name, + :column_name, + :default_value, + :min_n_values, + :max_n_values, + :sort_order, + :storage, + :static_p + ) - + - select ams_option__new (:ams_attribute_id,:option,:sort_order) + select attribute_id + from acs_attributes + where object_type = :object_type + and attribute_name = :attribute_name - + - select ams_option__delete (:option_id) + select supertype + from acs_object_types + where object_type = :object_type - - + - select ams_option__map (:option_map_id,:option_id) - - - - - - select ams.*, - acs.attribute_name, - acs.pretty_name, - acs.pretty_plural, - acs.object_type, - aw.storage_type - from ams_attributes ams, - acs_attributes acs, - ams_widgets aw - where ams.ams_attribute_id = :ams_attribute_id - and ams.attribute_id = acs.attribute_id - and ams.widget_name = aw.widget_name - - - - - - 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__options_string(option_map_id) as options_string, - 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) + (object_id,attribute_id,value_id) + ( select :to, + attribute_id, + value_id + from ams_attribute_values + where object_id = :from ) - + - 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 ) + delete from ams_attribute_values + where object_id = :object_id - + select * - from ams_lists - where list_id = :list_id + from ams_attributes + where attribute_id = :attribute_id - - + - select ams_attribute_id - from ams_list_attribute_map - where list_id = :list_id + select ams_attribute_id + from ams_attributes + where attribute_id = :attribute_id - - + - select '1' - from ams_lists - where package_key = :package_key - and object_type = :object_type - and list_name = :list_name + select ams_attribute_value__save ( + :object_id, + :attribute_id, + :value_id + ) - + - select list_id - from ams_lists - where package_key = :package_key - and object_type = :object_type - and list_name = :list_name + select option + from ams_option_types + where option_id = :option_id - - + - select ams_list__attribute_map ( - :list_id, - :ams_attribute_id, - :sort_order, - :required_p, - :section_heading - ) + select alam.attribute_id, + alam.required_p, + alam.section_heading, + aa.attribute_name, + aa.pretty_name, + aa.widget + from ams_list_attribute_map alam, + ams_attributes aa + where alam.attribute_id = aa.attribute_id + and alam.list_id = :list_id + order by alam.sort_order - + - select sort_order - from ams_list_attribute_map - where list_id = :list_id - order by sort_order desc - limit 1 + select + alam.attribute_id, + alam.required_p, + alam.section_heading, + alam.html_options, + aa.attribute_name, + aa.pretty_name, + aa.widget + from + ams_list_attribute_map alam, + ams_attributes aa + where + alam.attribute_id = aa.attribute_id + and alam.list_id in ($list_ids) + order by alam.sort_order - + - delete from ams_list_attribute_map - where list_id = :list_id - and ams_attribute_id = :ams_attribute_id + select aav.*, aa.attribute_name, aa.widget, aa.pretty_name, + ams_attribute_value__value(aav.attribute_id,aav.value_id) as value + from ams_attribute_values aav, + ams_attributes aa + where aav.object_id = :object_id + and aav.attribute_id = aa.attribute_id + and aa.attribute_id in ( select attribute_id from ams_list_attribute_map where list_id = :list_id ) - + - update ams_list_attribute_map - set required_p = 't' - where list_id = :list_id - and ams_attribute_id = :ams_attribute_id + select alam.attribute_id, + alam.section_heading, + alam.html_options, + aa.attribute_name, + aa.pretty_name, + aa.widget, + av.value + from ams_list_attribute_map alam, + ams_attributes aa left join ( + select + ams_attribute_values.attribute_id, + ams_attribute_value__value(ams_attribute_values.attribute_id,ams_attribute_values.value_id) as value + from + ams_attribute_values + where + ams_attribute_values.object_id = :object_id ) av on ( aa.attribute_id = av.attribute_id ) + where + alam.attribute_id = aa.attribute_id + and alam.list_id in ($list_ids) + order by alam.sort_order + + + + select ams_attribute_value__value(av.attribute_id,av.value_id) as value, widget,attribute_name,av.attribute_id + from ams_attribute_values av, ams_attributes aa + where object_id = :object_id + and av.attribute_id = aa.attribute_id + $where_clause + + - - - update ams_list_attribute_map - set required_p = 'f' - where list_id = :list_id - and ams_attribute_id = :ams_attribute_id - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 -r1.7 -r1.7.2.1 --- openacs-4/packages/ams/tcl/ams-procs.tcl 30 Oct 2004 00:23:54 -0000 1.7 +++ openacs-4/packages/ams/tcl/ams-procs.tcl 30 Nov 2005 16:21:53 -0000 1.7.2.1 @@ -1,1326 +1,596 @@ ad_library { - Support procs for the ams package +Support procs for the ams package - @author Matthew Geddert openacs@geddert.com +@author Matthew Geddert openacs@geddert.com @creation-date 2004-09-28 @cvs-id $Id$ } +namespace eval attribute:: {} +namespace eval ams:: {} +namespace eval ams::attribute {} +namespace eval ams::option {} +namespace eval ams::ad_form {} +namespace eval ams::util {} - -ad_proc -public ams_object_id { - -object_id:required +ad_proc -public attribute::pretty_name { + {-attribute_id:required} } { - @param object_id - Returns the revision controlled ams_object_id for the given openacs object_id. Cached. - @return ams_object_id + get the pretty_name of an attribute. Cached } { - return [util_memoize [list ams_object_id_not_cached -object_id $object_id]] + return [lang::util::localize [util_memoize [list ::attribute::pretty_name_not_cached -attribute_id $attribute_id]]] } -ad_proc -private ams_object_id_not_cached { - -object_id:required +ad_proc -public attribute::pretty_name_not_cached { + {-attribute_id:required} } { - @param object_id - Returns the revision controlled ams_object_id for the given openacs object_id. - @return ams_object_id + get the pretty_name of an attribute } { - 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 {}] - } + return [db_string get_pretty_name {} -default {}] } -ad_proc -public ams_form { - -package_key:required - -object_type:required - -list_name:required - -form_name:required - -object_id:required - -return_url:required +ad_proc -public attribute::pretty_plural { + {-attribute_id:required} } { - TODO DOCUMENTATION + get the pretty_plural of an attribute. Cached } { - - set edit_proc "ams::object::attribute::values -vars -object_id $object_id" - set submit_proc "ams::ad_form::save -package_key $package_key -object_type $object_type -list_name $list_name -form_name $form_name -object_id $object_id" - set after_submit_proc "ad_returnredirect $return_url" + return [lang::util::localize [util_memoize [list ::attribute::pretty_plural_not_cached -attribute_id $attribute_id]]] +} - ad_form \ - -name $form_name \ - -form [ams::ad_form::elements -package_key $package_key -object_type $object_type -list_name $list_name -key "object_id"] \ - -edit_request $edit_proc \ - -on_submit $submit_proc \ - -after_submit $after_submit_proc - +ad_proc -public attribute::pretty_plural_not_cached { + {-attribute_id:required} +} { + get the pretty_plural of an attribute +} { + return [db_string get_pretty_plural {} -default {}] } - -namespace eval ams:: {} - - -ad_proc -public ams::define_list { - -package_key:required +ad_proc -public attribute::new { -object_type:required - -list_name:required + -attribute_name:required + -datatype:required -pretty_name:required - {-description ""} - {-description_mime_type ""} - {-reset_order:boolean} - {-attributes} + -pretty_plural:required + {-table_name ""} + {-column_name ""} + {-default_value ""} + {-min_n_values "1"} + {-max_n_values "1"} + {-sort_order ""} + {-storage "generic"} + {-static_p "f"} + {-if_does_not_exist:boolean} } { - TODO: Need Documentation + create a new attribute - @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 + @see ams::attribute::new } { - - # now we check to see if this list already exists - if { ![ams::list::exists_p -package_key $package_key -object_type $object_type -list_name $list_name] } { - set list_id [ams::list::new -list_name $list_name \ - -package_key $package_key \ - -object_type $object_type \ - -pretty_name $pretty_name \ - -description $description \ - -description_mime_type $description_mime_type] - + if { $if_does_not_exist_p } { + set attribute_id [attribute::id -object_type $object_type -attribute_name $attribute_name] + if { [string is false [exists_and_not_null attribute_id]] } { + set attribute_id [db_string create_attribute {}] + } } else { - set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $list_name] + set attribute_id [db_string create_attribute {}] } - foreach { attribute } $attributes { - # the attribute follows this order - # attribute_name widget_name pretty_name pretty_plural extra_args - set attribute_name [lindex $attribute 0] - set widget_name [lindex $attribute 1] - set pretty_name [lindex $attribute 2] - set pretty_plural [lindex $attribute 3] - # we set the defaults for values that are required - set required_p 0 - set default_name {} - set description {} - set default_value {} - set context_id {} - set options {} - # we now check for other values - set i 4 - while { $i < [llength $attribute] } { - set arg [lindex $attribute $i] - switch [lindex $arg 0] { - required { set required_p 1 } - default { set [lindex $arg 0] [lindex $arg 1] } - } - incr i - } - set ams_attribute_id [ams::attribute::new -object_type $object_type \ - -attribute_name $attribute_name \ - -widget_name $widget_name \ - -pretty_name $pretty_name \ - -pretty_plural $pretty_plural \ - -default_value $default_value \ - -description $description \ - -context_id $context_id \ - -options $options \ - -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 $object_type -attribute_name $attribute_name] - } - 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 - } - } - ams::list::get_list_id_flush -package_key $package_key -object_type $object_type -list_name $list_name - + # Update the pretty names + set pretty_name [lang::util::convert_to_i18n -message_key "ams_attribute_${attribute_id}_pretty_name" -text "$pretty_name"] + set pretty_plural [lang::util::convert_to_i18n -message_key "ams_attribute_${attribute_id}_pretty_plural" -text "$pretty_plural"] + db_dml update_pretty_names "update acs_attributes set pretty_name = :pretty_name, pretty_plural = :pretty_plural where attribute_id = :attribute_id" + return $attribute_id } - -ad_proc -public ams::define_attributes { +ad_proc -public attribute::id { -object_type:required - -attributes:required + -attribute_name:required } { - 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 -package_key "contacts" \
-        -object_type "ct_contact" \
-        -list_name "contact_person_ae" \
-        -pretty_name "The Fields used to Add/Edit a Contact Person" \
-        -attributes {
-            {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.

- + return the attribute_id for the specified attribute } { - 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 + return [db_string get_attribute_id {} -default {}] } -ad_proc -public ams::package_id {} { - - TODO: Get the AMS package ID, not the connection package_id +ad_proc -public ams::package_id { +} { +TODO: Get the AMS package ID, not the connection package_id Get the package_id of the ams instance - @return package_id +@return package_id } { return [ad_conn package_id] } - -ad_proc -public ams::lang_key_encode { - {-len "175"} - -string:required +ad_proc -public ams::util::edit_lang_key_url { + -message:required + {-package_key "ams"} } { - @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]]] -} + if { [regsub "^${package_key}." [string trim $message "\#"] {} message_key] } { + set edit_url [export_vars -base "[apm_package_url_from_key "acs-lang"]admin/edit-localized-message" { { locale {[ad_conn locale]} } package_key message_key { return_url [ad_return_url] } }] + } else { + set edit_url "" + } + return $edit_url + } + ad_proc -public ams::util::localize_and_sort_list_of_lists { + {-list} + {-position "0"} + } { + localize and sort a list of lists + } { + set localized_list [ams::util::localize_list_of_lists -list $list] + return [ams::util::sort_list_of_lists -list $localized_list -position $position] + } -namespace eval ams::ad_form {} + ad_proc -public ams::util::localize_list_of_lists { + {-list} + } { + localize the elements of a list_of_lists + } { + set list_output [list] + foreach item $list { + set item_output [list] + foreach part $item { + lappend item_output [lang::util::localize $part] + } + lappend list_output $item_output + } + return $list_output + } -ad_proc -public ams::ad_form::save { - -package_key:required - -object_type:required - -list_name:required - -form_name:required - -object_id:required -} { - this code saves attributes input in a form -} { + ad_proc -public ams::util::sort_list_of_lists { + {-list} + {-position "0"} + } { + sort a list_of_lists + } { + set sort_output [list] + foreach item $list { + set sort_key [string toupper [lindex $item $position]] + # we need to replace spaces because it prevents + # multi word sort keys from recieving curly + # brackets during the sort, which skews results + regsub -all " " $sort_key "_" sort_key + lappend sort_output [list $sort_key $item] + } + set sort_output [lsort $sort_output] + set list_output [list] + foreach item $sort_output { + lappend list_output [lindex $item 1] + } + return $list_output + } - set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $list_name] + ad_proc -public ams::object_parents { + -object_type:required + -sql:boolean + -hide_current:boolean + -show_root:boolean + } { + @param sql if selected the list will be formatted in a way suitable for inclusion in sql statements + @param hide_current hide the current object_type + @param show_root show the root object_type (the acs_object object type) + @return a list of the parent object_types + } { + if { [string is false $hide_current_p] } { + set object_types [list $object_type] + } + while { $object_type != "acs_object" } { + set object_type [db_string get_supertype {}] + if { $object_type != "acs_object" } { + lappend object_types $object_type + } + } + if { $show_root_p } { + lappend object_types "acs_object" + } + if { $sql_p } { + return "'[join $object_types "','"]'" + } else { + return $object_types + } + } - ams::object::attribute::values -ids -array "oldvalues" -object_id $object_id - set ams_attribute_ids [ams::list::ams_attribute_ids -list_id $list_id] - set variables {} + ad_proc -public ams::object_copy { + -from:required + -to:required + } { + } { + db_transaction { + db_dml copy_object {} + } + } - foreach ams_attribute_id $ams_attribute_ids { - set storage_type [ams::attribute::storage_type -ams_attribute_id $ams_attribute_id] - set attribute_name [ams::attribute::name -ams_attribute_id $ams_attribute_id] - set attribute_value [template::element::get_value $form_name $attribute_name] - if { $storage_type == "ams_options" } { - # we always order the options_string in the order of the option_id - # when doing internal processing - set attribute_value [lsort [template::element::get_values $form_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" - db_transaction { - ams::object::attribute::values_flush -object_id $object_id - set revision_id [ams::object::revision::new -object_id $object_id] - set ams_object_id [ams_object_id -object_id $object_id] - foreach { ams_attribute_id attribute_value } $variables { - ams::attribute::value::superseed -revision_id $revision_id -ams_attribute_id $ams_attribute_id -ams_object_id $ams_object_id - if { [exists_and_not_null attribute_value] } { - ams::attribute::value::new -revision_id $revision_id -ams_attribute_id $ams_attribute_id -attribute_value $attribute_value - } - } - } - } - ams::object::attribute::values -object_id $object_id - return 1 -} + ad_proc -public ams::object_delete { + {-object_id:required} + } { + delete and object that uses ams attributes + } { + return [db_dml delete_object {}] + } -ad_proc -public ams::ad_form::elements { - -package_key:required - -object_type:required - -list_name:required - {-key ""} -} { - this code saves retrieves ad_form elements -} { - set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $list_name] + ad_proc -public ams::attribute::get { + -attribute_id:required + -array:required + } { + Get the info on an ams_attribute + } { + upvar 1 $array row + db_1row select_attribute_info {} -column_array row + } - set element_list "" - if { [exists_and_not_null key] } { - lappend element_list "$key\:key" - } - db_foreach select_elements {} { - if { $required_p } { - lappend element_list [ams::attribute::widget -ams_attribute_id $ams_attribute_id -required] - } else { - lappend element_list [ams::attribute::widget -ams_attribute_id $ams_attribute_id] - } - } - return $element_list -} + ad_proc -public ams::attribute::new { + -attribute_id:required + {-ams_attribute_id ""} + -widget:required + {-dynamic_p "0"} + {-deprecated_p "0"} + {-context_id ""} + } { + create a new ams_attribute + @see attribute::new + } { + set existing_ams_attribute_id [db_string get_existing_ams_attribute_id {} -default {}] + if { [exists_and_not_null existing_ams_attribute_id] } { + return $existing_ams_attribute_id + } else { + set extra_vars [ns_set create] + oacs_util::vars_to_ns_set -ns_set $extra_vars -var_list {attribute_id ams_attribute_id widget dynamic_p deprecated_p context_id} + set ams_attribute_id [package_instantiate_object -extra_vars $extra_vars ams_attribute] + return $ams_attribute_id + } + } -namespace eval ams::option {} + ad_proc -public ams::attribute::value_save { + -object_id:required + -attribute_id:required + -value_id:required + } { + save and attribute value + } { + db_exec_plsql attribute_value_save {} + } -ad_proc -public ams::option::new { - -ams_attribute_id:required - -option:required - {-locale ""} - {-sort_order ""} -} { - Create a new ams option for an attribute + ad_proc -public ams::option::new { + {-option_id ""} + -attribute_id:required + -option:required + {-sort_order ""} + {-deprecated_p "0"} + {-context_id ""} + } { + 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. + set option_id [db_string get_option_id { select option_id from ams_option_types where option = :option and attribute_id = :attribute_id } -default {}] - @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 + if { $option_id == "" } { - @return option_id -} { - - set lang_key "ams.option:[ams::lang_key_encode -string $option]" - _mr en $lang_key $option - set option $lang_key - - return [db_exec_plsql ams_option_new {}] + set option_id [db_nextval acs_object_id_seq] + set pretty_name [lang::util::convert_to_i18n -message_key "ams_option_${option_id}" -text "$option"] + set extra_vars [ns_set create] + oacs_util::vars_to_ns_set -ns_set $extra_vars -var_list {option_id attribute_id option sort_order deprecated_p pretty_name} + set option_id [package_instantiate_object -extra_vars $extra_vars ams_option] + + # For whatever the reason it does not insert the pretty_name, + # let's do it manually then... + db_dml update_pretty_name "update acs_objects set title = :pretty_name where object_id = :option_id" + } + + return $option_id } - ad_proc -public ams::option::delete { -option_id:required } { Delete an ams option - @param option_id +@param option_id } { db_exec_plsql ams_option_delete {} } - -ad_proc -public ams::option::map { - {-option_map_id ""} +ad_proc -public ams::option::name { -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. + Delete an ams option - @param option_map_id - @param option_id - - @return option_map_id +@param option_id } { - return [db_exec_plsql ams_option_map {}] + return [lang::util::localize [db_string get_option {} -default {}]] } - -namespace eval ams::attribute {} - -ad_proc -public ams::attribute::get { - -ams_attribute_id:required - -array:required +ad_proc -public ams::ad_form::save { + -package_key:required + -object_type:required + -list_name:required + -form_name:required + -object_id:required + {-copy_object_id ""} } { - Get the info on an ams_attribute + this code saves attributes input in a form } { - upvar 1 $array row - db_1row select_attribute_info {} -column_array row + if { [exists_and_not_null copy_object_id] } { + ams::object_copy -from $object_id -to $copy_object_id + } + set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $list_name] + db_transaction { + db_foreach select_elements {} { + set value_id [ams::widget -widget $widget -request "form_save_value" -attribute_name $attribute_name -pretty_name $pretty_name -form_name $form_name -attribute_id $attribute_id] + ams::attribute::value_save -object_id $object_id -attribute_id $attribute_id -value_id $value_id + } + } } -ad_proc -public ams::attribute::flush { - -ams_attribute_id:required +ad_proc -public ams::ad_form::elements { + -package_key:required + -object_type:required + {-list_name ""} + {-list_names ""} + {-key ""} } { - Get the info on an ams_attribute -} { - ams::attribute::get -ams_attribute_id $ams_attribute_id -array attribute_info + This code saves retrieves ad_form elements, it recieves list_name or list_names switch, if both are provided + then it would use list_names. - set object_type $attribute_info(object_type) - set attribute_name $attribute_info(attribute_name) - ams::attribute::widget_flush -ams_attribute_id $ams_attribute_id - ams::attribute::exists_p_flush -object_type $object_type -attribute_name $attribute_name - ams::attribute::get_ams_attribute_id_flush -object_type $object_type -attribute_name $attribute_name - ams::attribute::name_flush -ams_attribute_id $ams_attribute_id - ams::attribute::storage_type_flush -ams_attribute_id $ams_attribute_id - -} - - -ad_proc -public ams::attribute::widget { - -ams_attribute_id:required - {-required:boolean} + @param package_key The package_key of the list_id. + @param object_type The object_type of the list_id. + @param list_name The list_name to get the list_id. Either this or list_names must be provided. + @param list_names A list of list_names to get the list_ids from. Either this or list_name must be provided. + @param key The key element to use in the form. } { - @return an ad_form encoded attribute widget -} { - set attribute_widget [ams::attribute::widget_cached -ams_attribute_id $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 + set list_ids [list] + if { [empty_string_p $list_names] && [empty_string_p $list_name] } { + ad_return_complaint 1 "[_ ams.you_must_provide_list_name]" + ad_script_abort } - return $attribute_widget -} - -ad_proc -private ams::attribute::widget_not_cached { - -ams_attribute_id:required -} { - 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 { [empty_string_p $list_names] && ![empty_string_p $list_name] } { + set list_names $list_name } - if { $storage_type == "ams_options" } { - set options {} - db_foreach select_options {} { - lappend options [list [_ $option] [lindex $option_id]] - } - lappend attribute_widget [list "options" $options] + foreach l_name $list_names { + set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $l_name] + if {![empty_string_p $list_id]} { + lappend list_ids $list_id + } } - return $attribute_widget -} - -ad_proc -private ams::attribute::widget_cached { - -ams_attribute_id:required -} { - 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 $ams_attribute_id]] -} - - -ad_proc -private ams::attribute::widget_flush { - -ams_attribute_id:required -} { - Returns an ad_form encoded attribute widget list, as used by other procs. Flush. - @see ams::attribute::widget_not_cached -} { - return [util_memoize_flush [list ams::attribute::widget_not_cached -ams_attribute_id $ams_attribute_id]] -} - - - - - - -ad_proc -private ams::attribute::exists_p { - -object_type:required - -attribute_name:required -} { - 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 -} { - set ams_attribute_id [ams::attribute::get_ams_attribute_id -object_type $object_type -attribute_name $attribute_name] - if { [exists_and_not_null ams_attribute_id] } { - return 1 - } else { - return 0 + # To use in the query + set list_ids [template::util::tcl_to_sql_list $list_ids] + set element_list "" + if { [exists_and_not_null key] } { + lappend element_list "$key\:key" } -} -ad_proc -private ams::attribute::exists_p_flush { - -object_type:required - -attribute_name:required -} { - - does an attribute with this given attribute_name for this object type exists? Flush. + # Control list to know which attributes are already in the + # elements list so we don't en up with duplicates + set control_list [list] - @return ams_attribute_id if none exists then it returns blank -} { - return [util_memoize_flush [list ams::attribute::get_ams_attribute_id_not_cached -object_type $object_type -attribute_name $attribute_name]] -} + set all_attributes [db_list_of_lists select_elements " "] + foreach attribute $all_attributes { + set attribute_id [lindex $attribute 0] + if { [string equal [lsearch $control_list $attribute_id] "-1"] } { + lappend control_list $attribute_id + set required_p [lindex $attribute 1] + set section_heading [lindex $attribute 2] + set html_options [lindex $attribute 3] + set attribute_name [lindex $attribute 4] + set pretty_name [lindex $attribute 5] + set widget [lindex $attribute 6] -ad_proc -private ams::attribute::get_ams_attribute_id { - -object_type:required - -attribute_name:required -} { - - return the ams_attribute_id for the given ams_attriubte_name belonging to this object_type. Cached. + set element [ams::widget \ + -widget $widget \ + -request "ad_form_widget" \ + -attribute_name $attribute_name \ + -pretty_name $pretty_name \ + -optional_p [string is false $required_p] \ + -html_options $html_options \ + -attribute_id $attribute_id] - @return ams_attribute_id if none exists then it returns blank -} { - - return [util_memoize [list ams::attribute::get_ams_attribute_id_not_cached -object_type $object_type -attribute_name $attribute_name]] -} - -ad_proc -private ams::attribute::get_ams_attribute_id_not_cached { - -object_type:required - -attribute_name:required -} { + if { [exists_and_not_null section_heading] } { + lappend element [list section $section_heading] + } + lappend element_list $element + } + } - 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 {}] + return $element_list } -ad_proc -private ams::attribute::get_ams_attribute_id_flush { +ad_proc -public ams::ad_form::values { + -package_key:required -object_type:required - -attribute_name:required -} { - - return the ams_attribute_id for the given ams_attriubte_name belonging to this object_type. Flush. - - @return ams_attribute_id if none exists then it returns blank -} { - - return [util_memoize_flush [list ams::attribute::get_ams_attribute_id_not_cached -object_type $object_type -attribute_name $attribute_name]] -} - -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} - {-options} -} { - create a new ams_attribute - -

widget_name

-

- This should be a widget_name used by ams. All available widgets can be found at /ams/widgets. -
- - - - @param context_id defaults to package_id - @param no_complain silently ignore attributes that already exist. - @param options a list of options for an ams_object that has the ams_options storage type the options will be ordered in the order of the list - @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" } - } - ams::attribute::exists_p_flush -object_type $object_type -attribute_name $attribute_name - if { [ams::attribute::exists_p -object_type $object_type -attribute_name $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 [ams::attribute::get_ams_attribute_id -object_type $object_type -attribute_name $attribute_name] - } - } 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] - - # now we define options for an attribute - if they are provided and the attribute accepts options - if { [string equal [ams::attribute::storage_type -ams_attribute_id $ams_attribute_id] "ams_options"] && [exists_and_not_null options] } { - foreach { option } $options { - ams::option::new -ams_attribute_id $ams_attribute_id -option $option - } - } - return $ams_attribute_id - } -} - - -ad_proc -private ams::attribute::name_not_cached { - -ams_attribute_id:required -} { - 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:required -} { - 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 $ams_attribute_id]] -} - - -ad_proc -private ams::attribute::name_flush { - -ams_attribute_id:required -} { - 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:required -} { - 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:required -} { - 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 $ams_attribute_id]] -} - - -ad_proc -private ams::attribute::storage_type_flush { - -ams_attribute_id:required -} { - 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 { + -list_name:required + -form_name:required -object_id:required - -ams_attribute_id:required } { - this code returns the cached attribute value for a specific ams_attribute + this code populates ad_form values } { - set attribute_values_and_ids [ams::object::attributes::list_format -object_id $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] - } + set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $list_name] + db_foreach select_values {} { + ams::widget -widget $widget -request "form_set_value" -attribute_name $attribute_name -pretty_name $pretty_name -form_name $form_name -attribute_id $attribute_id -value $value } - return $attribute_value } -ad_proc -public ams::attribute::value_from_name { +ad_proc -public ams::values { + -package_key:required -object_type:required - -attribute_name:required + {-list_name ""} + {-list_names ""} -object_id:required + {-format "text"} + {-locale ""} } { - this code returns the cached attribute value for a specific ams_attribute + This returns a list with the first element as the pretty_attribute name + and the second the value. Cached } { - return [ams::attribute::value -object_id $object_id [ams::attribute::get_ams_attribute_id -object_type $object_type -attribute_name $attribute_name]] + return [util_memoize [list ams::values_not_cached \ + -package_key $package_key \ + -object_type $object_type \ + -list_name $list_name \ + -list_names $list_names \ + -object_id $object_id \ + -format $format \ + -locale $locale]] } -namespace eval ams::attribute::value {} - -ad_proc -public ams::attribute::value::new { - -revision_id:required - -ams_attribute_id:required - -attribute_value:required -} { - this code saves attributes input in a form -} { - set storage_type [ams::attribute::storage_type -ams_attribute_id $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_number_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 { - # we need to loop through the values - # on the first option_map_id the option_map_id - # will be set. - foreach { option_id } $attribute_value { - set option_map_id [ams::option::map -option_map_id $option_map_id -option_id $option_id] - } - } - - 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:required - -ams_attribute_id:required - -ams_object_id:required -} { - superseed an attribute value -} { - db_dml superseed_attribute_value {} -} - -namespace eval ams::multirow {} - -ad_proc -private ams::multirow::extend { +ad_proc -public ams::values_not_cached { -package_key:required -object_type:required - -list_name:required - -multirow:required - -key:required + {-list_name ""} + {-list_names ""} + -object_id:required + {-format "text"} + {-locale ""} } { - append ams_attribute_values to a multirow + this returns a list with the first element as the pretty_attribute name and the second the value } { - set list_id [ams::list::get_list_id \ - -package_key $package_key \ - -object_type $object_type \ - -list_name $list_name] - - - # first we make sure all the attribute_values are efficiently cached - # i.e. we only do one trip to the database, instead of one for - # each object in the multirow - set object_id_list "" - template::multirow foreach $multirow { - lappend object_id_list [set $key] + if { $format != "html" } { + set format "text" } - if { [exists_and_not_null object_id_list] } { - ams::object::attribute::values_batch_process -object_id_list $object_id_list + if { [empty_string_p $list_names] && [empty_string_p $list_name] } { + ad_return_complaint 1 "[_ ams.you_must_provide_list_name]" + ad_script_abort } - # now we extend the multirow with the ams_attribute_names - set ams_attribute_ids [ams::list::ams_attribute_ids -list_id $list_id] - set ams_attribute_names {} - foreach ams_attribute_id $ams_attribute_ids { - set ams_attribute_name [ams::attribute::name -ams_attribute_id $ams_attribute_id] - lappend ams_attribute_names $ams_attribute_name - template::multirow extend $multirow $ams_attribute_name + if { [empty_string_p $list_names] && ![empty_string_p $list_name] } { + set list_names $list_name } - # now we populate the multirow with ams_attribute_values - template::multirow foreach $multirow { - # first we set a null value for all ams_attribute_names - # since the ams::object::attribute::values proc only - # returns those ams_attribute_values that do not - # have a null value - foreach ams_attribute_name ams_attribute_names { - set [set $ams_attribute_name] {} - } - ams::object::attribute::values -vars -object_id [set $key] + foreach l_name $list_names { + set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $l_name] + if {![empty_string_p $list_id]} { + lappend list_ids $list_id + } } -} + # To use in the query + set list_ids [template::util::tcl_to_sql_list $list_ids] + if { [exists_and_not_null list_ids] } { + set values [list] + set heading "" + set html_opt "" + + # Control list to know which attributes are already in the + # elements list so we don't en up with duplicates + set control_list [list] + + set all_attributes [db_list_of_lists select_values " "] + + foreach attribute $all_attributes { + set attribute_id [lindex $attribute 0] + if { [string equal [lsearch $control_list $attribute_id] "-1"] } { + lappend control_list $attribute_id + set section_heading [lindex $attribute 1] + set html_options [lindex $attribute 2] + set attribute_name [lindex $attribute 3] + set pretty_name [lindex $attribute 4] + set widget [lindex $attribute 5] + set value [lindex $attribute 6] + + set val [list] + if { [regexp "\{text/.*\}" $value value_format] } { + lappend val [lindex $value_format 0] + lappend val [list [string range $value [expr [string length $value_format] + 1] [string length $value]]] + } else { + set val $value + } + + if { [exists_and_not_null section_heading] } { + set heading $section_heading + } + + if { [exists_and_not_null html_options] } { + set html_opt $html_options + } -namespace eval ams::object {} + if { [exists_and_not_null value] } { + lappend values $heading $attribute_name $pretty_name [ams::widget \ + -widget $widget \ + -request "value_${format}" \ + -attribute_name $attribute_name \ + -attribute_id $attribute_id \ + -value $value \ + -locale $locale] $html_opt -namespace eval ams::object::attribute {} + ns_log Notice "$attribute_name ($attribute_id):: $value" + } - - - -ad_proc -private ams::object::attribute::value_memoize { - -object_id:required - -ams_attribute_id:required - -attribute_value:required -} { - memoize an ams::object::attribute::value -} { - if { [string is true [util_memoize_cached_p [list ams::object::attribute::values_not_cached -object_id $object_id]]] } { - array set $object_id [util_memoize [list ams::object::attribute::values_not_cached -object_id $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 $object_id] [array get ${object_id}] -} - -ad_proc -public ams::object::attribute::value { - -object_id:required - -ams_attribute_id:required -} { -} { - ams::object::attribute::values -array $object_id -object_id $object_id - if { [info exists ${object_id}($ams_attribute_id)] } { - return ${object_id}($ams_attribute_id) + ns_log Notice "$attribute_name ($attribute_id):: $value" + } + } + return $values } else { - return {} + return [list] } } -ad_proc -public ams::object::attribute::values { - -object_id:required - {-ids:boolean} - {-vars:boolean} - {-array ""} -} { - @param ids - if specified we will return the ams_attribute_id instead of the attribute_name - @param array - if specified the attribute values are returned in the given array - @param vars - if sepecified the attribute values vars are returned to the calling environment - if neither array nor vars are specified then a list is returned -} { - set attribute_values_list [util_memoize [list ams::object::attribute::values_not_cached -object_id $object_id]] - if { !$ids_p } { - set attribute_values_list_with_names "" - foreach { key value } $attribute_values_list { - lappend attribute_values_list_with_names [ams::attribute::name -ams_attribute_id $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 { $vars_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 { +ad_proc -public ams::value { -object_id:required + {-attribute_id ""} + {-attribute_name ""} + {-format "html"} + {-locale ""} } { + Return the value of an attribute for a certain object. You can + provide either the attribute_id or the attribute_name. Cached. + + @param object_id The object for which the value is stored + @param attribute_id The attribute_id of the attribute for which the value is retrieved + @param attribute_name Alternatively the attribute_name for the attribute + @return + @error } { - ams::object::attribute::values_batch_process -object_id_list $object_id - if { [string is true [util_memoize_cached_p [list ams::object::attribute::values_not_cached -object_id $object_id]]] } { - return [util_memoize [list ams::object::attribute::values_not_cached -object_id $object_id]] - } else { - return {} - } + return [util_memoize [list ams::value_not_cached \ + -object_id $object_id \ + -attribute_id $attribute_id \ + -attribute_name $attribute_name \ + -format $format \ + -locale $locale]] } - -ad_proc -private ams::object::attribute::values_flush { +ad_proc -public ams::value_not_cached { -object_id:required + -attribute_id + -attribute_name + {-format "html"} + {-locale ""} } { + Return the value of an attribute for a certain object. You can + provide either the attribute_id or the attribute_name + + @author Malte Sussdorff (sussdorff@sussdorff.de) + @creation-date 2005-07-22 + + @param object_id The object for which the value is stored + + @param attribute_id The attribute_id of the attribute for which the value is retrieved + + @param attribute_name Alternatively the attribute_name for the attribute + + @return + + @error } { - return [util_memoize_flush [list ams::object::attribute::values_not_cached -object_id $object_id]] -} - - -ad_proc -private ams::object::attribute::values_batch_process { - -object_id_list:required -} { - @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_id_list { - if { [string is false [util_memoize_cached_p [list ams::object::attribute::values -object_id $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 -list $objects_to_cache] - db_foreach get_attr_values "" { - switch [ams::attribute::storage_type -ams_attribute_id $ams_attribute_id] { - telecom_number { - set attribute_value $telecom_number_string - } - postal_address { - set attribute_value $address_string - } - ams_options { - set attribute_value $options_string - } - 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_id_list { - util_memoize_seed [list ams::object::attribute::values_not_cached -object_id $object_id_from_list] [array get ${object_id_from_list}] - } - } -} - - - -namespace eval ams::object::revision {} - - -ad_proc -public ams::object::revision::new { - {-package_id ""} - -object_id:required -} { - 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 -public ams::list::get { - -list_id:required - -array:required -} { - Get the info on an ams_attribute -} { - upvar 1 $array row - db_1row select_list_info {} -column_array row -} - -ad_proc -private ams::list::ams_attribute_ids_not_cached { - -list_id:required -} { - 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_ids {}] -} - -ad_proc -private ams::list::ams_attribute_ids { - -list_id:required -} { - 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 $list_id]] -} - -ad_proc -private ams::list::ams_attribute_ids_flush { - -list_id:required -} { - 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 $list_id]] -} - - - -ad_proc -private ams::list::exists_p { - -package_key:required - -object_type:required - -list_name:required -} { - 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 -} { - set list_id [ams::list::get_list_id_not_cached -package_key $package_key -object_type $object_type -list_name $list_name] - if { [exists_and_not_null list_id] } { - return 1 + if {[exists_and_not_null attribute_id]} { + set where_clause "and aa.attribute_id = :attribute_id" } else { - return 0 + set where_clause "and aa.attribute_name = :attribute_name" } -} - -ad_proc -private ams::list::flush { - -package_key:required - -object_type:required - -list_name:required -} { - flush all inte info we have on an ams_list - - @return 1 if the list exists for this object_type and package_key and 0 if the does not exist -} { - ams::list::ams_attribute_ids_flush -list_id [ams::list::get_list_id_not_cached -package_key $package_key -object_type $object_type -list_name $list_name] - ams::list::get_list_id_flush -package_key $package_key -object_type $object_type -list_name $list_name -} - -ad_proc -private ams::list::get_list_id { - -package_key:required - -object_type:required - -list_name:required -} { - return the list_id for the given parameters. Chached. - - @return list_id if none exists then it returns blank -} { - return [util_memoize [list ams::list::get_list_id_not_cached -package_key $package_key -object_type $object_type -list_name $list_name]] -} - - -ad_proc -private ams::list::get_list_id_not_cached { - -package_key:required - -object_type:required - -list_name:required -} { - 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 -private ams::list::get_list_id_flush { - -package_key:required - -object_type:required - -list_name:required -} { - - flush the memorized list_id for the given parameters. - - @return list_id if none exists then it returns blank -} { - return [util_memoize_flush [list ams::list::get_list_id_not_cached -package_key $package_key -object_type $object_type -list_name $list_name]] -} - -ad_proc -public ams::list::new { - {-list_id ""} - -package_key:required - -object_type:required - -list_name:required - -pretty_name: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 {[db_0or1row select_value {}]} { + return [ams::widget -widget $widget -request "value_${format}" -attribute_name $attribute_name -attribute_id $attribute_id -value $value -locale $locale] + } else { + return "" } - if { ![exists_and_not_null description] } { - set description_mime_type "" - } - set lang_key "ams.$package_key\:$object_type\:$list_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\:$list_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 package_key object_type list_name pretty_name description description_mime_type } - set list_id [package_instantiate_object -extra_vars $extra_vars ams_list] - - return $list_id } - -namespace eval ams::list::attribute {} - -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 -} { - if { ![exists_and_not_null sort_order] } { - set sort_order [expr 1 + [db_string get_highest_sort_order {} -default "0"]] - } - return [db_exec_plsql ams_list_attribute_map {}] -} - -ad_proc -public ams::list::attribute::unmap { - -list_id:required - -ams_attribute_id:required -} { - Unmap an ams option from an ams list -} { - db_dml ams_list_attribute_unmap {} -} - -ad_proc -public ams::list::attribute::required { - -list_id:required - -ams_attribute_id:required -} { - Specify and ams_attribute as required in an ams list -} { - db_dml ams_list_attribute_required {} -} - -ad_proc -public ams::list::attribute::optional { - -list_id:required - -ams_attribute_id:required -} { - Specify and ams_attribute as optional in an ams list -} { - db_dml ams_list_attribute_optional {} -} - - - - - - - - - - - - -namespace eval ams::util {} - - - -ad_proc -public ams::util::sqlify_list { - -list:required -} { - set output_list {} - foreach item $list { - if { [exists_and_not_null output_list] } { - append output_list ", " - } - regsub -all {'} $item {''} item - append output_list "'$item'" - } - return $output_list -} Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/ams-widget-procs-postgresql.xql'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.15.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/ams-widget-procs.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/tcl/recurrence-widget-procs.tcl'. Fisheye: No comparison available. Pass `N' to diff? 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 -r1.2 -r1.2.2.1 --- openacs-4/packages/ams/tcl/telecom-number-widget-procs.tcl 27 Oct 2004 03:33:25 -0000 1.2 +++ openacs-4/packages/ams/tcl/telecom-number-widget-procs.tcl 30 Nov 2005 16:21:53 -0000 1.2.2.1 @@ -47,8 +47,25 @@ {location {}} {phone_type_id {}} } { - set telecom_number "$national_number $area_city_code-$subscriber_number\x$extension" - return [ad_text_to_html $telecom_number] + set telecom_number "" + if { [parameter::get_from_package_key -parameter "ForceCountryCodeOneFormatting" -package_key "ams" -default "0"] } { + if { $national_number != "1" } { + set telecom_number "[_ ams.international_dial_code]${national_number}-" + } + } else { + set telecom_number ${national_number} + if { [exists_and_not_null telecom_number] } { append telecom_number "-" } + } + append telecom_number $area_city_code + if { [exists_and_not_null telecom_number] } { append telecom_number "-" } + append telecom_number "$subscriber_number" + if { [exists_and_not_null extension] } { append telecom_number " x$extension" } + set phone_url [parameter::get_from_package_key -parameter "PhoneURL" -package_key "ams" -default ""] + if {[empty_string_p $phone_url]} { + return $telecom_number + } else { + return "$telecom_number" + } } ad_proc -public template::util::telecom_number::acquire { type { value "" } } { @@ -93,17 +110,16 @@ 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] - - if { ![parameter::get -parameter "ForceCountryCodeOneFormatting" -default "0"] } { + if { ![parameter::get_from_package_key -parameter "ForceCountryCodeOneFormatting" -package_key "ams" -default "0"] } { # the number is not required to be formatted in a country code one friendly way # we need to verify that the number does not contain invalid characters set telecom_number_temp "$itu_id$national_number$area_city_code$subscriber_number$extension$sms_enabled_p$best_contact_time" regsub -all " " $telecom_number_temp "" telecom_number_temp ns_log Notice $telecom_number_temp - if { ![regexp {^([0-9]|x|-|\)|\(){1,}$} $telecom_number_temp match telecom_number_temp] } { - set message [_ ams.Telecom_numbers_must_only_contain_numbers_dashes_and_x_es_and_rounded_braces] + if { ![regexp {^([0-9]|x|-|\+|\)|\(){1,}$} $telecom_number_temp match telecom_number_temp] } { + set message [_ ams.lt_Telecom_numbers_must_only_contain] } } else { # we have a number in country code one that must follow certain formatting guidelines @@ -114,7 +130,7 @@ # users know how they are supposed to format numbers. if { ![exists_and_not_null area_city_code] || ![exists_and_not_null national_number] } { - set message [_ ams.Telecom_numbers_in_country_code_one_must_be_formatted_like_AAA-SSS-SSSSxXXXX_out_of_country_like_011-CCC-AAAA-SSSS-SSSxXXXX] + set message [_ ams.lt_Telecom_numbers_in_country_code] } } @@ -145,7 +161,7 @@ # we need to seperate out the returned value into individual elements for a single box entry widget set number [string trim [ns_queryget $element_id.summary_number]] - if { ![parameter::get -parameter "ForceCountryCodeOneFormatting" -default "0"] } { + if { ![parameter::get_from_package_key -parameter "ForceCountryCodeOneFormatting" -package_key "ams" -default "0"] } { # we need to verify that the number is formatted correctly # if yes we seperate the number into various elements set subscriber_number $number @@ -202,9 +218,9 @@ } { 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 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] @@ -252,12 +268,15 @@ @param what the name of the property. Must be one of:
  • itu_id (synonyms street_telecom_number, street) -
  • subscriber_number (synonyms zip_code, zip)
  • national_number (synonyms city, town)
  • area_city_code (synonyms state, province) +
  • subscriber_number (synonyms zip_code, zip)
  • extension (synonym country)
  • addtional_text (this is not implemented in the default US widget)
  • best_contact_time (this is not implemented in the default US widget) +
  • sms_enabled_p (this is not implemented in the default US widget) +
  • location (this is not implemented in the default US widget) +
  • phone_type_id (this is not implemented in the default US widget)
  • html_view - this returns an nice html formatted view of the telecom_number
@param telecom_number_list a telecom_number datatype value, usually created with ad_form. @@ -301,7 +320,7 @@ 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] + return [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] } 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'." @@ -325,9 +344,9 @@ 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 subscriber_number [template::util::telecom_number::get_property subscriber_number $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)] @@ -376,7 +395,7 @@ } else { # Display mode if { [info exists element(value)] } { - append output [template::util::telecom_number::get_property html_view $element(value)] + append output "[template::util::telecom_number::get_property html_view $element(value)]" append output "" append output "" append output "" Index: openacs-4/packages/ams/www/attribute-add-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/attribute-add-2.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/attribute-add-2.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/attribute-add-2.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -16,8 +16,8 @@ acs_object_type::get -object_type $object_type -array "object_info" -set title "Define Options" -set context [list [list objects Objects] [list "object?object_type=$object_type" $object_info(pretty_name)] [list "attribute-add?object_type=$object_type" "Add Attribute"] $title] +set title "[_ ams.Define_Options]" +set context [list [list objects Objects] [list "object?object_type=$object_type" $object_info(pretty_name)] [list "attribute-add?object_type=$object_type" "[_ ams.Add_Attribute]"] $title] db_1row select_widget_pretty_and_storage_type { select storage_type from ams_widgets where widget_name = :widget_name } @@ -28,10 +28,10 @@ if { [exists_and_not_null list_id] } { set return_url "list-attributes-map?[export_vars -url {ams_attribute_id list_id}]" - set user_message "AMS Attribute $pretty_name Created and Mapped." + set user_message "[_ ams.lt_AMS_Attribute_a_hrefa]" } else { set return_url "object?[export_vars -url {object_type}]" - set user_message "AMS Attribute $pretty_name Created." + set user_message "[_ ams.lt_AMS_Attribute_a_hrefa_1]" } @@ -59,15 +59,15 @@ {ams_attribute_id:key} {list_id:integer(hidden)} {object_type:text(hidden)} - {widget_name:text(inform) {label "Widget"}} - {attribute_name:text(inform) {label "Attribute Name"}} - {pretty_name:text(inform) {label "Pretty Name"}} - {pretty_plural:text(inform) {label "Pretty Plural"}} + {widget_name:text(inform) {label "[_ ams.Widget_1]"}} + {attribute_name:text(inform) {label "[_ ams.Attribute_Name]"}} + {pretty_name:text(inform) {label "[_ ams.Pretty_Name_1]"}} + {pretty_plural:text(inform) {label "[_ ams.Pretty_Plural_1]"}} } if { [exists_and_not_null description] } { ad_form -extend -name attribute_form -form { - {description:text(inform) {label "Description"}} + {description:text(inform) {label "[_ ams.Description]"}} } } else { ad_form -extend -name attribute_form -form { @@ -76,15 +76,15 @@ } ad_form -extend -name attribute_form -form { - {option1:text {label "Option 1"} {html {size 50}}} - {option2:text,optional {label "Option 2"} {html {size 50}}} - {option3:text,optional {label "Option 3"} {html {size 50}}} - {option4:text,optional {label "Option 4"} {html {size 50}}} - {option5:text,optional {label "Option 5"} {html {size 50}}} - {option6:text,optional {label "Option 6"} {html {size 50}}} - {option7:text,optional {label "Option 7"} {html {size 50}}} - {option8:text,optional {label "Option 8"} {html {size 50}}} - {option9:text,optional {label "Option 9"} {html {size 50}} {help_text {If you need to add more options you will be able to do so by editing this attributes details}}} + {option1:text {label "[_ ams.Option_1]"} {html {size 50}}} + {option2:text,optional {label "[_ ams.Option_2]"} {html {size 50}}} + {option3:text,optional {label "[_ ams.Option_3]" } {html {size 50}}} + {option4:text,optional {label "[_ ams.Option_4]" } {html {size 50}}} + {option5:text,optional {label "[_ ams.Option_5]"} {html {size 50}}} + {option6:text,optional {label "[_ ams.Option_6]"} {html {size 50}}} + {option7:text,optional {label "[_ ams.Option_7]"} {html {size 50}}} + {option8:text,optional {label "[_ ams.Option_8]"} {html {size 50}}} + {option9:text,optional {label "[_ ams.Option_9]"} {html {size 50}} {help_text {If you need to add more options you will be able to do so by editing this attributes details}}} } -new_request { } -edit_request { } -validate { Index: openacs-4/packages/ams/www/attribute-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/attribute-add.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/attribute-add.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/attribute-add.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -4,44 +4,193 @@ @creation-date 2004-07-28 @cvs-id $Id$ } { + {return_url:optional ""} + {return_url_label:optional ""} + {list_id:optional ""} {object_type:notnull} - {list_id:integer} + {widget:optional ""} + {attribute_name:optional ""} } acs_object_type::get -object_type $object_type -array "object_info" -set title "Add Attribute" -set context [list [list objects Objects] [list "object?object_type=$object_type" $object_info(pretty_name)] "Add Attribute"] +set title "[_ ams.Add_Attribute]" +set context [list [list objects Objects] [list "object?object_type=$object_type" $object_info(pretty_name)] "[_ ams.Add_Attribute]"] -set widget_options " [db_list_of_lists select_widgets { select widget_name, widget_name from ams_widgets order by widget_name } ]" - - ad_form -name attribute_form -form { {ams_attribute_id:key} - {list_id:integer(hidden)} + {return_url:text(hidden),optional} + {return_url_label:text(hidden),optional} + {list_id:integer(hidden),optional} {object_type:text(hidden)} - {widget_name:text(multiselect) {label "Widget"} {options $widget_options } {help_text {Widgets descriptions are available}}} - {attribute_name:text {label "Attribute Name"} {html {size 30 maxlength 100}} {help_text {This name must be lower case, contain only letters and underscores, and contain no spaces}}} - {pretty_name:text {label "Pretty Name"} {html {size 30 maxlength 100}}} - {pretty_plural:text {label "Pretty Plural"} {html {size 30 maxlength 100}}} - {description:text(textarea),optional {label "Description"} {html {cols 55 rows 4}}} -} -new_request { -} -edit_request { -} -validate { - # i need to add validation that the attribute isn't already in the database - { attribute_name - { [::regexp {^([0-9]|[a-z]|\_){1,}$} $attribute_name match attribute_name_validate] } - "You have used invalid characters." + {mode:text(hidden),optional} + {widget:text(radio),optional {label "[_ ams.Widget_1]"} {options {[lsort [::ams::widget_list]]}}} + {attribute_name:text,optional {label "[_ ams.Attribute_Name]"} {html {size 30 maxlength 100}} {help_text {This name must be lower case, contain only letters and underscores, and contain no spaces. If not specified one will be generated for you.}}} + {pretty_name:text,optional {label "[_ ams.Pretty_Name_1]"} {html {size 30 maxlength 100}}} + {pretty_plural:text,optional {label "[_ ams.Pretty_Plural_1]"} {html {size 30 maxlength 100}}} +} + + +#if { [ams::widget_has_options_p -widget $widget] } { +# foreach elemement [list option1 option2 option3 option4 option4] { +# ::template::element::set_properties attribute_form $element -widget text +# } +#} +if { [ams::widget_has_options_p -widget $widget] } { + set default_number_of_options 5 + set option_fields_count $default_number_of_options + set i 1 + set elements [list] + lappend elements [list option_fields_count:integer(hidden) [list value $option_fields_count]] +# lappend elements [list options_on_last_screen:integer(hidden),optional] + while { $i <= $option_fields_count } { + set element [list option${i}:text(text),optional [list label "[_ ams.Option] $i"] [list html [list size 50]]] + if { $i == $option_fields_count } { + lappend element [list help_text "[_ ams.lt_If_you_need_to_add_mo]"] + } + if { $i == 1 } { + lappend element [list section "[_ ams.Predefined_Options]"] + } + lappend elements $element + incr i } - { attribute_name - { ![::attribute::exists_p $object_type $attribute_name] } - "Attribute $attribute_name already exists for $object_info(pretty_name)." + ad_form -extend -name attribute_form -form $elements +} + + + +ad_form -extend -name attribute_form -on_request { + set mode "new" + if { [::attribute::exists_p -convert_p 0 $object_type $attribute_name] } { + # this attribute already exists - so we are in "edit" mode for + ::template::element::set_properties attribute_form attribute_name -mode display + db_1row get_attr_info { select pretty_name, pretty_plural from acs_attributes where attribute_name = :attribute_name and object_type = :object_type } + set mode "edit" } + if { [exists_and_not_null widget] } { + if { [string is false [ams::widget_proc_exists_p -widget $widget]] } { + ad_return_error "[_ ams.lt_There_was_a_problem_w]" "[_ ams.lt_The_widget_specified_]" + } + ::template::element::set_properties attribute_form widget -widget select -mode display + } + set option_on_last_screen 1 +#::template::element set_properties attribute_form pretty_plural -widget hidden +# foreach field [list attribute_name pretty_name pretty_plural] { +# ::template::element set_properties attribute_form $field -mode display +# } } -on_submit { -} -new_data { -} -edit_data { + ams::widgets_init + if { [exists_and_not_null attribute_name] } { + if { [string is false [::regexp {^([0-9]|[a-z]|\_){1,}$} $attribute_name match attribute_name_matcher]] } { + ::template::form::set_error attribute_form attribute_name "[_ ams.lt_You_have_used_invalid]" + } else { + ::template::element::set_properties attribute_form attribute_name -mode display + } + } else { + if { [exists_and_not_null pretty_name] } { + set attribute_name [util_text_to_url -replacement "_" -text $pretty_name] + set attribute_name_generated_p 1 + ::template::element::set_value attribute_form attribute_name $attribute_name + } + } + set required_fields [list widget pretty_name pretty_plural] + if { [exists_and_not_null option_fields_count] } { + lappend required_fields "option1" + } + foreach required_field $required_fields { + if { [string is false [exists_and_not_null ${required_field}]] } { + ::template::form::set_error attribute_form $required_field "[::template::element::get_property attribute_form $required_field label] is required" + } + } + + + # Replace the pretty_name and pretty_plural with the message key, so it is inserted correctly in the database +# set pretty_name [lang::util::convert_to_i18n -text $pretty_name -prefix $object_type] +# set pretty_plural [lang::util::convert_to_i18n -text $pretty_plural -prefix $object_type] + + if { [exists_and_not_null widget] } { + ::template::element::set_properties attribute_form widget -widget select -mode display + } + if { $mode == "new" } { + if { [::attribute::exists_p -convert_p 0 $object_type $attribute_name] } { + if { [exists_and_not_null attribute_name_generated_p] } { + set message "[_ ams.lt_The_attribute_name_au]" + } else { + set message "[_ ams.lt_This_attribute_name_a]" + } + ::template::element::set_error attribute_form attribute_name $message + ::template::element::set_properties attribute_form attribute_name -mode edit + } + } +# ::template::form::set_error attribute_form attribute_name "$mode $attribute_name $object_type" + +# element::create attribute_form change_widget -datatype text -widget submit -label "Change Widget" +# { ![::attribute::exists_p $object_type $attribute_name] } +# "Attribute $attribute_name already exists for $object_info(pretty_name)." + +# if { [exists_and_not_null option_fields_count] } { +# if { xists_and_not_null options_on_last_screen] && [string is false [exists_and_not_null option1]] } { +# ::template::form::set_error attribute_form option1 "Option 1 is required" +# } else { +# ::template::element::set_value attribute_form options_on_last_screen 1 +# } +# } + + + if { [::template::form::is_valid attribute_form] } { + + + db_transaction { + # the form has passed all validation blocks +# ::template::element::set_error attribute_form attribute_name "valid" + if { $mode == "new" } { + set attribute_id [attribute::new \ + -object_type $object_type \ + -attribute_name $attribute_name \ + -datatype [::ams::widget -widget $widget -request "widget_datatypes"] \ + -pretty_name $pretty_name \ + -pretty_plural $pretty_plural] + set dynamic_p 1 + } else { + set attribute_id [attribute::id \ + -object_type $object_type \ + -attribute_name $attribute_name] + set dynamic_p 0 + } + ams::attribute::new \ + -attribute_id $attribute_id \ + -ams_attribute_id $ams_attribute_id \ + -widget $widget \ + -dynamic_p $dynamic_p + + if { [ams::widget_has_options_p -widget $widget] && [exists_and_not_null option_fields_count] } { + set i 1 + while { $i <= $option_fields_count } { + set option [set "option${i}"] + if { [exists_and_not_null option] } { + ams::option::new \ + -attribute_id $attribute_id \ + -option $option + } + incr i + } + } + } + } else { + break + } } -after_submit { - ad_returnredirect "attribute-add-2?[export_vars -url {ams_attribute_id object_type widget_name attribute_name pretty_name pretty_plural description list_id}]" + if { [exists_and_not_null list_id] } { + ams::list::attribute::map -list_id $list_id -attribute_id $attribute_id + ams::list::get -list_id $list_id -array list_info + set list_name $list_info(list_name) + set object_type $list_info(object_type) + set package_key $list_info(package_key) + set return_url [export_vars -base "list" -url {list_name object_type package_key return_url return_url_label}] + } else { + set return_url [export_vars -base "object" -url {object_type return_url return_url_label}] + } + ad_returnredirect -message "$pretty_name [_ ams.has_been_added_as_an_attribute_to] $object_type" $return_url ad_script_abort } Index: openacs-4/packages/ams/www/attribute-option-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/attribute-option-delete.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/attribute-option-delete.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/attribute-option-delete.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -9,17 +9,29 @@ } { option_id:integer,notnull + {attribute_id ""} } -validate { option_has_no_entries -requires {option_id} { - if { ![string match [db_string get_count { select count(*) from ams_option_map where option_id = :option_id } -default {0}] {0}] } { - ad_complain {You cannot delete an option that already has entries on it} - } + if {[empty_string_p $attribute_id]} { + if { ![string match [db_string get_count { select count(*) from ams_option_types where option_id = :option_id } -default {0}] {0}] } { + ad_complain [_ ams.lt_You_cannot_delete_an_] + } + } } } -db_1row get_option_info { select * from ams_options where option_id = :option_id } +if {[empty_string_p $attribute_id]} { -db_dml delete_option { delete from ams_options where option_id = :option_id } + # Delete the option for good + + db_1row get_option_info { select * from ams_options where option_id = :option_id } + db_dml delete_option { delete from ams_options where option_id = :option_id } +} else { + + # Just unmap the option + + db_dml unmap_option { delete from ams_option_types where option_id = :option_id and attribute_id = :attribute_id } +} -ad_returnredirect -message "Option Deleted" "attribute?[export_vars -url {ams_attribute_id}]" +ad_returnredirect -message "[_ ams.Option_Deleted]" "attribute?[export_vars -url {attribute_id}]" Index: openacs-4/packages/ams/www/attribute-options-update.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/attribute-options-update.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/attribute-options-update.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/attribute-options-update.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -1,51 +1,56 @@ ad_page_contract { - Update sort order @author Matthew Geddert openacs@geddert.com @creation-date 2004-07-28 @cvs-id $Id$ - - } { option:array sort_key:array - ams_attribute_id:integer,notnull + attribute_id:integer,notnull } -# first we check to see if there are new options. -# if yes we add them + +# first we check to see if there are new options. if yes we add them + foreach option_key [list new1 new2 new3] { set option_string [string trim $option(${option_key})] - if { [exists_and_not_null option_string] } { - set option_id [ams::option::new -ams_attribute_id $ams_attribute_id -option $option_string] + if {[exists_and_not_null option_string]} { + + set option_id [ams::option::new \ + -attribute_id $attribute_id \ + -option $option_string] + set sort_key(${option_id}) $sort_key(${option_key}) } } -# now that all the options are in the database we get the "old" sort order -# if not value for sort_key is provided we will keep the same order as before -set option_ids [db_list get_option_ids { select option_id from ams_options where ams_attribute_id = :ams_attribute_id order by sort_order }] +# now that all the options are in the database we get the "old" sort +# order if not value for sort_key is provided we will keep the same +# order as before -# first we get the highest sort_order so variables without a sort_order can be given one +set option_ids [db_list get_option_ids {select option_id from ams_option_types where attribute_id = :attribute_id order by sort_order}] + +# first we get the highest sort_order so variables without a +# sort_order can be given one + set highest_sort 0 foreach option_id $option_ids { - if { $sort_key(${option_id}) > $highest_sort } { + if {$sort_key(${option_id}) > $highest_sort} { set highest_sort $sort_key(${option_id}) - } + } } - db_transaction { foreach option_id $option_ids { set sort_order $sort_key(${option_id}) incr highest_sort - db_dml update_sort_order { update ams_options set sort_order = :highest_sort where sort_order = :sort_order and ams_attribute_id = :ams_attribute_id } - if { ![exists_and_not_null sort_order] } { + db_dml update_sort_order {update ams_option_types set sort_order = :highest_sort where sort_order = :sort_order and attribute_id = :attribute_id} + if {![exists_and_not_null sort_order]} { incr highest_sort 1 - set sort_order $highest_sort + set sort_order $highest_sort } - db_dml update_sort_order { update ams_options set sort_order = :sort_order where option_id = :option_id } + db_dml update_sort_order {update ams_option_types set sort_order = :sort_order where option_id = :option_id} } } -ams::attribute::flush -ams_attribute_id $ams_attribute_id -ad_returnredirect -message "Options Updated" "attribute?[export_vars -url {ams_attribute_id}]" +ad_returnredirect -message "[_ ams.Options_Updated]" "attribute?[export_vars \ +-url {attribute_id}]" Index: openacs-4/packages/ams/www/attribute.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/attribute.adp,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/attribute.adp 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/attribute.adp 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -3,10 +3,13 @@ @title@@context@ -

Pretty Name: @pretty_name@

-

Pretty Plural: @pretty_plural@

-

Widget: @attribute_info.widget_name@

+

#ams.Attribute_Name# @attribute_info.attribute_name@ +

#ams.Pretty_Name# @attribute_info.pretty_name@ Edit

+

#ams.Pretty_Plural# @attribute_info.pretty_plural@ Edit

+

#ams.Widget# @attribute_info.widget@

- + + + Index: openacs-4/packages/ams/www/attribute.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/attribute.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/attribute.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/attribute.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -4,29 +4,27 @@ @creation-date 2004-07-28 @cvs-id $Id$ - } { - {ams_attribute_id:notnull} + {attribute_id:notnull} orderby:optional } -ams::attribute::get -ams_attribute_id $ams_attribute_id -array "attribute_info" +#db_1row get_attribute_info {} +ams::attribute::get -attribute_id $attribute_id -array "attribute_info" acs_object_type::get -object_type $attribute_info(object_type) -array "object_info" -set pretty_name [_ $attribute_info(pretty_name)] -set pretty_plural [_ $attribute_info(pretty_plural)] -set title $pretty_name +set pretty_name_url [ams::util::edit_lang_key_url -message $attribute_info(pretty_name)] +set pretty_plural_url [ams::util::edit_lang_key_url -message $attribute_info(pretty_plural)] +set title $attribute_info(pretty_name) set context [list [list objects Objects] [list "object?object_type=$attribute_info(object_type)" $object_info(pretty_name)] $title] - - list::create \ -name options \ -multirow options \ -key option_id \ - -row_pretty_plural "Options" \ + -row_pretty_plural "[_ ams.Options]" \ -checkbox_name checkbox \ -selected_format "normal" \ -class "list" \ @@ -35,15 +33,15 @@ -pass_properties { } -actions { } -bulk_action_export_vars { - ams_attribute_id + attribute_id } -bulk_actions { - "Update" "attribute-options-update" "Update Options" + "#acs-kernel.common_Update#" "attribute-options-update" "#ams.Update_Options#" } -elements { edit { label {} } option { - label "Option" + label "[_ ams.Option]" display_template { @options.option@ @@ -53,16 +51,20 @@ } } + pretty_name { + label "[_ ams.Pretty_Name]" + } sort_order { - label "Sort Order" + label "[_ ams.Sort_Order]" display_template { } } actions { label "" display_template { - Delete + Edit + Delete } } } -filters { @@ -79,6 +81,7 @@ layout table row { option {} + pretty_name {} sort_order {} actions {} } @@ -88,42 +91,27 @@ set sort_count 10 set sort_key_count 10000 -db_multirow -extend { sort_order sort_key } options select_options { - select option_id, option, - CASE WHEN ( select '1' from ams_option_map where ams_option_map.option_id = ams_options.option_id limit 1 ) IS NULL THEN 0 ELSE 1 END as in_use_p - from ams_options - where ams_attribute_id = :ams_attribute_id +db_multirow -extend { sort_order sort_key delete_url edit_url } options select_options { + select option_id, option, title as pretty_name, + CASE WHEN ( select '1' from ams_options where ams_options.option_id = ams_option_types.option_id limit 1 ) IS NULL THEN 0 ELSE 1 END as in_use_p + from ams_option_types aot, acs_objects o + where attribute_id = :attribute_id + and aot.option_id = o.object_id order by sort_order } { - set option [_ $option] set sort_order $sort_count set sort_key $sort_key_count incr sort_count 10 incr sort_key_count 1 + set delete_url [export_vars -base "attribute-option-delete" -url {attribute_id option_id}] + set edit_url [ams::util::edit_lang_key_url -message $option] } - -set sort_order $sort_count -set sort_key $sort_key_count -template::multirow append options {new1} {} 1 $sort_count $sort_key -template::multirow append options {new2} {} 1 [incr sort_count 10] [incr sort_key 1] -template::multirow append options {new3} {} 1 [incr sort_count 10] [incr sort_key 1] - - - - - - - - - - - - - - - - - - +if { [template::multirow size options] > 0 } { + set sort_order $sort_count + set sort_key $sort_key_count + template::multirow append options {new1} {} 1 $sort_count $sort_key + template::multirow append options {new2} {} 1 [incr sort_count 10] [incr sort_key 1] + template::multirow append options {new3} {} 1 [incr sort_count 10] [incr sort_key 1] +} ad_return_template Index: openacs-4/packages/ams/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/index.adp,v diff -u -r1.3 -r1.3.2.1 --- openacs-4/packages/ams/www/index.adp 30 Oct 2004 00:23:54 -0000 1.3 +++ openacs-4/packages/ams/www/index.adp 30 Nov 2005 16:21:53 -0000 1.3.2.1 @@ -1,9 +1,10 @@ @title@ @context@ - + Index: openacs-4/packages/ams/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/index.tcl,v diff -u -r1.5 -r1.5.2.1 --- openacs-4/packages/ams/www/index.tcl 30 Oct 2004 00:23:54 -0000 1.5 +++ openacs-4/packages/ams/www/index.tcl 30 Nov 2005 16:21:53 -0000 1.5.2.1 @@ -8,95 +8,9 @@ } { } -set title "Attribute Management System" +# MS (2005-05-29): Removed a ton of code that is unnecessary +set title "[_ ams.lt_Attribute_Management_]" set context {} - - - -# Once done comment out the error line -# ad_return_error "You need to specify and valid object id in the packages/ams/www/index.tcl file" "Once done comment out this line." - - - -#set package_key "ams" -#set object_type "ams_list" -#set list_name "ams_list_demo3" -#set pretty_name "The Fields used to Add/Edit a Contact Person" -# -#ams::define_list -package_key $package_key \ -# -object_type $object_type \ -# -list_name $list_name \ -# -pretty_name $pretty_name \ -# -attributes { -# {first_names textbox {First Name(s)} {First Names} required {description {this is my description of first names}}} -# {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}} -# {home_phone telecom_number {Home Phone} {Home Phones}} -# {gender radio {Gender} {Genders} {options {{Male} {Female}}} required} -# } -# -#set object_id [ams::list::get_list_id \ -# -package_key $package_key \ -# -object_type $object_type \ -# -list_name $list_name] -#set object_id "452" -##ad_form -name entry \ -## -form [ams::ad_form::elements -package_key $package_key \ -## -object_type $object_type \ -## -list_name $list_name \ -## -key "object_id"] \ -# -edit_request { -# ams::object::attribute::values -vars -object_id $object_id -# } -on_submit { -# ams::ad_form::save -package_key $package_key \ -# -object_type $object_type \ -# -list_name $list_name \ -# -form_name "entry" \ -# -object_id $object_id -# } -after_submit { -# if { ![exists_and_not_null return_url] } { -# set return_url "./" -# } -# } -# - -#ams_form -package_key $package_key \ -# -object_type $object_type \ -# -list_name $list_name \ -# -form_name "entry" \ -# -object_id $object_id \ -# -return_url "./" -# -# set attr_list [ams::object::attribute::values_flush -object_id $object_id] -#set attr_list [ams::object::attribute::values -object_id $object_id] -# -# -#db_multirow lists get_list { select list_id, pretty_name from ams_lists } -# -#ams::multirow::extend \ -# -package_key $package_key \ -# -object_type $object_type \ -# -list_name $list_name \ -# -multirow "lists" \ -# -key "list_id" -## -##template::multirow extend lists [list first_names last_name home_address first_names] -## -## -#set key_id "list_id" -#template::multirow foreach lists { -# set object_id [set $key_id] -# ams::object::attribute::values -vars -object_id $object_id -#} -## set attr_list $rowcount -#template::multirow foreach lists { -# ns_log Notice "$first_names $last_name $home_address" -#} - - - +set package_id [ad_conn package_id] +set parameters_url [export_vars -base "/shared/parameters" {package_id {return_url [ad_return_url]}}] ad_return_template Index: openacs-4/packages/ams/www/list-add.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-add.adp,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-add.adp 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-add.adp 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -2,10 +2,11 @@ @title@ @context@ -

Note: Adding an AMS List here is primarily for demonstration purposes. In order for AMS Lists to be useful you need to integrated them with your package.

+

#ams.Note# Adding an AMS List here is primarily for demonstration purposes. In order for AMS Lists to be useful you need to integrated them with your package.

+ Index: openacs-4/packages/ams/www/list-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-add.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-add.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-add.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -6,12 +6,17 @@ } { {object_type:notnull} {package_key ""} + {list_name ""} + {pretty_name ""} + {description ""} + {return_url ""} + {return_url_label ""} } acs_object_type::get -object_type $object_type -array "object_info" -set title "Add List" -set context [list [list objects Objects] [list "object?object_type=$object_type" $object_info(pretty_name)] "Add List"] +set title "[_ ams.Add_List]" +set context [list [list objects Objects] [list "object?object_type=$object_type" $object_info(pretty_name)] "[_ ams.Add_List]"] set package_options " [db_list_of_lists select_packages { select package_key, package_key from apm_package_types order by package_key } ]" @@ -21,23 +26,51 @@ ad_form -name list_form -form { {list_id:key} - {package_key:text(select) {label "Package Key"} {options $package_options}} - {object_type:text(inform) {label "Object Type"}} - {list_name:text {label "List Name"} {html {size 30 maxlength 100}} {help_text {This name must be lower case, contain only letters and underscores, and contain no spaces}}} - {pretty_name:text {label "Pretty Name"} {html {size 30 maxlength 100}}} - {pretty_plural:text {label "Pretty Plural"} {html {size 30 maxlength 100}}} - {description:text(textarea),optional {label "Description"} {html {cols 55 rows 4}}} + {package_key:text(select) {label "[_ ams.Package_Key_1]"} {options $package_options}} + {object_type:text(inform) {label "[_ ams.Object_Type_1]"}} + {list_name:text {label "[_ ams.List_Name_1]"} {html {size 30 maxlength 100}} {help_text {[_ ams.lt_This_name_must_be_low]}}} + {pretty_name:text {label "[_ ams.Pretty_Name_1]"} {html {size 30 maxlength 100}}} + {description:text(textarea),optional {label "[_ ams.Description]"} {html {cols 55 rows 4}}} + return_url:text(hidden),optional + return_url_label:text(hidden),optional } -new_request { + set uneditable_attributes [list package_key object_type list_name pretty_name description] + set blank_required_attributes [list] + foreach attribute $uneditable_attributes { + if { [set $attribute] != "" } { + template::element::set_properties list_form $attribute mode display + } else { + if { $attribute != "description" } { + lappend blank_required_attributes $attribute + } + } + } + # if the only blank attribute is description we can create this list (since all the data was + # provided by the request of this page + if { [string is false [exists_and_not_null blank_required_attributes]] } { + util_user_message -replace + ams::list::flush -package_key $package_key -object_type $object_type -list_name $list_name + ams::list::new -package_key $package_key \ + -object_type $object_type \ + -list_name $list_name \ + -pretty_name $pretty_name \ + -description $description \ + -description_mime_type "text/plain" \ + -context_id "" + ams::list::flush -package_key $package_key -object_type $object_type -list_name $list_name + ad_returnredirect "list?[export_vars -url {package_key object_type list_name return_url return_url_label}]" + ad_script_abort + } } -edit_request { } -validate { # i need to add validation that the attribute isn't already in the database { list_name { [::regexp {^([0-9]|[a-z]|\_){1,}$} $list_name match list_name_validate] } - "You have used invalid characters." + "[_ ams.lt_You_have_used_invalid]" } { list_name { ![::ams::list::exists_p -package_key $package_key -object_type $object_type -list_name $list_name] } - "List name $list_name already exists for $object_info(pretty_name)." + "[_ ams.lt_List_name_a_hrefliste]" } } -on_submit { @@ -57,7 +90,7 @@ } -edit_data { } -after_submit { - ad_returnredirect "list?[export_vars -url {package_key object_type list_name}]" + ad_returnredirect "list?[export_vars -url {package_key object_type list_name return_url return_url_label}]" ad_script_abort } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attribute-html-options-postgresql.xql'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attribute-html-options.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attribute-html-options.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attribute-section-heading.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.3.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attribute-section-heading.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/ams/www/list-attributes-map.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-attributes-map.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-attributes-map.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-attributes-map.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -1,17 +1,16 @@ ad_page_contract { - @author Matthew Geddert openacs@geddert.com @creation-date 2004-07-28 @cvs-id $Id$ } { - {ams_attribute_id:integer,multiple} + {attribute_id:integer,multiple} {list_id:integer,notnull} } -foreach ams_attribute_id $ams_attribute_id { - ams::list::attribute::map -list_id $list_id -ams_attribute_id $ams_attribute_id +foreach attribute_id $attribute_id { + ams::list::attribute::map -list_id $list_id -attribute_id $attribute_id } ams::list::get -list_id $list_id -array "list_info" Index: openacs-4/packages/ams/www/list-attributes-optional.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-attributes-optional.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-attributes-optional.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-attributes-optional.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -6,18 +6,20 @@ @cvs-id $Id$ } { - {ams_attribute_id:integer,multiple,notnull} + {attribute_id:integer,multiple,notnull} {list_id:integer,notnull} + return_url:optional + return_url_label:optional } -foreach ams_attribute_id $ams_attribute_id { - ams::list::attribute::optional -list_id $list_id -ams_attribute_id $ams_attribute_id +foreach attribute_id $attribute_id { + ams::list::attribute::optional -list_id $list_id -attribute_id $attribute_id } ams::list::get -list_id $list_id -array "list_info" set package_key $list_info(package_key) set object_type $list_info(object_type) set list_name $list_info(list_name) -ad_returnredirect "list?[export_vars -url {package_key object_type list_name}]" +ad_returnredirect "list?[export_vars -url {package_key object_type list_name return_url return_url_label}]" ad_script_abort Index: openacs-4/packages/ams/www/list-attributes-required.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-attributes-required.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-attributes-required.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-attributes-required.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -6,18 +6,20 @@ @cvs-id $Id$ } { - {ams_attribute_id:integer,multiple,notnull} + {attribute_id:integer,multiple,notnull} {list_id:integer,notnull} + return_url:optional + return_url_label:optional } -foreach ams_attribute_id $ams_attribute_id { - ams::list::attribute::required -list_id $list_id -ams_attribute_id $ams_attribute_id +foreach attribute_id $attribute_id { + ams::list::attribute::required -list_id $list_id -attribute_id $attribute_id } ams::list::get -list_id $list_id -array "list_info" set package_key $list_info(package_key) set object_type $list_info(object_type) set list_name $list_info(list_name) -ad_returnredirect "list?[export_vars -url {package_key object_type list_name}]" +ad_returnredirect "list?[export_vars -url {package_key object_type list_name return_url return_url_label}]" ad_script_abort Index: openacs-4/packages/ams/www/list-attributes-unmap.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-attributes-unmap.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-attributes-unmap.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-attributes-unmap.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -5,18 +5,20 @@ @cvs-id $Id$ } { - {ams_attribute_id:integer,multiple} + {attribute_id:integer,multiple} {list_id:integer,notnull} + return_url:optional + return_url_label:optional } -foreach ams_attribute_id $ams_attribute_id { - ams::list::attribute::unmap -list_id $list_id -ams_attribute_id $ams_attribute_id +foreach attribute_id $attribute_id { + ams::list::attribute::unmap -list_id $list_id -attribute_id $attribute_id } ams::list::get -list_id $list_id -array "list_info" set package_key $list_info(package_key) set object_type $list_info(object_type) set list_name $list_info(list_name) -ad_returnredirect "list?[export_vars -url {package_key object_type list_name}]" +ad_returnredirect "list?[export_vars -url {package_key object_type list_name return_url return_url_label}]" ad_script_abort Fisheye: Tag 1.4.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attributes.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-attributes.xql'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.6.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-code.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.6.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-code.tcl'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-form-preview.adp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.3.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list-form-preview.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/ams/www/list-order-update.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list-order-update.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list-order-update.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list-order-update.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -10,31 +10,66 @@ } { sort_key:array list_id:integer,notnull +} -validate { + ordering_is_valid -requires {sort_key} { + set no_value_supplied [list] + set no_integer_supplied [list] + set used_sort_orders [list] + set doubled_sort_orders [list] + foreach {attribute_id sort_order} [array get sort_key] { + set sort_order [string trim $sort_order] + if { $sort_order == "" } { + lappend no_value_supplied $attribute_id + } elseif { [string is false [string is integer $sort_order]] } { + lappend no_integer_supplied $attribute_id $sort_order + } elseif { [info exists order($sort_order)] } { + lappend doubled_sort_orders $attribute_id $order($sort_order) + } else { + set order($sort_order) $attribute_id + } + } + set error_messages [list] + if { [llength $no_value_supplied] } { + foreach attribute_id $no_value_supplied { + lappend error_messages "[_ ams.No_ordering_integer_was_supplied_for] [attribute::pretty_name -attribute_id $attribute_id]" + } + } + if { [llength $no_integer_supplied] } { + foreach { attribute_id sort_order } $no_integer_supplied { + lappend error_messages "[_ ams.The_ordering_number_is_not_an_integer_for] [attribute::pretty_name -attribute_id $attribute_id]" + } + } + if { [llength $doubled_sort_orders] } { + foreach { one_attribute_id two_attribute_id } $doubled_sort_orders { + lappend error_messages "[_ ams.The_ordering_number_is_the_same_for] [attribute::pretty_name -attribute_id $one_attribute_id] [_ ams.and] [attribute::pretty_name -attribute_id $two_attribute_id]" + } + } + if { [llength $error_messages] > 0 } { + foreach message $error_messages { + ad_complain $message + } + } + } } - -set ams_attribute_ids [db_list get_attribute_ids { select ams_attribute_id from ams_list_attribute_map where list_id = :list_id order by sort_order }] - - -# first we get the highest sort_order so variables without a sort_order can be given one -set highest_sort 0 -set used_sorts [list] -foreach ams_attribute_id $ams_attribute_ids { - if { $sort_key(${ams_attribute_id}) > $highest_sort } { - set highest_sort $sort_key(${ams_attribute_id}) - } +set attribute_order [list] +set sort_key_list [array get sort_key] +foreach {attribute_id sort_order} $sort_key_list { + set order($sort_order) $attribute_id + lappend attribute_order $sort_order } +set ordered_list [lsort -integer $attribute_order] +set highest_sort [db_string get_highest_sort { select sort_order from ams_list_attribute_map where list_id = :list_id order by sort_order desc limit 1 }] +incr highest_sort +set sort_number 1 db_transaction { - foreach ams_attribute_id $ams_attribute_ids { - set sort_order $sort_key(${ams_attribute_id}) - incr highest_sort 1 - db_dml update_sort_order { update ams_list_attribute_map set sort_order = :highest_sort where sort_order = :sort_order and list_id = :list_id } - if { ![exists_and_not_null sort_order] } { - incr highest_sort 1 - set sort_order $highest_sort - } - db_dml update_sort_order { update ams_list_attribute_map set sort_order = :sort_order where ams_attribute_id = :ams_attribute_id and list_id = :list_id } + foreach sort_order $ordered_list { + set attribute_id $order($sort_order) + db_dml update_sort_order { update ams_list_attribute_map set sort_order = :highest_sort where sort_order = :sort_number and list_id = :list_id } + db_dml update_sort_order { update ams_list_attribute_map set sort_order = :sort_number where attribute_id = :attribute_id and list_id = :list_id } + incr highest_sort + incr sort_number } } Index: openacs-4/packages/ams/www/list.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list.adp,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list.adp 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list.adp 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -3,19 +3,29 @@ @context@ -

Package Key: @package_key@

-

Object Type: @object_type@

-

List Name: @list_name@

-

Mapped Attributes

+

+ +@return_url_label@ + +#ams.Preview_Input_Form# +

+

#ams.Package_Key# @package_key@

+

#ams.Object_Type# @object_type@

+

#ams.List_Name# @list_name@

+ +

#ams.Mapped_Attributes#

+ -

Unmapped Attributes

+

#ams.Unmapped_Attributes#

+ Index: openacs-4/packages/ams/www/list.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/list.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/list.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/list.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -10,22 +10,45 @@ package_key:notnull object_type:notnull list_name:notnull + {pretty_name ""} + {description ""} groupby:optional orderby:optional {format "normal"} {status "normal"} + {return_url ""} + {return_url_label "[_ ams.lt_Return_to_Where_You_W]"} } +set provided_return_url $return_url +set provided_return_url_label $return_url_label + +set this_url [export_vars -url -base "list" {package_key object_type list_name }] +set code_url [export_vars -url -base "list-code" {package_key object_type list_name return_url return_url_label}] + + + +if { ![ams::list::exists_p -package_key $package_key -object_type $object_type -list_name $list_name] } { + ad_returnredirect -message "[_ ams.lt_The_list_specified_do]" [export_vars -base "list-add" -url {package_key object_type list_name pretty_name description return_url return_url_label}] + ad_script_abort +} set list_id [ams::list::get_list_id -package_key $package_key -object_type $object_type -list_name $list_name] + + +set create_attribute_url [export_vars -base "attribute-add" -url {object_type list_id return_url return_url_label}] + + + + ams::list::get -list_id $list_id -array "list_info" -set title [_ $list_info(pretty_name)] +set title $list_info(pretty_name) set context [list [list lists Lists] $title] list::create \ -name mapped_attributes \ -multirow mapped_attributes \ - -key ams_attribute_id \ - -row_pretty_plural "Mapped Attributes" \ + -key attribute_id \ + -row_pretty_plural "[_ ams.Mapped_Attributes]" \ -checkbox_name checkbox \ -selected_format $format \ -class "list" \ @@ -34,205 +57,174 @@ -pass_properties { } -actions { } -bulk_actions { - "Answer Required" "list-attributes-required" "Require an answer from the checked attributes" - "Answer Optional" "list-attributes-optional" "An answer from the checked attributes is optional" - "Unmap" "list-attributes-unmap" "Unmap check attributes" - "Update Ordering" "list-order-update" "Update ordering from values in list" + "#ams.Answer_Required#" "list-attributes-required" "#ams.lt_Require_an_answer_fro#" + "#ams.Answer_Optional#" "list-attributes-optional" "#ams.lt_An_answer_from_the_ch#" + "#ams.Unmap#" "list-attributes-unmap" "#ams.lt_Unmap_check_attribute#" + "#ams.Update_Ordering#" "list-order-update" "#ams.lt_Update_ordering_from_#" } -bulk_action_export_vars { list_id } -elements { attribute_name { - label "Attribute" + label "[_ ams.Attribute]" display_col attribute_name } pretty_name { - label "Pretty Name" - display_col pretty_name - link_url_eval $attribute_url + label "[_ ams.Pretty_Name_1]" + display_template { + @mapped_attributes.pretty_name@ (Parent Object Type: @mapped_attributes.object_type@) + } } widget { - label "Widget" + label "[_ ams.Widget_1]" display_col widget link_url_eval widgets } + section_heading { + label "[_ ams.Heading]" + display_col section_heading + } + html_options { + label "[_ ams.Html_options]" + display_col html_options + } action { - label "Action" + label "[_ ams.Action]" display_template { - Unmap + [_ ams.Unmap] + [_ ams.Add_Heading][_ ams.EditDelete_Heading] + [_ ams.Add_Html_options][_ ams.EditDelete_Html] } } answer { - label "Required" + label "[_ ams.Required]" display_template { - + - + } } sort_order { - label "Ordering" + label "[_ ams.Ordering]" display_template { - + } } } -filters { } -groupby { } -orderby { } -formats { normal { - label "Table" + label "[_ ams.Table]" layout table row { checkbox {} + attribute_name {} pretty_name {} sort_order {} answer {} action {} + section_heading {} + html_options {} } } } -# Table "public.ams_lists" -# Column | Type | Modifiers -#-----------------------+-------------------------+----------- -# list_id | integer | not null -# package_key | character varying(100) | not null -# object_type | character varying(1000) | not null -# list_name | character varying(100) | not null -# pretty_name | character varying(200) | not null -# description | character varying(200) | -# description_mime_type | character varying(200) | - -# Table "public.ams_list_attribute_map" -# Column | Type | Modifiers -#------------------+------------------------+----------- -# list_id | integer | not null -# ams_attribute_id | integer | not null -# sort_order | integer | not null -# required_p | boolean | not null -# section_heading | character varying(200) | - - set sort_order_count 10 -db_multirow -extend { sort_order_key attribute_url } mapped_attributes select_mapped_attributes { - select alam.required_p, - alam.section_heading, - ams.ams_attribute_id, - ams.widget_name, - ams.deprecated_p, - acs.attribute_name, - acs.pretty_name, - acs.pretty_plural, - acs.object_type - from ams_list_attribute_map alam, - ams_attributes ams, - acs_attributes acs - where alam.list_id = :list_id - and alam.ams_attribute_id = ams.ams_attribute_id - and ams.attribute_id = acs.attribute_id - order by alam.sort_order -} { - set pretty_name [_ $pretty_name] - set attribute_url "attribute?[export_vars -url {ams_attribute_id}]" +set extend_list [list \ + sort_order_key \ + attribute_url \ + unmap_url \ + heading_url \ + required_url \ + optional_url \ + html_options_url] + +db_multirow -extend $extend_list -unclobber mapped_attributes select_mapped_attributes { } { + set attribute_url "attribute?[export_vars -url {attribute_id}]" set sort_order_key $sort_order_count + set unmap_url [export_vars -base "list-attributes-unmap" -url {list_id attribute_id return_url return_url_label}] + set heading_url [export_vars -base "list-attribute-section-heading" -url {list_id attribute_id return_url return_url_label}] + set required_url [export_vars -base "list-attributes-required" -url {list_id attribute_id return_url return_url_label}] + set optional_url [export_vars -base "list-attributes-optional" -url {list_id attribute_id return_url return_url_label}] + set html_options_url [export_vars \ + -base "list-attribute-html-options" \ + -url {list_id attribute_id}] + incr sort_order_count 10 } - -#---------------------------------------------------------------------- -# List builder -#---------------------------------------------------------------------- - - - - - list::create \ -name unmapped_attributes \ -multirow unmapped_attributes \ - -key ams_attribute_id \ - -row_pretty_plural "Unmapped Attributes" \ + -key attribute_id \ + -row_pretty_plural "[_ ams.Unmapped_Attributes]" \ -checkbox_name checkbox \ -selected_format "normal" \ -class "list" \ -main_class "list" \ -sub_class "narrow" \ -pass_properties { } -actions { - } -bulk_actions { - "Map" "list-attributes-map" "Map the selected attributes" - } -bulk_action_export_vars { - list_id } -elements { attribute_name { - label "Attribute" + label "[_ ams.Attribute]" display_col attribute_name } pretty_name { - label "Pretty Name" + label "[_ ams.Pretty_Name_1]" display_col pretty_name link_url_eval $attribute_url } widget { - label "Widget" - display_col widget_name + label "[_ ams.Widget_1]" + display_col widget link_url_eval widgets } action { - label "Action" + label "[_ ams.Action]" display_template { - Map + + [_ ams.Define_Widget] + + + [_ ams.Map] + } } } -filters { } -groupby { } -orderby { } -formats { normal { - label "Table" + label "[_ ams.Table]" layout table row { - checkbox {} pretty_name {} widget {} action {} } } } +# checkbox {} # This query will override the ad_page_contract value entry_id -db_multirow -extend { attribute_url } -unclobber unmapped_attributes get_unmapped_attributes { - select ams.ams_attribute_id, - ams.widget_name, - ams.deprecated_p, - acs.attribute_name, - acs.pretty_name, - acs.pretty_plural, - acs.object_type - from ams_attributes ams, - acs_attributes acs - where ams.ams_attribute_id not in ( select alam.ams_attribute_id from ams_list_attribute_map alam where alam.list_id = :list_id ) - and ams.attribute_id = acs.attribute_id -} { - set pretty_name [_ $pretty_name] - set attribute_url "attribute?[export_vars -url {ams_attribute_id}]" - +db_multirow -extend { attribute_url attribute_add_url map_url } -unclobber unmapped_attributes get_unmapped_attributes " " { + set attribute_add_url [export_vars -base "attribute-add" -url {object_type attribute_name {return_url $this_url}}] + set attribute_url [export_vars -base "attribute" -url {attribute_id}] + set map_url [export_vars -base "list-attributes" -url {list_id attribute_id return_url return_url_label {command "map"}}] } +set return_url $provided_return_url +set return_url_label $provided_return_url_label ad_return_template - - - - - Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `openacs-4/packages/ams/www/list.xql'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/ams/www/lists.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/lists.adp,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/lists.adp 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/lists.adp 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -3,7 +3,7 @@ @title@ @context@ -

You can create a list by selecting an acs_object. Note that list creation should be done with contracting packages. These lists shows what ams can do for your package.

+

#ams.lt_You_can_create_a_list#

Index: openacs-4/packages/ams/www/lists.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/lists.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/lists.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/lists.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -9,14 +9,14 @@ {orderby "name"} } -set title "AMS Lists" +set title "[_ ams.AMS_Lists]" set context [list $title] list::create \ -name lists \ -multirow lists \ -key list_id \ - -row_pretty_plural "AMS Lists" \ + -row_pretty_plural "[_ ams.AMS_Lists]" \ -checkbox_name checkbox \ -selected_format "normal" \ -class "list" \ @@ -30,28 +30,28 @@ } pretty_name { display_col pretty_name - label "Pretty Name" + label "[_ ams.Pretty_Name_1]" } package_key { display_col package_key - label "Package Key" + label "[_ ams.Package_Key_1]" } list_name { display_col list_name - label "List Name" + label "[_ ams.List_Name_1]" link_url_eval $list_url } object_type { display_col object_type - label "Object Type" + label "[_ ams.Object_Type_1]" link_url_eval $object_url } } -filters { } -groupby { } -orderby { } -formats { normal { - label "Table" + label "[_ ams.Table]" layout table row { package_key {} Index: openacs-4/packages/ams/www/object-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/object-postgresql.xql,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/object-postgresql.xql 30 Oct 2004 00:27:00 -0000 1.1 +++ openacs-4/packages/ams/www/object-postgresql.xql 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -1,25 +1,25 @@ - - - - postgresql7.1 - - - - update contact_attribute_object_map set sort_order = '-1' where object_id = :object_id - - - - - - select attribute_id from contact_attribute_object_map where object_id = :object_id - - - - - - update contact_attribute_object_map set sort_order = :sort_order_temp where object_id = :object_id and attribute_id = :attribute_id - - - - - + + + + postgresql7.1 + + + + update contact_attribute_object_map set sort_order = '-1' where object_id = :object_id + + + + + + select attribute_id from contact_attribute_object_map where object_id = :object_id + + + + + + update contact_attribute_object_map set sort_order = :sort_order_temp where object_id = :object_id and attribute_id = :attribute_id + + + + + Index: openacs-4/packages/ams/www/object.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/object.adp,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/object.adp 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/object.adp 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -5,11 +5,10 @@ -

AMS Attributes

+

#ams.AMS_Attributes#

-

Attributes not managed by AMS

- -

AMS Lists associated with @object_info.pretty_plural@

+

#ams.lt_AMS_Lists_associated_#

+ Index: openacs-4/packages/ams/www/object.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/object.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/object.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/object.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -20,39 +20,33 @@ -name object_attributes \ -multirow object_attributes \ -key attribute_name \ - -row_pretty_plural "AMS Attributes" \ + -row_pretty_plural "[_ ams.AMS_Attributes]" \ -checkbox_name checkbox \ -selected_format "normal" \ -class "list" \ -main_class "list" \ -sub_class "narrow" \ -pass_properties { object_type - } -actions [list "Add" "attribute-add?object_type=$object_type" "Add an AMS Attribute"] \ + } -actions [list "[_ acs-kernel.common_Add]" "attribute-add?object_type=$object_type" "[_ ams.Add_an_AMS_Attribute]"] \ -bulk_actions { } -elements { edit { label {} } pretty_name { display_col pretty_name - label "Pretty Name" + label "[_ ams.Pretty_Name_1]" link_url_eval $ams_attribute_url } attribute_name { display_col attribute_name - label "Attribute Name" - link_url_eval $ams_attribute_url + label "[_ ams.Attribute_Name]" } - widget_name { - display_col widget_name - label "Widget Name" - link_url_eval widgets - } - actions { - label "" + widget { + label "[_ ams.Widget_1]" display_template { - Upgrade to AMS Attribute + [_ ams.Define_Widget]@object_attributes.widget@ } } } -filters { @@ -72,42 +66,35 @@ label attribute_name multirow_cols {ams_attribute_p attribute_name pretty_name} } - widget_name { + widget { label widget_name - multirow_cols {ams_attribute_p widget_name pretty_name attribute_name} + multirow_cols {ams_attribute_p widget pretty_name attribute_name} } } -formats { normal { - label "Table" + label "[_ ams.Table]" layout table row { pretty_name {} attribute_name {} - widget_name {} - actions {} + widget {} } } } db_multirow -extend { ams_attribute_url ams_attribute_p } object_attributes select_object_attributes { - select acs.attribute_name, - acs.pretty_name, - acs.pretty_plural, - acs.attribute_id, - ams.ams_attribute_id, - ams.widget_name - from acs_attributes acs, ams_attributes ams - where acs.object_type = :object_type - and acs.attribute_id = ams.attribute_id + select attribute_name, + pretty_name, + pretty_plural, + attribute_id, + widget + from ams_attributes + where object_type = :object_type + order by upper(pretty_name) } { if { [exists_and_not_null ams_attribute_id] } { set ams_attribute_p 1 } else { set ams_attribute_p 0 } - - if { [exists_and_not_null ams_attribute_id] } { - set ams_attribute_url "attribute?ams_attribute_id=$ams_attribute_id" - } else { - set ams_attribute_url "" - } + set ams_attribute_url "attribute?attribute_id=$attribute_id" if { [lang::message::message_exists_p en_US $pretty_name] } { set pretty_name [_ $pretty_name] } @@ -128,66 +115,9 @@ -# This code lets me setup AMS Attribute Upgrades for Attributes that were not created by AMS -# -# eventually we will allow these attributes to be "upgraded" to ams_attributes. We first need to provision a way -# for them to not be deleted at package drop time, since other packages created these attributes they may need them. -list::create \ - -name non_ams_attributes \ - -multirow non_ams_object_attributes \ - -key attribute_name \ - -row_pretty_plural "Attributes not managed by AMS" \ - -checkbox_name checkbox \ - -selected_format "normal" \ - -class "list" \ - -main_class "list" \ - -sub_class "narrow" \ - -pass_properties { - variable - } -actions { - } -bulk_actions { - } -elements { - pretty_name { - display_col pretty_name - label "Pretty Name" - } - attribute_name { - display_col attribute_name - label "Attribute Name" - } - actions { - label "" - display_template { - Upgrade to AMS Attribute - } - } - } -filters { - object_type {} - } -groupby { - } -orderby { - } -formats { - normal { - label "Table" - layout table - row { - pretty_name {} - attribute_name {} - } - } - } -db_multirow non_ams_object_attributes select_non_ams_object_attributess { - select acs.attribute_name, - acs.pretty_name, - acs.pretty_plural, - acs.attribute_id - from acs_attributes acs - where acs.object_type = :object_type - and acs.attribute_id not in ( select attribute_id from ams_attributes ) -} { -} @@ -203,11 +133,6 @@ - - - - - # AMS Lists associated with this object type list::create \ @@ -285,12 +210,4 @@ - - - - - - - - ad_return_template Index: openacs-4/packages/ams/www/objects.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/objects.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/objects.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/objects.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -9,14 +9,14 @@ {orderby "name"} } -set title "Objects" +set title "[_ ams.Objects]" set context [list $title] list::create \ -name object_types \ -multirow object_types \ -key object_type \ - -row_pretty_plural "Object Types" \ + -row_pretty_plural "[_ ams.Object_Types]" \ -checkbox_name checkbox \ -selected_format "normal" \ -class "list" \ @@ -30,20 +30,20 @@ } pretty_name { display_col pretty_name - label "Pretty Name" + label "[_ ams.Pretty_Name_1]" link_url_eval $object_attributes_url } object_type { display_col object_type - label "Object Type" + label "[_ ams.Object_Type_1]" link_url_eval $object_attributes_url } } -filters { } -groupby { } -orderby { } -formats { normal { - label "Table" + label "[_ ams.Table]" layout table row { pretty_name {} Index: openacs-4/packages/ams/www/widgets.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/widgets.tcl,v diff -u -r1.1 -r1.1.2.1 --- openacs-4/packages/ams/www/widgets.tcl 30 Oct 2004 00:23:54 -0000 1.1 +++ openacs-4/packages/ams/www/widgets.tcl 30 Nov 2005 16:21:53 -0000 1.1.2.1 @@ -9,7 +9,7 @@ } -set title "Widgets" +set title "[_ ams.Widgets]" set context [list $title] @@ -19,7 +19,7 @@ -name widgets \ -multirow widgets \ -key widget_name \ - -row_pretty_plural "Object Types" \ + -row_pretty_plural "[_ ams.Object_Types]" \ -checkbox_name checkbox \ -selected_format "normal" \ -class "list" \ @@ -32,35 +32,35 @@ } -elements { widget_name { display_col widget_name - label "Widget Name" + label "[_ ams.Widget_Name]" } pretty_name { display_col pretty_name - label "Pretty Name" + label "[_ ams.Pretty_Name_1]" } pretty_plural { display_col pretty_plural - label "Pretty Plural" + label "[_ ams.Pretty_Plural_1]" } widget { display_col widget - label "Widget" + label "[_ ams.Widget_1]" } datatype { display_col datatype - label "Datatype" + label "[_ ams.Datatype]" } parameters { display_col parameters - label "Parameters" + label "[_ ams.Parameters]" } } -filters { object_type {} } -groupby { } -orderby { } -formats { normal { - label "Table" + label "[_ ams.Table]" layout table row { widget_name {} @@ -83,7 +83,7 @@ template::multirow foreach widgets { set form_element "${widget_name}_widget:${datatype}(${widget}),optional" if { [string equal $storage_type "ams_options"] } { - append form_element { {options { {"Demo Example One" 1} {"Demo Example Two" 2} {"Demo Example Three" 3} {"Demo Example Four" 4} {"Demo Example Five" 5} {"Demo Example Six" 6} }}} + append form_element { {options { {"[_ ams.Demo_Example_One]" 1} {"[_ ams.Demo_Example_Two]" 2} {"[_ ams.Demo_Example_Three]" 3} {"[_ ams.Demo_Example_Four]" 4} {"[_ ams.Demo_Example_Five]" 5} {"[_ ams.Demo_Example_Six]" 6} }}} } if { [exists_and_not_null parameters] } { append form_element " ${parameters}" Index: openacs-4/packages/ams/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/doc/index.html,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/packages/ams/www/doc/index.html 25 Oct 2004 00:10:43 -0000 1.4 +++ openacs-4/packages/ams/www/doc/index.html 30 Nov 2005 16:21:53 -0000 1.4.2.1 @@ -1,139 +1,177 @@ - - -AMS (Attribute Management System) - - - - - -

AMS (Attribute Management System)

- -

AMS lets developers (via tcl api) and site wide administrators (via the the ams admin UI) add attributes to acs_object. These attributes can be dynamically added at any time on a live system. AMS then helps you collect attribute information for these defined acs_objects via input forms and helps you present them to users via your website. Whenever AMS stores ams attribute information about an object it keeps track of changes made via the content repository. This way you can see who and when a user changed an object's attributes and are able to revert back to a previous state.

- -

Defining an Attribute

- -

Ams attributes can either be defined via the ams admin user interface or via the ams::attribute::new proc. Every ams_attribute has an ams_widget associated with it. ams_widgets define what type of information the attribute contains the information necessary to generate forms and save various funcationally different types of information. View the documentation for ams::attribute::new to see what types of widgets are available. In most cases using the ams::attribute::new proc will be too tedious to do, instead it would be a good idea to use the shorthand as defined in creating and ams_list. - -

AMS Lists

- -

AMS stores attributes in ams_lists. These lists are an ordered collection of attributes and can be called upon a variety of ways. Ams_lists can be used to generate ad_forms, or return attribute information for use with your packages UI. The attributes associated with your acs_object can be returned as named variables in your calling environment, as an array or as a list via the ams::object::attribute::values proc.

- -

To define an ams_list of the elements you use the ams::define_list. That procedure has extensive documentation about the nuances of defining an ams_list. For example, lets assume that you are developing a package called "contacts" with the object_type of "ct_contact" and you want to define a list to collect information about a contact. You might choose to run the following procedure in when your system restarts:

-
-ams::define_list -package_key "contacts" \
-        -object_type "ct_contact" \
-        -list_name "contact_person" \
-        -pretty_name "The Fields used to Add/Edit a Contact Person" \
-        -attributes {
-                {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}}
-                {home_phone telecom_number {Home Phone} {Home Phones}}
-                {gender radio {Gender} {Genders} {options {{Male} {Female}}}}
-        }
-
- -

This will create an ams_list, define any attributes that haven't previously been defined for the ct_contact object and order the list in the order the attributes are specified.

- -

AMS and ad_form

-

You have two options when dealing with ams and ad_form. Shorthand and detailed.

-

Shorthand

-

Shorthands is a completely simple way of creating forms without many options. These forms must only contain attributes defined in an ams_list. The supplied object_id must already exist in the acs_object table. The shorthand procs is ams_form, which is simply a wrapper for ad_form. For example, to create and ad_form named "contact_person_ae" create a page contacts/www/contact-person-ae.tcl with the following content:

-
-ad_page_contract {
-} {
-        {ct_contact_id:integer,notnull}
-}
-set title "Contact Person Add/Edit"
-set context [list $title]
-
-ams_form -package_key "contacts" \
-         -object_type "ct_contact" \
-         -list_name "contact_person" \
-         -form_name "contact_person_ae" \
-         -object_id $ct_contact_id \
-         -return_url "./"
-
-ad_return_template
-
-

The contacts/www/contact-person-ae.adp would contain

-
-<master>
-<property name="title">@title@</property">
-<property name="context">@context@</property">
-
-<formtemplate id="contact_person_ae"></formtemplate">
-
-

That's it. If this isn't flexible enough you can also go with the detailed method.

- - -

Detailed

-

For many application the AMS and ad_form shorthand will be too simplistic. For those situations, you can use ams to interface with ad_form. You need to define ad_from -form elements like this: -

-ad_form ... -form [ams::ad_form::elements -package_key "contacts" -object_type "ct_contact" -list_name "contact_person"] ...
-
-

Note that this procedure returns an ad form appropriate element list. If you intending to define other elements you will need to ad_from -extend -name form_name -form ...

-

-

In the ad_form -edit_request block put

-
-ad_form ... -edit_request {
-        ams::object::attribute::values -vars -object_id $object_id
-    } ...
-
-

This returns the variables upvared into your page, i.e. the first_names attribute could be returned with a value of "Jane" and the last_name attribute with a value of "Doe"... etc. ad_from looks for all form elements and appropriately pre-fills the form with the given values.

- -

In the -on_submit block you enter the following:

-
-ad_from ... -on_submit {
-        ams::ad_form::save \
-            -package_key "contacts" \
-            -object_type "ct_contact" \
-            -list_name "contact_person" \
-            -form_name "contact_person_ae" \
-            -object_id $ct_contact_id
-    }
-
-

This is how you interface with AMS and ad_form. You may also specify other code in the -form -on_submit and -on_submit blocks.

- -

AMS and your package's UI

- - -

to display attributes you can call ams::object::attribute::values to get the results back as upvared variables, as an array or as a list however you want. So, if on the contact-view page you do, for example to get an array with all attribute_values that are not null represented in. -

-
-ams::object::attribute::values -array "contact_info" -object_id $ct_contact_id
-
-

To add ams_attribute_values to a multirow you call ams::multirow::extend to efficiently extend your multirow with ams_attribute_values. For example:

-
-db_multirow contacts get_contacts { select ct_contact_id from ct_contacts }
-
-ams::multirow::extend \
-    -package_key "contacts" \
-    -object_type "ct_contact" \
-    -list_name "contact_person" \
-    -multirow "contacts" \
-    -key "ct_contact_id"
-
-

-

AMS Permissions

-

THIS SECTION NEEDS TO BE PROGRAMMED AN DOCUMENTED

- - + + +AMS (Attribute Management System) + + + + + + + +

AMS (Attribute Management System)

+ +

AMS lets developers (via tcl api) and site wide administrators (via the the ams admin UI) add attributes to acs_object. These attributes can be dynamically added at any time on a live system. AMS then helps you collect attribute information for these defined acs_objects via input forms and helps you present them to users via your website. Whenever AMS stores ams attribute information about an object it keeps track of changes made via the content repository. This way you can see who and when a user changed an object's attributes and are able to revert back to a previous state.

+ +

Widgets

+

The following procs associated with it in the tcl files, this is done via tcl so +people can actually have a "widget" represent a series of widgets in ad_form or template::form

+
+::widget::${widget}::ad_form_widget       - returns a string suitable for input into ad_form, it gets: attribute, pretty_name, value
+::widget::${widget}::ad_form_save         - saves the input to an ad_form widget and returns a value_id
+::widget::${widget}::ad_form_value        - returns a value suitable for input into ad_form, it gets, attribute, attribute_id and value
+::widget::${widget}::template_form_widget - runs a proc suitable for template::form, it gets: pretty_name, attribute, attribute_id, value
+::widget::${widget}::template_form_save   - saves the input to an termplate::form widget and returns a value_id
+::widget::${widget}::template_form_value  - returns a value suitable for input into ad_form, it gets, attribute, attribute_id and value
+::widget::${widget}::value_text           - return the value formatted for text output, value is provided - this in the future will allow for search indexing of this data
+::widget::${widget}::value_html           - return the value formatted for html output, value is provided
+::widget::${widget}::csv_value            - return the value formatted for csv output, value and attribute are provided
+::widget::${widget}::csv_headers          - return the value formatted for csv output, attribute is provided, for example, if returning a postal address we woudl return ${attribute}__country and ${attribute}__city, etc. For something such as gender we would simply return ${attribute}
+::widget::${widget}::csv_save             - save the value provided by csv, the input into this proc will be ${attribute}__subitem $value ${attribute}__subitem $value, its assumed that the cvs_headers will all be provided and that if there is no input a blank field will be supplied.
+
+
+
+::widget::${widget}::datatypes
+
+-- ams_widget_datatype_map is simplifies the selection of widgets to associate
+-- with an attribute. This allows us to present an administrator with list of valid
+-- widgets she can select for assocation with a particular datatype.
+
+create table ams_widget_datatype_map (
+        widget                  varchar(100)
+                                constraint ams_widget_datatype_map_fk references ams_widgets(widget)
+                                constraint ams_widget_datatype_map_nn not null,
+        datatype                varchar(50)
+                                constraint ams_widget_datatype_map_datatype_fk references acs_datatypes(datatype)
+                                constraint ams_widget_datatype_map_datatype_nn not null
+);
+
+
+
+ +

Defining an Attribute

+ +

Ams attributes can either be defined via the ams admin user interface or via the ams::attribute::new proc. Every ams_attribute has an ams_widget associated with it. ams_widgets define what type of information the attribute contains the information necessary to generate forms and save various funcationally different types of information. View the documentation for ams::attribute::new to see what types of widgets are available. In most cases using the ams::attribute::new proc will be too tedious to do, instead it would be a good idea to use the shorthand as defined in creating and ams_list. + +

AMS Lists

+ +

AMS stores attributes in ams_lists. These lists are an ordered collection of attributes and can be called upon a variety of ways. Ams_lists can be used to generate ad_forms, or return attribute information for use with your packages UI. The attributes associated with your acs_object can be returned as named variables in your calling environment, as an array or as a list via the ams::object::attribute::values proc.

+ +

To define an ams_list of the elements you use the ams::define_list. That procedure has extensive documentation about the nuances of defining an ams_list. For example, lets assume that you are developing a package called "contacts" with the object_type of "ct_contact" and you want to define a list to collect information about a contact. You might choose to run the following procedure in when your system restarts:

+
+ams::define_list -package_key "contacts" \
+        -object_type "ct_contact" \
+        -list_name "contact_person" \
+        -pretty_name "The Fields used to Add/Edit a Contact Person" \
+        -attributes {
+                {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}}
+                {home_phone telecom_number {Home Phone} {Home Phones}}
+                {gender radio {Gender} {Genders} {options {{Male} {Female}}}}
+        }
+
+ +

This will create an ams_list, define any attributes that haven't previously been defined for the ct_contact object and order the list in the order the attributes are specified.

+ +

AMS and ad_form

+

You have two options when dealing with ams and ad_form. Shorthand and detailed.

+

Shorthand

+

Shorthands is a completely simple way of creating forms without many options. These forms must only contain attributes defined in an ams_list. The supplied object_id must already exist in the acs_object table. The shorthand procs is ams_form, which is simply a wrapper for ad_form. For example, to create and ad_form named "contact_person_ae" create a page contacts/www/contact-person-ae.tcl with the following content:

+
+ad_page_contract {
+} {
+        {ct_contact_id:integer,notnull}
+}
+set title "Contact Person Add/Edit"
+set context [list $title]
+
+ams_form -package_key "contacts" \
+         -object_type "ct_contact" \
+         -list_name "contact_person" \
+         -form_name "contact_person_ae" \
+         -object_id $ct_contact_id \
+         -return_url "./"
+
+ad_return_template
+
+

The contacts/www/contact-person-ae.adp would contain

+
+<master>
+<property name="title">@title@</property">
+<property name="context">@context@</property">
+
+<formtemplate id="contact_person_ae"></formtemplate">
+
+

That's it. If this isn't flexible enough you can also go with the detailed method.

+ + +

Detailed

+

For many application the AMS and ad_form shorthand will be too simplistic. For those situations, you can use ams to interface with ad_form. You need to define ad_from -form elements like this: +

+ad_form ... -form [ams::ad_form::elements -package_key "contacts" -object_type "ct_contact" -list_name "contact_person"] ...
+
+

Note that this procedure returns an ad form appropriate element list. If you intending to define other elements you will need to ad_from -extend -name form_name -form ...

+

+

In the ad_form -edit_request block put

+
+ad_form ... -edit_request {
+        ams::object::attribute::values -vars -object_id $object_id
+    } ...
+
+

This returns the variables upvared into your page, i.e. the first_names attribute could be returned with a value of "Jane" and the last_name attribute with a value of "Doe"... etc. ad_from looks for all form elements and appropriately pre-fills the form with the given values.

+ +

In the -on_submit block you enter the following:

+
+ad_from ... -on_submit {
+        ams::ad_form::save \
+            -package_key "contacts" \
+            -object_type "ct_contact" \
+            -list_name "contact_person" \
+            -form_name "contact_person_ae" \
+            -object_id $ct_contact_id
+    }
+
+

This is how you interface with AMS and ad_form. You may also specify other code in the -form -on_submit and -on_submit blocks.

+ +

AMS and your package's UI

+ + +

to display attributes you can call ams::object::attribute::values to get the results back as upvared variables, as an array or as a list however you want. So, if on the contact-view page you do, for example to get an array with all attribute_values that are not null represented in. +

+
+ams::object::attribute::values -array "contact_info" -object_id $ct_contact_id
+
+

To add ams_attribute_values to a multirow you call ams::multirow::extend to efficiently extend your multirow with ams_attribute_values. For example:

+
+db_multirow contacts get_contacts { select ct_contact_id from ct_contacts }
+
+ams::multirow::extend \
+    -package_key "contacts" \
+    -object_type "ct_contact" \
+    -list_name "contact_person" \
+    -multirow "contacts" \
+    -key "ct_contact_id"
+
+

+

AMS Permissions

+

THIS SECTION NEEDS TO BE PROGRAMMED AN DOCUMENTED

+ + Index: openacs-4/packages/dynamic-types/dynamic-types.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/dynamic-types.info,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/dynamic-types/dynamic-types.info 14 Feb 2005 14:33:27 -0000 1.1 +++ openacs-4/packages/dynamic-types/dynamic-types.info 30 Nov 2005 16:19:08 -0000 1.1.4.1 @@ -5,19 +5,20 @@ Dynamic Object Type Dynamic Object Types f - t + f - + Rob Denison Lee Denison Dynamic Object Type management API Xarg Allows creation, manipulation and ui generation of dynamically generated object types. - - - + + + + Index: openacs-4/packages/dynamic-types/catalog/dynamic-types.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/catalog/dynamic-types.en_US.ISO-8859-1.xml,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/dynamic-types/catalog/dynamic-types.en_US.ISO-8859-1.xml 14 Feb 2005 14:33:27 -0000 1.1 +++ openacs-4/packages/dynamic-types/catalog/dynamic-types.en_US.ISO-8859-1.xml 30 Nov 2005 16:19:08 -0000 1.1.4.1 @@ -1,14 +1,50 @@ - - - + + Add + Add a Dynamic Attribute + Add a Form element + Add a Form + Attribute + Add Attribute + Default Value + Edit Attribute + Attribute Name + This name must be lower case, contain only letters and underscores, and contain no spaces. If not specified one will be generated for you. + Attributes + Export code to recreate dynamic types and forms + Tcl code to recreate selected dynamic types and forms Content + Datatype + Dynamic Types Management + Dynamic Types + Edit Form Name + Form elements + Export + Form Name + Form "%form_name%" + Forms you must supply either -multirow or -indexed_array - unable to retrieve widget parameter %name% for attribute %attribute_id% - returning "" as parameter value - + Object Type + Parameter + Parameter "%param%" + Source + Tcl Function + Constant + DB Query + Type + List with multiple columns + List with one column + Single Value + Value + Parameters of "%attribute_name%" + Parameters + Pretty Name + Pretty Plural + Remove + Remove Element from Form + Required? + unable to retrieve widget parameter %name% for attribute %attribute_id% - returning "" as parameter value + Widget + -- Default Widget -- Index: openacs-4/packages/dynamic-types/sql/postgresql/dtype-package-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/sql/postgresql/dtype-package-create.sql,v diff -u -r1.3 -r1.3.2.1 --- openacs-4/packages/dynamic-types/sql/postgresql/dtype-package-create.sql 28 Feb 2005 08:33:03 -0000 1.3 +++ openacs-4/packages/dynamic-types/sql/postgresql/dtype-package-create.sql 30 Nov 2005 16:19:09 -0000 1.3.2.1 @@ -3,6 +3,23 @@ -- Based on cms code by Michael Pih (pihman@arsdigita.com) and -- Karl Goldstein (karlg@arsdigita.com) +----------------------------- +-- timo: +-- i am quite emberassed to do this, but the OCT wouldn't want it +-- any other way, so here they have it. they'll gonna change it +-- anyway, if this makes it into the core... +----------------------------- + +create table dtype_attributes ( + attribute_id integer + constraint dtype_attributes_pk + primary key + constraint dtype_attributes_fk + references acs_attributes +); + + + select define_function_args('dynamic_type__create_type','object_type,supertype;acs_object,pretty_name,pretty_plural,table_name,id_column;XXX,name_method'); create or replace function dynamic_type__create_type (varchar,varchar,varchar,varchar,varchar,varchar,varchar) @@ -47,6 +64,10 @@ p_name_method ); + update acs_object_types + set dynamic_p = true + where object_type = p_object_type; + PERFORM dynamic_type__refresh_view(p_object_type); return 0; @@ -206,13 +227,15 @@ null, null, p_default_value, + 0, 1, - 1, p_sort_order, ''type_specific'', ''f'' ); + insert into dtype_attributes values (v_attr_id); + PERFORM dynamic_type__refresh_view(p_object_type); return v_attr_id; @@ -253,6 +276,8 @@ end if; -- Drop the attribute + delete from dtype_attributes where attribute_id = v_attr_id; + PERFORM acs_attribute__drop_attribute(p_object_type, p_attribute_name); @@ -534,6 +559,10 @@ and ancestor_type = ''content_revision''; end if; + if v_content_revision_p then + PERFORM content_type__refresh_view(p_object_type); + else + for join_rec in select ot2.table_name, ot2.id_column, tree_level(ot2.tree_sortkey) as level from acs_object_types ot1, acs_object_types ot2 where ot2.object_type <> ''acs_object'' @@ -595,6 +624,8 @@ PERFORM dynamic_type__refresh_trigger(p_object_type); + end if; + return 0; end;' language 'plpgsql'; -- show errors Index: openacs-4/packages/dynamic-types/sql/postgresql/forms-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/sql/postgresql/forms-create.sql,v diff -u -r1.3 -r1.3.2.1 --- openacs-4/packages/dynamic-types/sql/postgresql/forms-create.sql 24 Feb 2005 14:21:50 -0000 1.3 +++ openacs-4/packages/dynamic-types/sql/postgresql/forms-create.sql 30 Nov 2005 16:19:09 -0000 1.3.2.1 @@ -177,7 +177,7 @@ not null constraint dtype_wgt_tpls_pm_src_ck check (param_source in ('literal', 'query', 'eval')), - value text, + value text, constraint dtype_wgt_tpls_pm_pk primary key(template_id, param_id) ); @@ -232,7 +232,7 @@ form_id integer constraint dtype_felements_form_id_fk references dtype_forms, - widget varchar(100) + widget varchar(100) constraint dtype_felements_widget_fk references dtype_widgets constraint dtype_felements_widget_nil @@ -262,7 +262,7 @@ not null, constraint dtype_element_param_src_ck check (param_source in ('literal', 'query', 'eval')), - value text, + value text, constraint dtype_element_param_pk primary key(element_id, param_id) ); Index: openacs-4/packages/dynamic-types/sql/postgresql/metadata-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/sql/postgresql/metadata-create.sql,v diff -u -r1.2 -r1.2.4.1 --- openacs-4/packages/dynamic-types/sql/postgresql/metadata-create.sql 15 Feb 2005 13:55:34 -0000 1.2 +++ openacs-4/packages/dynamic-types/sql/postgresql/metadata-create.sql 30 Nov 2005 16:19:09 -0000 1.2.4.1 @@ -15,7 +15,7 @@ insert into dtype_db_datatypes (datatype, db_type) values (''integer'', ''integer''); insert into dtype_db_datatypes (datatype, db_type) - values (''money'', ''text''); + values (''money'', ''varchar(30)''); insert into dtype_db_datatypes (datatype, db_type) values (''date'', ''timestamp''); insert into dtype_db_datatypes (datatype, db_type) @@ -25,11 +25,13 @@ insert into dtype_db_datatypes (datatype, db_type) values (''enumeration'', ''text''); insert into dtype_db_datatypes (datatype, db_type) - values (''url'', ''text''); + values (''url'', ''varchar(1000)''); insert into dtype_db_datatypes (datatype, db_type) - values (''email'', ''text''); + values (''email'', ''varchar(100)''); insert into dtype_db_datatypes (datatype, db_type) values (''text'', ''text''); + insert into dtype_db_datatypes (datatype, db_type) + values (''string'', ''varchar(1000)''); raise notice ''Inserting standard widget metadata...''; @@ -209,6 +211,21 @@ insert into dtype_default_widgets (template_id, datatype) values (v_template_id, ''text''); + -- Text (single line) (default ''string'' widget) + v_template_id := dtype_wdgt_tmpl__new ( + null, + null, + ''string'', + ''String'', + ''text'', + ''string'', + null, + null + ); + + insert into dtype_default_widgets (template_id, datatype) + values (v_template_id, ''string''); + -- Email Address v_template_id := dtype_wdgt_tmpl__new ( null, Index: openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-oracle.xql,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-oracle.xql 14 Feb 2005 14:33:28 -0000 1.1 +++ openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-oracle.xql 30 Nov 2005 16:19:09 -0000 1.1.4.1 @@ -67,11 +67,20 @@ - + select a.attribute_name as name, - a.pretty_name, a.attribute_id, a.datatype + a.pretty_name, + a.attribute_id, + a.datatype, + a.table_name, + nvl(a.column_name, a.attribute_name) as column_name, + a.default_value, + a.min_n_values, + a.max_n_values, + a.storage, + a.static_p from acs_object_type_attributes a, (select t.object_type, level as type_level from acs_object_types_t @@ -81,7 +90,33 @@ and t.object_type = a.ancestor_type $storage_clause order by type_level, a.sort_order + + + + + + select a.attribute_name as name, + a.pretty_name, + a.attribute_id, + a.datatype, + a.table_name, + nvl(a.column_name, a.attribute_name) as column_name, + a.default_value, + a.min_n_values, + a.max_n_values, + a.storage, + a.static_p + from acs_object_type_attributes a, dtype_attributes d, + (select t.object_type, level as type_level + from acs_object_types_t + start with t.object_type = :start_with + connect by prior t.object_type = t.supertype) t + where a.object_type = :name + and d.attribute_id = a.attribute_id + and t.object_type = a.ancestor_type $storage_clause + order by type_level, a.sort_order + Index: openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-postgresql.xql,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-postgresql.xql 14 Feb 2005 14:33:28 -0000 1.1 +++ openacs-4/packages/dynamic-types/tcl/dynamic-type-procs-postgresql.xql 30 Nov 2005 16:19:09 -0000 1.1.4.1 @@ -47,7 +47,7 @@ - + select a.attribute_name as name, a.pretty_name, @@ -71,6 +71,31 @@ + + + select a.attribute_name as name, + a.pretty_name, + a.attribute_id, + a.datatype, + a.table_name, + coalesce(a.column_name, a.attribute_name) as column_name, + a.default_value, + a.min_n_values, + a.max_n_values, + a.storage, + a.static_p + from acs_object_type_attributes a, dtype_attributes d, + (select t.object_type, tree_level(t.tree_sortkey) - tree_level(t2.tree_sortkey) as type_level + from acs_object_types t, acs_object_types t2 + where t2.object_type = :start_with + and t.tree_sortkey between t2.tree_sortkey and tree_right(t2.tree_sortkey)) t + where a.object_type = :name + and d.attribute_id = a.attribute_id + and t.object_type = a.ancestor_type $storage_clause + order by type_level, a.sort_order + + + Index: openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.tcl,v diff -u -r1.2 -r1.2.2.1 --- openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.tcl 24 Feb 2005 14:21:50 -0000 1.2 +++ openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.tcl 30 Nov 2005 16:19:09 -0000 1.2.2.1 @@ -23,17 +23,22 @@ {-object_id:required} {-object_type:required} {-array:required} + {-exclude_static:boolean} + {-dform implicit} + {-variables ""} } { Populates array with the data for the object specified. } { - upvar $array local + set attributes_list [dtype::get_attributes_list -name $object_type -start_with acs_object -storage_types type_specific -exclude_static_p $exclude_static_p] - set attributes_list [dtype::get_attributes -name $object_type -list t attributes] - + upvar $array local set columns [list] foreach attribute_info $attributes_list { foreach {name pretty_name attribute_id datatype table_name column_name default_value min_n_values max_n_values static_p} $attribute_info break + if {$column_name == "package_id"} { + continue + } switch $datatype { date - timestamp - @@ -46,9 +51,49 @@ } } } - db_1row select_table_name {} - set columns [join $columns ", "] - db_0or1row select_object {} -column_array local + + if {[llength $columns] > 0} { + db_1row select_table_name {} + set columns [join $columns ", "] + db_0or1row select_object {} -column_array local + } + + dtype::form::metadata::widgets -object_type $object_type \ + -dform $dform \ + -exclude_static_p $exclude_static_p \ + -multirow widgets + + dtype::form::metadata::params -object_type $object_type \ + -dform $dform \ + -multirow params + + set widget_count [template::multirow size widgets] + set param_count [template::multirow size params] + + for {set w 1} {$w <= $widget_count} {incr w} { + template::multirow get widgets $w + + if {[lsearch -exact [list "select" "multiselect" "checkbox" "radio"] $widgets(widget)] > -1} { + + for {set p 1} {$p <= $param_count} {incr p} { + template::multirow get params $p + + if {$params(attribute_id) != $widgets(attribute_id) || $params(param) != "options"} { + continue; + } + + set options [dtype::form::parameter_value -parameter params -vars $variables] + set new_value "" + set old_value $local($widgets(attribute_name)) + foreach option $options { + if {[lsearch -exact $old_value [lindex $option 1]] > -1} { + lappend new_value [lindex $option 0] + } + } + set local($widgets(attribute_name)) [join $new_value ", "] + } + } + } } ad_proc -public dtype::create { @@ -67,13 +112,15 @@ set name_method [db_null] } + ns_log Debug "DYNAMIC TYPES: Creating Object $name with Pretty Name $pretty_name" db_exec_plsql create_type {} } ad_proc -public dtype::delete { {-name:required} {-drop_children:boolean} {-drop_table:boolean} + {-no_flush:boolean} } { Delete a dynamically created content type. } { @@ -85,6 +132,11 @@ set event(object_type) $name set event(action) deleted util::event::fire -event dtype event + + if {!$no_flush_p} { + dtype::flush_cache -type $name -event event + } + } ad_proc -public dtype::create_attribute { @@ -95,6 +147,8 @@ {-pretty_plural ""} {-sort_order ""} {-default_value ""} + {-no_flush:boolean} + } { Creates an attribute on a content type. } { @@ -115,11 +169,16 @@ } db_exec_plsql create_attr {} - + set event(object_type) $object_type set event(attribute) $name set event(action) created util::event::fire -event dtype.attribute event + + if {!$no_flush_p} { + dtype::flush_cache -type $name -event event + } + } ad_proc -public dtype::get_attributes { @@ -177,15 +236,20 @@ {-name:required} {-start_with:required} {-storage_types:required} + {-exclude_static_p 0} } { Gets all the attributes of a object_type. } { if {$no_cache_p} { set storage_clause "and a.storage in ('[join $storage_types "', '"]')" - return [db_list_of_lists select_attributes {}] + if {$exclude_static_p} { + return [db_list_of_lists select_attributes_dynamic {}] + } else { + return [db_list_of_lists select_attributes {}] + } } else { - return [util_memoize "dtype::get_attributes_list -no_cache -name \"$name\" -start_with \"$start_with\" -storage_types \"$storage_types\""] + return [util_memoize "dtype::get_attributes_list -no_cache -name \"$name\" -start_with \"$start_with\" -storage_types \"$storage_types\" -exclude_static_p $exclude_static_p"] } } @@ -195,7 +259,7 @@ } { Flushes the util_memoize cache of dtype calls for a given object type. - event is assumed to contain object_type and action + event is assumed to be a name of an array that contains object_type and action } { upvar $event dtype_event @@ -207,6 +271,8 @@ {-object_type:required} {-pretty_name:required} {-pretty_plural:required} + {-default_value ""} + {-no_flush:boolean} } { Sets the details of an attribute. } { @@ -216,6 +282,10 @@ set event(attribute) $name set event(action) updated util::event::fire -event dtype.attribute event + + if {!$no_flush_p} { + dtype::flush_cache -type $name -event event + } } ad_proc -public dtype::get_attribute { @@ -232,6 +302,7 @@ {-name:required} {-object_type:required} {-drop_column:boolean} + {-no_flush:boolean} } { Drops an attribute on a content type. } { @@ -243,6 +314,10 @@ set event(attribute) $name set event(action) deleted util::event::fire -event dtype.attribute event + + if {!$no_flush_p} { + dtype::flush_cache -type $name -event event + } } @@ -372,11 +447,11 @@ # get default widgets foreach type $types { - if {[info exists type_dforms($type)]} { - set type_dform $type_dforms($type) - } else { - set type_dform "implicit" - } + if {[info exists type_dforms($type)]} { + set type_dform $type_dforms($type) + } else { + set type_dform "implicit" + } dtype::form::metadata::widgets -object_type $type \ -dform $type_dform \ Index: openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.xql,v diff -u -r1.2 -r1.2.2.1 --- openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.xql 24 Feb 2005 14:21:50 -0000 1.2 +++ openacs-4/packages/dynamic-types/tcl/dynamic-type-procs.xql 30 Nov 2005 16:19:09 -0000 1.2.2.1 @@ -46,7 +46,9 @@ update acs_attributes - set pretty_name=:pretty_name,pretty_plural=:pretty_plural + set pretty_name = :pretty_name, + pretty_plural = :pretty_plural, + default_value = :default_value where acs_attributes.attribute_name = :name and acs_attributes.object_type = :object_type Fisheye: Tag 1.2.2.1 refers to a dead (removed) revision in file `openacs-4/packages/dynamic-types/tcl/form-init.tcl'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/dynamic-types/tcl/form-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/form-procs-postgresql.xql,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/dynamic-types/tcl/form-procs-postgresql.xql 14 Feb 2005 14:33:28 -0000 1.1 +++ openacs-4/packages/dynamic-types/tcl/form-procs-postgresql.xql 30 Nov 2005 16:19:09 -0000 1.1.4.1 @@ -95,7 +95,7 @@ :item_locale, now(), :item_creation_user, - null, + :item_context_id, :item_creation_ip, 'content_item', :item_content_type, @@ -104,7 +104,8 @@ 'text/plain', null, null, - :cr_storage) + :cr_storage, + :item_package_id) Index: openacs-4/packages/dynamic-types/tcl/form-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/form-procs.tcl,v diff -u -r1.5 -r1.5.2.1 --- openacs-4/packages/dynamic-types/tcl/form-procs.tcl 26 Feb 2005 19:09:21 -0000 1.5 +++ openacs-4/packages/dynamic-types/tcl/form-procs.tcl 30 Nov 2005 16:19:09 -0000 1.5.2.1 @@ -41,6 +41,9 @@ {-overrides {}} {-cr_widget textarea} {-cr_widget_options {}} + {-exclude {}} + {-exclude_static:boolean} + {-variables {}} } { Adds the elements of the specified object types dynamic form and all of its supertypes dynamic forms to the specified template form. @@ -70,22 +73,23 @@ template::form create $form } + if {![empty_string_p $object_id]} { + set object_id [db_string check_object_existence {} -default ""] + } + set types [dtype::form::types_list \ -object_id $object_id \ -object_type $object_type] set object_type [lindex $types 0] - + set action edit - array set type_dforms $dforms array set override $overrides - if {![string equal $object_id ""] && - [info exists override(object_id)]} { + if {![empty_string_p $object_id] && [info exists override(object_id)]} { error "Cannot override object_id for an existing object" - } elseif {[string equal $object_id ""]} { + } elseif {[empty_string_p $object_id]} { set action new - if {![info exists override(object_id)]} { set override(object_id) [db_nextval acs_object_id_seq] } @@ -117,20 +121,27 @@ -form $form \ -overrides [array get override] \ -cr_widget $cr_widget \ - -cr_widget_options $cr_widget_options + -cr_widget_options $cr_widget_options \ + -exclude_static_p $exclude_static_p \ + -exclude $exclude \ + -variables $variables } } ad_proc -public dtype::form::process { {-prefix ""} {-object_type ""} + {-object_id ""} {-dform implicit} {-dforms {acs_object default content_revision default}} {-form:required} {-defaults {}} + {-default_fields {}} {-cr_widget textarea} {-cr_storage file} {-cr_mime_filters {text/html dtype::mime_filters::text_html}} + {-exclude {}} + {-exclude_static:boolean} } { Process a dynamic type form submission created by a function such as dtype::form::add_elements. @@ -143,6 +154,7 @@ @param prefix the prefix for each attribute name used @param defaults default values to use for attributes (this should be used to supply values for context_id and the like) + @param default_fields default columns with values to be used for db insert @param cr_widget the input method for the content @param cr_storage the content repository storage method @@ -153,7 +165,9 @@ # Pull the object_id out of the form - technically a acs_object dform # could be created that doesn't include object_id as a field in which # case this would just break. - set object_id [template::element::get_value $form ${prefix}object_id] + if {[empty_string_p $object_id]} { + set object_id [template::element::get_value $form ${prefix}object_id] + } # Pull the action out of the form set action [template::element::get_value $form ${prefix}dform_action] @@ -177,22 +191,36 @@ ####################################################### # Setup default values for object creation # - if {$new_p} { - set default(object_type) $object_type - - if {![info exists default(creation_user)]} { - set default(creation_user) [ad_conn user_id] - } - - if {![info exists default(creation_ip)]} { - set default(creation_ip) [ad_conn peeraddr] - } + set default(object_type) $object_type + if {![info exists default(creation_user)]} { + set default(creation_user) [ad_conn user_id] } + if {![info exists default(creation_ip)]} { + set default(creation_ip) [ad_conn peeraddr] + } + if {![info exists default(context_id)]} { + set default(context_id) [db_null] + } + if {![info exists default(package_id)]} { + set default(package_id) [ad_conn package_id] + } + if {![info exists default(parent_id)]} { + set default(parent_id) [db_null] + } + if {![info exists default(nls_language)]} { + set default(nls_language) [db_null] + } + if {![info exists default(publish_date)]} { + set default(publish_date) [db_null] + } ####################################################### # Content Repository specific preparations # if {$content_type_p} { + if {![info exists default(mime_type)]} { + set default(mime_type) "text/plain" + } if {$new_p} { # We are creating an initial revision of a content item (ie. a new # instance of a subtype of content_revision). We need to first @@ -204,6 +232,8 @@ locale [db_null] \ parent_id [db_null] \ content_type $object_type \ + context_id [db_null] \ + package_id [ad_conn package_id] \ creation_user [ad_conn user_id] \ creation_ip [ad_conn peeraddr] \ storage_type $cr_storage] @@ -249,10 +279,6 @@ set default(mime_type) [ns_guesstype $default(filename)] } - - # Populate content revision fields with default values - set default(nls_language) [db_null] - set default(publish_date) [db_null] } ####################################################### @@ -261,6 +287,25 @@ set columns [list] set values [list] + # set default fields with provided values + foreach var_spec $default_fields { + set var_name [lindex $var_spec 0] + if {[llength $var_spec] > 1} { + set var_value [uplevel subst \{[lindex $var_spec 1]\}] + } else { + upvar 1 $var_name upvar_variable + if {[info exists upvar_variable]} { + set crvd_$var_name $upvar_variable + set var_value ":crvd_$var_name" + } else { + set var_value "null" + } + } + lappend columns $var_name + lappend values $var_value + } + + # LEED context_id and similar fields should be passed in using the # -defaults { context_id 1234 } argument @@ -274,161 +319,162 @@ set type_dform $dform } - # Add attributes to $columns and associated bind variables to $values - # for each type - if {[info exists type_dforms($type)]} { - set type_dform $type_dforms($type) - } else { - set type_dform $dform - } # get the attribute metadata for the object type dtype::get_attributes -name $type \ -start_with $type \ attributes dtype::form::metadata::widgets -object_type $type \ -dform $type_dform \ + -exclude_static_p $exclude_static_p \ -indexed_array widgets set size [template::multirow size attributes] for {set i 1} {$i <= $size} {incr i} { template::multirow get attributes $i + # exclude specified widgets + if {[lsearch -exact $exclude $attributes(name)] > -1} { + continue + } + set crv_$attributes(name) "" - ns_log debug "PROCESSING: $attributes(name)" + ns_log notice "PROCESSING: $attributes(name)" if {[info exists widgets($attributes(attribute_id))]} { - ns_log debug "PROCESSING: found $attributes(name) in form" + ns_log notice "PROCESSING: found $attributes(name) in form" # first check for the attribute in the submitted form array set this_widget_info $widgets($attributes(attribute_id)) switch $this_widget_info(widget) { file {} - checkbox - - multiselect { - set crv_$attributes(name) [template::element::get_values \ - $form \ - ${prefix}$attributes(name)] + checkbox - multiselect { + set crv_$attributes(name) [template::element::get_values $form ${prefix}$attributes(name)] } default { - set crv_$attributes(name) [template::element::get_value \ - $form \ - ${prefix}$attributes(name)] + set crv_$attributes(name) [template::element::get_value $form ${prefix}$attributes(name)] } } } elseif {[info exists default($attributes(name))]} { ns_log debug "PROCESSING: using supplied default for $attributes(name)" - - if {![string equal [set crv_$attributes(name)] ""]} { - + if {[empty_string_p [set crv_$attributes(name)]]} { # second check if the caller supplied a default value set crv_$attributes(name) $default($attributes(name)) + } - } elseif {$new_p && - ![string equal $attributes(default_value) ""]} { - ns_log debug "PROCESSING: using attribute default for $attributes(name)" + } elseif {$new_p && ![empty_string_p $attributes(default_value)]} { + ns_log debug "PROCESSING: using attribute default for $attributes(name)" - # if we are inserting a new object then use the attributes - # default value - set crv_$attributes(name) $attributes(default_value) + # if we are inserting a new object then use the attributes + # default value + set crv_$attributes(name) $attributes(default_value) - } elseif {!$new_p} { - ns_log debug "PROCESSING: using existing value for $attributes(name) (ie. adding it to missing columns)" + } elseif {!$new_p} { + ns_log debug "PROCESSING: using existing value for $attributes(name) (ie. adding it to missing columns)" - # append the column to missing columns so that the value - # is copied from the previous revision when we are dealing - # with content types - lappend missing_columns $attributes(column_name) + # append the column to missing columns so that the value + # is copied from the previous revision when we are dealing + # with content types + if {[lsearch -exact {creation_date last_modified modifying_ip} $attributes(name)] == -1} { + lappend missing_columns $attributes(column_name) + } + } - } - if {![string equal [set crv_$attributes(name)] ""]} { - lappend columns $attributes(column_name) + if {![empty_string_p [set crv_$attributes(name)]] && [lsearch -exact $columns $attributes(name)] == -1} { + lappend columns $attributes(column_name) - # cast the value to the appropriate datatype - switch $attributes(datatype) { - date - - time_of_day - - timestamp { - lappend values [template::util::date::get_property \ - sql_date \ - [lindex [set crv_$attributes(name)] 0]] - } - default { - lappend values ":crv_$attributes(name)" - } - } - } + # cast the value to the appropriate datatype + switch $attributes(datatype) { + date - time_of_day - timestamp { + lappend values [template::util::date::get_property sql_date [lindex [set crv_$attributes(name)] 0]] + } + default { + lappend values ":crv_$attributes(name)" + } + } } } + } - ####################################################### - # Perform the insert or update as appropriate - # - if {$content_type_p} { - db_transaction { - if {$new_p} { - db_dml insert_statement " + ####################################################### + # Perform the insert or update as appropriate + # + + # title, description, object_title + if {$content_type_p} { + set pos [lsearch -exact $columns package_id] + set columns [lreplace $columns $pos $pos object_package_id] + set columns [concat "item_id" "revision_id" $columns] + set values [concat ":item_id" ":object_id" $values] + + db_transaction { + if {$new_p} { + db_dml insert_statement " insert into ${type_info(table_name)}i - ([join [concat "item_id" "revision_id" $columns] ", "]) + ([join $columns ", "]) values - ([join [concat ":item_id" ":object_id" $values] ", "])" - } else { - set latest_revision [content::item::get_latest_revision -item_id $item_id] + ([join $values ", "])" + } else { + set latest_revision [content::item::get_latest_revision -item_id $item_id] + set object_id [db_nextval acs_object_id_seq] - db_dml insert_statement " + db_dml insert_statement " insert into ${type_info(table_name)}i - ([join [concat "item_id" "revision_id" $columns $missing_columns] ", "]) + ([join [concat $columns $missing_columns] ", "]) select - [join [concat ":item_id" ":object_id" $values $missing_columns] ", "] + [join [concat $values $missing_columns] ", "] from ${type_info(table_name)}i where revision_id = $latest_revision" - } + } - set revision_ids [db_list get_revision_ids {}] - set revision_id [lindex $revision_ids 0] - set prev_revision_id [lindex $revision_ids 1] + content::item::set_live_revision -revision_id $object_id - if {[string equal $cr_widget none] || - ([string equal $cr_widget file] && - [string equal $tmp_file ""])} { + set revision_ids [db_list get_revision_ids {}] + set revision_id [lindex $revision_ids 0] + set prev_revision_id [lindex $revision_ids 1] - # either a content widget wasn't included in the form or - # no new file was uploaded, so we want to preserve the previous - # revisions content - if {![string equal $prev_revision_id ""]} { - db_dml update_content {} - } - } else { - dtype::upload_content -item_id $item_id \ - -revision_id $revision_id \ - -file $tmp_file \ - -storage_type $cr_storage + if {[string equal $cr_widget none] || + ([string equal $cr_widget file] && + [string equal $tmp_file ""])} { - ns_unlink $tmp_file - } - } - } else { - if {$new_p} { - db_dml insert_statement " + # either a content widget wasn't included in the form or + # no new file was uploaded, so we want to preserve the previous + # revisions content + if {![string equal $prev_revision_id ""]} { + db_dml update_content {} + } + } else { + dtype::upload_content -item_id $item_id \ + -revision_id $revision_id \ + -file $tmp_file \ + -storage_type $cr_storage + + ns_unlink $tmp_file + } + } + } else { + if {$new_p} { + db_dml insert_statement " insert into ${type_info(table_name)}i ([join $columns ", "]) values ([join $values ", "])" - } else { - set updates [list] + } else { + set updates [list] - set all_columns [concat $columns $missing_columns] - set all_values [concat $values $missing_columns] + set all_columns [concat $columns $missing_columns] + set all_values [concat $values $missing_columns] - set length [llength $all_columns] - for {set i 0} {$i < $length} {incr i} { - lappend updates "[lindex $all_columns $i] = [lindex $all_values $i]" - } + set length [llength $all_columns] + for {set i 0} {$i < $length} {incr i} { + lappend updates "[lindex $all_columns $i] = [lindex $all_values $i]" + } - db_dml update_statement " + db_dml update_statement " update ${type_info(table_name)}i set [join $updates ", "] where $type_info(id_column) = :object_id" - } - } + } } + + return $object_id } ad_proc -private dtype::form::add_type_elements { @@ -441,6 +487,9 @@ {-overrides {}} {-cr_widget textarea} {-cr_widget_options {}} + {-exclude_static_p 0} + {-exclude {}} + {-variables {}} } { Adds the elements of the specified or implicit object form to the specified template form. @@ -462,6 +511,7 @@ # dtype::form::metadata::widgets -object_type $object_type \ -dform $dform \ + -exclude_static_p $exclude_static_p \ -multirow widgets dtype::form::metadata::params -object_type $object_type \ @@ -471,6 +521,7 @@ set widget_count [template::multirow size widgets] set param_count [template::multirow size params] + set default_locale [lang::system::site_wide_locale] set p 1 # Generate form elements for each attribute / widget @@ -479,8 +530,19 @@ set html_options [list] set widget_options [list] + # exclude specified widgets + if {[lsearch -exact $exclude $widgets(attribute_name)] > -1} { + continue + } + # set the default values for overridable options - set overridables(label) $widgets(pretty_name) + set overridables(help_text) "[_ acs-translations.$widgets(object_type)\_$widgets(attribute_name)\_help]" + set message_key "acs-translations.$widgets(object_type)\_$widgets(attribute_name)" + if {[lang::message::message_exists_p $default_locale $message_key]} { + set overridables(label) "[_ $message_key]" + } else { + set overridables(label) $widgets(pretty_name) + } # Create the main element create line set element_create_cmd "template::element create \ @@ -521,7 +583,7 @@ break; } - set value [dtype::form::parameter_value -parameter params] + set value [dtype::form::parameter_value -parameter params -vars $variables] # determine if the parameter value is null switch $params(param_type) { @@ -534,7 +596,7 @@ } } - if {!$null_value_p} { + if {!$null_value_p || $params(param) == "options"} { if {[template::util::is_true $params(is_html)]} { lappend html_options $params(param) lappend html_options $value @@ -695,11 +757,14 @@ ad_proc -private dtype::form::parameter_value { {-object_type ""} {-parameter:required} + {-vars:required} } { Calculates and returns the current value for the supplied parameter array based on its type, source and default_value attributes. + Provide variables to tcl-procs by \$variables(--name--) } { upvar $parameter param + array set variables $vars set value "" set attribute_id $param(attribute_id) @@ -751,6 +816,7 @@ {-dform:required} {-multirow {}} {-indexed_array {}} + {-exclude_static_p 0} } { Returns the widget metadata for the specified object_type and dform as either a multirow or an indexed array. @@ -797,7 +863,9 @@ set metadata [dtype::form::metadata::widgets_list \ -object_type $object_type \ + -exclude_static_p $exclude_static_p \ -dform $dform] + foreach widget $metadata { if {$multirow_p} { eval "template::multirow append \$multirow $widget" @@ -815,6 +883,7 @@ {-no_cache:boolean} {-object_type:required} {-dform:required} + {-exclude_static_p 0} } { Returns a list of lists with the widget metadata for the specified object_type and dform. @@ -824,9 +893,13 @@ @param no_cache does not attempt to use the cache to retrieve the info } { if {$no_cache_p} { - return [db_list_of_lists select_dform_metadata {}] + if {$exclude_static_p} { + return [db_list_of_lists select_dform_metadata_dynamic {}] + } else { + return [db_list_of_lists select_dform_metadata {}] + } } else { - return [util_memoize "dtype::form::metadata::widgets_list -no_cache -object_type \"$object_type\" -dform \"$dform\""] + return [util_memoize "dtype::form::metadata::widgets_list -no_cache -object_type \"$object_type\" -dform \"$dform\" -exclude_static_p $exclude_static_p"] } } @@ -924,12 +997,12 @@ if {[string equal $type dtype] || [string equal $type dtype.attribute]} { # flush the default form - util_memoize_flush_regexp "$function $object_type -dform \"default\"" + util_memoize_flush_regexp "$function $object_type -dform \"implicit\".*" } else { set dform $dtype_event(dform) # flush the form specified in the event - util_memoize_flush_regexp "$function $object_type -dform \"$dform\"" + util_memoize_flush_regexp "$function $object_type -dform \"$dform\".*" } } @@ -1078,3 +1151,36 @@ -dform $dform } } + +ad_proc -public dtype::form::new { + {-object_type:required} + {-form_name:required} + {-form_id ""} +} { + Create new dynamic form +} { + if {[empty_string_p $form_id]} { + set form_id [db_nextval t_dtype_seq] + } + + db_dml insert_form {} + + set event(object_type) $object_type + set event(dform) $form_name + set event(action) created + util::event::fire -event dtype.form event +} + +ad_proc -public dtype::form::edit { + {-form_name:required} + {-form_id:required} +} { + Update dynamic form name +} { + db_dml update_form {} + + set event(object_type) $object_type + set event(dform) $form_name + set event(action) updated + util::event::fire -event dtype.form event +} Index: openacs-4/packages/dynamic-types/tcl/form-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/dynamic-types/tcl/form-procs.xql,v diff -u -r1.1 -r1.1.4.1 --- openacs-4/packages/dynamic-types/tcl/form-procs.xql 14 Feb 2005 14:33:28 -0000 1.1 +++ openacs-4/packages/dynamic-types/tcl/form-procs.xql 30 Nov 2005 16:19:09 -0000 1.1.4.1 @@ -1,40 +1,49 @@ + + + select object_id + from acs_objects + where object_id = :object_id + + + - update cr_revisions set content = (select content from cr_revisions where revision_id = :prev_revision_id) + update cr_revisions set content = (select content from cr_revisions where revision_id = :prev_revision_id) where revision_id = :revision_id - + - select attribute_id, - object_type, - table_name, - attribute_name, - pretty_name, - pretty_plural, - sort_order, - datatype, - default_value, - min_n_values, - max_n_values, - storage, - static_p, - column_name, - form_id, - form_name, - element_id, - widget, - is_required + select attribute_id, object_type, table_name, attribute_name, + pretty_name, pretty_plural, sort_order, datatype, + default_value, min_n_values, max_n_values, storage, + static_p, column_name, form_id, form_name, element_id, + widget, is_required from dtype_form_elements_all where object_type = :object_type and form_name = :dform order by sort_order + + + select e.attribute_id, object_type, table_name, attribute_name, + pretty_name, pretty_plural, sort_order, datatype, + default_value, min_n_values, max_n_values, storage, + static_p, column_name, form_id, form_name, element_id, + widget, is_required + from dtype_form_elements_all e, dtype_attributes a + where object_type = :object_type + and form_name = :dform + and e.attribute_id = a.attribute_id + order by sort_order + + + select ea.element_id, @@ -118,6 +127,16 @@ + + + + select table_name, id_column + from acs_object_types + where object_type = :object_type + + + + @@ -141,4 +160,23 @@ + + + + insert into dtype_forms (form_id, name, object_type) + values (:form_id, :form_name, :object_type) + + + + + + + + update dtype_forms + set name = :form_name + where form_id = :form_id + + + +
[_ ams.delivery_address]
      
[_ ams.municipality][_ ams.region][_ ams.postal_code]
[_ ams.postal_code][_ ams.municipality][_ ams.region]
[_ ams.municipality][_ ams.region][_ ams.postal_code]
[menu $element(id).country_code [template::util::address::country_options] $country_code attributes]