Index: openacs-4/contrib/packages/classified-ads/tcl/ads-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/tcl/ads-procs.tcl,v diff -u -r1.4 -r1.5 --- openacs-4/contrib/packages/classified-ads/tcl/ads-procs.tcl 21 Jul 2003 05:23:56 -0000 1.4 +++ openacs-4/contrib/packages/classified-ads/tcl/ads-procs.tcl 23 Jul 2003 21:08:19 -0000 1.5 @@ -8,9 +8,9 @@ } -namespace eval classified-ads::ads { +namespace eval classified-ads::ads {} -ad_proc -public new { +ad_proc -public classified-ads::ads::new { {-item_id_element:required} {-form_id:required} {-category_id} @@ -41,7 +41,7 @@ } -ad_proc -public edit { +ad_proc -public classified-ads::ads::edit { {-item_id_element:required} {-form_id:required} } { @@ -59,7 +59,7 @@ } -ad_proc -public delete { +ad_proc -public classified-ads::ads::delete { {-ad_id:required} } { delete an existing ad @@ -74,7 +74,7 @@ return 0 } -ad_proc -public get { +ad_proc -public classified-ads::ads::get { {-ad_id:required} {-revision_id ""} {-array:required} @@ -114,7 +114,7 @@ } -ad_proc -public get_assigned_ads_by_category { +ad_proc -public classified-ads::ads::get_assigned_ads_by_category { {-category_id_list ""} } { Gets all the ads assigned to categories @@ -146,7 +146,7 @@ } -ad_proc -public get_unassigned_ads_by_category { +ad_proc -public classified-ads::ads::get_unassigned_ads_by_category { {-category_id_list ""} } { Gets all the ads NOT assigned to the categories passed. @@ -167,7 +167,7 @@ return [db_list_of_ns_sets select_ads {}] } -ad_proc -public get_category_id { +ad_proc -public classified-ads::ads::get_category_id { {-ad_id:required} } { Return the keyword_id of the category the passed ad belongs to. @@ -177,7 +177,7 @@ return [db_0or1row get_category_id {}] } -ad_proc -public generate_trail { +ad_proc -public classified-ads::ads::generate_trail { {-ad_id:required} {-append_element} } { @@ -206,5 +206,3 @@ return $trail_list } - -} Index: openacs-4/contrib/packages/classified-ads/tcl/classified-ads-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/tcl/classified-ads-procs.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/classified-ads/tcl/classified-ads-procs.tcl 19 Jul 2003 01:48:45 -0000 1.3 +++ openacs-4/contrib/packages/classified-ads/tcl/classified-ads-procs.tcl 23 Jul 2003 21:08:19 -0000 1.4 @@ -1,745 +1,749 @@ ad_library { - Classified Ads Procs +Classified Ads Procs - @author Deds Castillo (deds@infiniteinfo.com) - @creation-date 2002-10-08 - @cvs-id $Id$ +@author Deds Castillo (deds@infiniteinfo.com) +@creation-date 2002-10-08 +@cvs-id $Id$ } -namespace eval classified-ads { - ad_proc -public package_key {} { - Returns the package key - } { - return "classified-ads" - } +namespace eval classified-ads {} +ad_proc -public classified-ads::package_key {} { + Returns the package key +} { + return "classified-ads" +} - ad_proc -public is_instantiated {} { - Returns 1 if classified-ads is instantiated, 0 otherwise - } { - return [ad_decode [apm_num_instances [package_key]] 0 0 1] - } +ad_proc -public classified-ads::is_instantiated {} { + Returns 1 if classified-ads is instantiated, 0 otherwise +} { + return [ad_decode [apm_num_instances [package_key]] 0 0 1] +} - ad_proc -public main_keyword_exists_p {} { - Returns the keyword id of the main category for the package, 0 if not yet created - } { - # These are magic values - set heading "[package_key]-main-category" - set description "$heading Main Category, this is where all classified ads categories are rooted" +ad_proc -public classified-ads::main_keyword_exists_p {} { + Returns the keyword id of the main category for the package, 0 if not yet created +} { + # These are magic values + set heading "[package_key]-main-category" + set description "$heading Main Category, this is where all classified ads categories are rooted" - return [db_string get_main_keyword {} -default 0] - } + return [db_string get_main_keyword {} -default 0] +} - ad_proc -public root_folder_exists_p {} { - Returns the folder id of the classified ads root folder, 0 if not yet created - } { - # These are magic values - set name "[package_key]" - set label "[package_key]" - set description "$name Root Folder, all classified ads items go here" +ad_proc -public classified-ads::root_folder_exists_p {} { + Returns the folder id of the classified ads root folder, 0 if not yet created +} { + # These are magic values + set name "[package_key]" + set label "[package_key]" + set description "$name Root Folder, all classified ads items go here" - return [db_string get_root_folder {} -default 0] - - } + return [db_string get_root_folder {} -default 0] - ad_proc -public get_root_folder_id {} { - Returns the folder id of the classified ads root folder, error if none - } { - set folder_id [root_folder_exists_p] +} - if {!$folder_id} { - ad_return_error "Root Folder not found" \ - "The root folder for [package_key] was not found. The datamodel might not be properly installed. Did you restart the server after installation?" - ad_script_abort - } +ad_proc -public classified-ads::get_root_folder_id {} { + Returns the folder id of the classified ads root folder, error if none +} { + set folder_id [root_folder_exists_p] - return $folder_id - } + if {!$folder_id} { + ad_return_error "Root Folder not found" \ + "The root folder for [package_key] was not found. The datamodel might not be properly installed. Did you restart the server after installation?" + ad_script_abort + } + return $folder_id +} - ad_proc -public get_folder_id { - {-package_id} - } { - Returns the folder_id for an instance of classified ads - @param package_id The package id of this classified ads instance. - Default to current instance if none passed. - } { - if {![exists_and_not_null package_id]} { - set package_id [ad_conn package_id] - } +ad_proc -public classified-ads::get_folder_id { + {-package_id} +} { + Returns the folder_id for an instance of classified ads - return [db_string select_folder_id {}] - } + @param package_id The package id of this classified ads instance. + Default to current instance if none passed. +} { + if {![exists_and_not_null package_id]} { + set package_id [ad_conn package_id] + } + return [db_string select_folder_id {}] +} - ad_proc -public get_mounted_packages {} { - Returns a list of mounted classified-ads packages - } { - set package_key [package_key] - return [db_list select_packages {}] - } - ad_proc -public get_content_type { - {-item_id:required} - } { +ad_proc -public classified-ads::get_mounted_packages {} { + Returns a list of mounted classified-ads packages +} { + set package_key [package_key] + return [db_list select_packages {}] +} + +ad_proc -public classified-ads::get_content_type { + {-item_id:required} +} { Gets the content type of a given item - } { - return [db_string select_type {}] - } +} { + return [db_string select_type {}] +} - ad_proc -public get_table_name { - {-content_type:required} - } { - Gets the table name of one content type - } { - return [db_string select_table_name {}] - } +ad_proc -public classified-ads::get_table_name { + {-content_type:required} +} { + Gets the table name of one content type +} { + return [db_string select_table_name {}] +} - ad_proc -public register_content_type { - {-folder_id:required} - {-content_type:required} - {-include_subtypes "f"} - } { - Registers a given content type to a particular folder - } { - return [db_list register_content_type {}] - } +ad_proc -public classified-ads::register_content_type { + {-folder_id:required} + {-content_type:required} + {-include_subtypes "f"} +} { + Registers a given content type to a particular folder +} { + return [db_list register_content_type {}] +} - ad_proc -public create_package_folder { - {-root_folder_id:required} - {-package_id:required} - } { - Creates a content revision folder for one instance of classified ads +ad_proc -public classified-ads::create_package_folder { + {-root_folder_id:required} + {-package_id:required} +} { + Creates a content revision folder for one instance of classified ads - @param root_folder_id The root folder id for the whole classified ads package - @param package_id The package id of the instance whose folder is to be created - } { - set name "[package_key]-$package_id" - set label "$name folder" - set description "Container folder for one instance of classified-ads" + @param root_folder_id The root folder id for the whole classified ads package + @param package_id The package id of the instance whose folder is to be created +} { + set name "[package_key]-$package_id" + set label "$name folder" + set description "Container folder for one instance of classified-ads" - db_transaction { - set new_folder_id [db_exec_plsql create_folder {}] - db_exec_plsql associate_package {} - } + db_transaction { + set new_folder_id [db_exec_plsql create_folder {}] + db_exec_plsql associate_package {} + } - return $new_folder_id - } + return $new_folder_id +} - ad_proc -public create_ca_item { - {-item_id_element:required} - {-parent_id} +ad_proc -public classified-ads::create_ca_item { + {-item_id_element:required} + {-parent_id} {-category_id} - {-content_type:required} - {-form_id:required} - {-title_column "title"} - {-description_column "description"} - {-data_column "data"} - } { - Creates a classified ads item. This is generic enough to: - 1. handle items that are either derived from content_revision or not - 2. dynamically generate insert statements for extension tables - 3. dynamically generate insert statements to handle generic attributes - 4. create new revisions as appropriate + {-content_type:required} + {-form_id:required} + {-title_column "title"} + {-description_column "description"} + {-data_column "data"} +} { + Creates a classified ads item. This is generic enough to: + 1. handle items that are either derived from content_revision or not + 2. dynamically generate insert statements for extension tables + 3. dynamically generate insert statements to handle generic attributes + 4. create new revisions as appropriate @author Deds Castillo @author Roberto Mello (rmello@fslc.usu.edu) - - @param item_id_element The name of the form element that should be used as the item id - @param content_type The type of the item being inserted - @param form_id The ID of the form that contains the the name/value pairs - } { - set package_id [ad_conn package_id] + @param item_id_element The name of the form element that should be used as the item id + @param content_type The type of the item being inserted + @param form_id The ID of the form that contains the the name/value pairs - if {![info exists parent_id]} { - set parent_id [get_folder_id -package_id $package_id] - } +} { + set package_id [ad_conn package_id] - set creation_user [ad_conn user_id] - set creation_ip [ad_conn peeraddr] + if {![info exists parent_id]} { + set parent_id [get_folder_id -package_id $package_id] + } - # DEDS: FIXME - for now we are assuming required fields are filtered - # out by the validation in the form procedures. i think we should - # double check it here again and barf if one of them is missing + set creation_user [ad_conn user_id] + set creation_ip [ad_conn peeraddr] - # get the item id, barf if not present + # DEDS: FIXME - for now we are assuming required fields are filtered + # out by the validation in the form procedures. i think we should + # double check it here again and barf if one of them is missing - if {[template::element::exists $form_id $item_id_element]} { - set item_id [template::element::get_value $form_id $item_id_element] - } else { - ad_return_complaint 1 "
  • Passed in item id not found" - ad_script_abort - } + # get the item id, barf if not present - # check if this is a subclass of content_revision + if {[template::element::exists $form_id $item_id_element]} { + set item_id [template::element::get_value $form_id $item_id_element] + } else { + ad_return_complaint 1 "
  • Passed in item id not found" + ad_script_abort + } - set cr_subclass_p [is_subclass -content_type $content_type -parent_type content_revision] - set content_item [get_supertype -content_type $content_type] + # check if this is a subclass of content_revision - set name "$content_type -- $item_id" - set title [template::element::get_value $form_id $title_column] + set cr_subclass_p [is_subclass -content_type $content_type -parent_type content_revision] + set content_item [get_supertype -content_type $content_type] - if {[empty_string_p $title]} { - # make sure there is always a title - set title $name - } + set name "$content_type -- $item_id" + set title [template::element::get_value $form_id $title_column] - set description [template::element::get_value $form_id $description_column] + if {[empty_string_p $title]} { + # make sure there is always a title + set title $name + } - if {[template::element::exists $form_id $data_column]} { - set data [template::element::get_value $form_id $data_column] - } + set description [template::element::get_value $form_id $description_column] - # do everything in a transaction + if {[template::element::exists $form_id $data_column]} { + set data [template::element::get_value $form_id $data_column] + } - db_transaction { - # insert the content item + # do everything in a transaction - set object_id [db_exec_plsql insert_content_item {}] - set cr_item_id $object_id + db_transaction { + # insert the content item - if {$cr_subclass_p} { - set object_id [db_exec_plsql insert_content_revision {}] - } + set object_id [db_exec_plsql insert_content_item {}] + set cr_item_id $object_id - # RBM: If a category was passed, assign the ad to it. - - if {[info exists category_id]} { - db_exec_plsql assign_item_to_category {} - } + if {$cr_subclass_p} { + set object_id [db_exec_plsql insert_content_revision {}] + } - # DEDS: FIXME - this only supports one table - # fix it so that it can span multiple tables - # - # get the type specific attributes + # RBM: If a category was passed, assign the ad to it. - set type_specific_attr_list [get_attributes -content_type $content_type -storage "type_specific"] - - if {[llength $type_specific_attr_list]} { - # we always reference the item_id - set name_list [list $item_id_element] - set value_list [list $object_id] - set type_specific_bind_vars [ns_set create] + if {[info exists category_id]} { + db_exec_plsql assign_item_to_category {} + } + + # DEDS: FIXME - this only supports one table + # fix it so that it can span multiple tables + # + # get the type specific attributes + + set type_specific_attr_list [get_attributes -content_type $content_type -storage "type_specific"] + + if {[llength $type_specific_attr_list]} { + # we always reference the item_id + set name_list [list $item_id_element] + set value_list [list $object_id] + set type_specific_bind_vars [ns_set create] - foreach one_attribute $type_specific_attr_list { - set column_name [ns_set get $one_attribute column_name] - set table_name [ns_set get $one_attribute table_name] - - if {[template::element::exists $form_id $column_name]} { - lappend name_list $column_name - lappend value_list ":$column_name" - set one_value [template::element::get_value $form_id $column_name] + foreach one_attribute $type_specific_attr_list { + set column_name [ns_set get $one_attribute column_name] + set table_name [ns_set get $one_attribute table_name] + + if {[template::element::exists $form_id $column_name]} { + lappend name_list $column_name + lappend value_list ":$column_name" + set one_value [template::element::get_value $form_id $column_name] - if {[string match "date" [ns_set get $one_attribute datatype]]} { - set one_value [classified-ads::widgets::date_widget_to_sql -date $one_value] - } + if {[string match "date" [ns_set get $one_attribute datatype]]} { + set one_value [classified-ads::widgets::date_widget_to_sql -date $one_value] + } - ns_set put $type_specific_bind_vars $column_name $one_value + ns_set put $type_specific_bind_vars $column_name $one_value - } else { - set default_value [ns_set get $one_attribute default_value] + } else { + set default_value [ns_set get $one_attribute default_value] - if {![empty_string_p $default_value]} { - lappend name_list $column_name - lappend value_list ":$column_name" - ns_set put $type_specific_bind_vars $column_name $default_value - } - } - } + if {![empty_string_p $default_value]} { + lappend name_list $column_name + lappend value_list ":$column_name" + ns_set put $type_specific_bind_vars $column_name $default_value + } + } + } - # create the insert statement for type specific attributes + # create the insert statement for type specific attributes - set plsql_query "insert into $table_name ([join $name_list ", "]) values ([join $value_list ", "])" - - # insert the type specific data + set plsql_query "insert into $table_name ([join $name_list ", "]) values ([join $value_list ", "])" - db_dml insert_data {} -bind $type_specific_bind_vars - ns_set free $type_specific_bind_vars - } - - # get the generic attributes + # insert the type specific data - set generic_attr_list [get_attributes -content_type $content_type -storage "generic"] - - if {[llength $generic_attr_list]} { - - foreach one_attribute $generic_attr_list { - set attribute_id [ns_set get $one_attribute attribute_id] - set column_name [ns_set get $one_attribute column_name] - set datatype [ns_set get $one_attribute datatype] - - if {[template::element::exists $form_id $column_name]} { - set attr_value [template::element::get_value $form_id $column_name] + db_dml insert_data {} -bind $type_specific_bind_vars + ns_set free $type_specific_bind_vars + } + + # get the generic attributes + + set generic_attr_list [get_attributes -content_type $content_type -storage "generic"] + + if {[llength $generic_attr_list]} { + + foreach one_attribute $generic_attr_list { + set attribute_id [ns_set get $one_attribute attribute_id] + set column_name [ns_set get $one_attribute column_name] + set datatype [ns_set get $one_attribute datatype] + + if {[template::element::exists $form_id $column_name]} { + set attr_value [template::element::get_value $form_id $column_name] - if {[string match "date" $datatype]} { - set attr_value [classified-ads::widgets::date_widget_to_sql -date $attr_value] - } - } else { - set default_value [ns_set get $one_attribute default_value] - - if {![empty_string_p $default_value]} { - set attr_value $default_value - } else { - set attr_value "" - } - } + if {[string match "date" $datatype]} { + set attr_value [classified-ads::widgets::date_widget_to_sql -date $attr_value] + } + } else { + set default_value [ns_set get $one_attribute default_value] - insert_generic_value -object_id $item_id -attribute_id $attribute_id -attr_value $attr_value - } - } - } on_error { - ad_return_complaint 1 "
  • $errmsg" - ad_script_abort - } + if {![empty_string_p $default_value]} { + set attr_value $default_value + } else { + set attr_value "" + } + } - return $item_id - - } + insert_generic_value -object_id $item_id -attribute_id $attribute_id -attr_value $attr_value + } + } + } on_error { + ad_return_complaint 1 "
  • $errmsg" + ad_script_abort + } - ad_proc -public edit_ca_item { - {-item_id_element:required} - {-form_id:required} - {-title_column "title"} - {-description_column "description"} - {-data_column "data"} - {-revision_id} - } { - Edits a classified ads item. + return $item_id - @param item_id_element The name of the form element that should be used as the item id - @param form_id The ID of the form that contains the the name/value pairs - @param title_column The element name in the form that will be used as title of this content - @param description_column The element name in the form that will be used as description of this content - } { +} - set creation_user [ad_conn user_id] - set creation_ip [ad_conn peeraddr] +ad_proc -public classified-ads::edit_ca_item { + {-item_id_element:required} + {-form_id:required} + {-title_column "title"} + {-description_column "description"} + {-data_column "data"} + {-revision_id} +} { + Edits a classified ads item. - # DEDS: FIXME - for now we are assuming required fields are filtered - # out by the validation in the form procedures. i think we should - # double check it here again and barf if one of them is missing + @param item_id_element The name of the form element that should be used as the item id + @param form_id The ID of the form that contains the the name/value pairs + @param title_column The element name in the form that will be used as title of this content + @param description_column The element name in the form that will be used as description of this content +} { - # get the item id, barf if not present + set creation_user [ad_conn user_id] + set creation_ip [ad_conn peeraddr] - if {[template::element::exists $form_id $item_id_element]} { - set item_id [template::element::get_value $form_id $item_id_element] - } else { - ad_return_complaint 1 "
  • passed in item id not found" - ad_script_abort - } + # DEDS: FIXME - for now we are assuming required fields are filtered + # out by the validation in the form procedures. i think we should + # double check it here again and barf if one of them is missing - set create_revision_p 0 + # get the item id, barf if not present - # check if this is a subclass of content_revision + if {[template::element::exists $form_id $item_id_element]} { + set item_id [template::element::get_value $form_id $item_id_element] + } else { + ad_return_complaint 1 "
  • passed in item id not found" + ad_script_abort + } - set content_type [get_content_type -item_id $item_id] - set cr_subclass_p [is_subclass -content_type $content_type -parent_type content_revision] + set create_revision_p 0 - if {$cr_subclass_p} { - if {[parameter::get -parameter create_new_ad_revision_p -default 0]} { - set create_revision_p 1 - } - if {[info exists revision_id]} { - set object_id $revision_id - } else { - set object_id [get_latest_revision -item_id $item_id] - } + # check if this is a subclass of content_revision - } else { - set object_id $item_id - } + set content_type [get_content_type -item_id $item_id] + set cr_subclass_p [is_subclass -content_type $content_type -parent_type content_revision] - set name "$content_type -- $item_id" - set title [template::element::get_value $form_id $title_column] + if {$cr_subclass_p} { + if {[parameter::get -parameter create_new_ad_revision_p -default 0]} { + set create_revision_p 1 + } + if {[info exists revision_id]} { + set object_id $revision_id + } else { + set object_id [get_latest_revision -item_id $item_id] + } - if {[empty_string_p $title]} { - # make sure there is always a title - set title $name - } + } else { + set object_id $item_id + } + + set name "$content_type -- $item_id" + set title [template::element::get_value $form_id $title_column] + + if {[empty_string_p $title]} { + # make sure there is always a title + set title $name + } - set description [template::element::get_value $form_id $description_column] + set description [template::element::get_value $form_id $description_column] - if {[template::element::exists $form_id $data_column]} { - set data [template::element::get_value $form_id $data_column] - } + if {[template::element::exists $form_id $data_column]} { + set data [template::element::get_value $form_id $data_column] + } - # do everything in a transaction + # do everything in a transaction - db_transaction { - # DEDS: FIXME - this only supports one table - # fix it so that it can span multiple tables - - if {$create_revision_p} { - set object_id [db_exec_plsql insert_content_revision {}] - } elseif {$cr_subclass_p} { - # DEDS: FIXME - this is straghtforward update. we should be using cr api. - db_dml update_content_revision {} - } - - # get the type specific attributes - set type_specific_attr_list [get_attributes -content_type $content_type -storage "type_specific"] - - if {[llength $type_specific_attr_list]} { - # we always reference the item_id - set update_list [list] - set name_list [list $item_id_element] - set value_list [list $object_id] - set type_specific_bind_vars [ns_set create] - - foreach one_attribute $type_specific_attr_list { - set column_name [ns_set get $one_attribute column_name] - set table_name [ns_set get $one_attribute table_name] - set datatype [ns_set get $one_attribute datatype] - - if {[template::element::exists $form_id $column_name]} { - lappend name_list $column_name - lappend value_list ":$column_name" - lappend update_list "$column_name = :$column_name" - set one_value [template::element::get_value $form_id $column_name] - if {[string match "date" $datatype]} { - set one_value [classified-ads::widgets::date_widget_to_sql -date $one_value] - } - ns_set put $type_specific_bind_vars $column_name $one_value - } - } + db_transaction { + # DEDS: FIXME - this only supports one table + # fix it so that it can span multiple tables - ns_set put $type_specific_bind_vars item_id $object_id + if {$create_revision_p} { + set object_id [db_exec_plsql insert_content_revision {}] - # create the update statement for type specific attributes + } elseif {$cr_subclass_p} { + # DEDS: FIXME - this is straghtforward update. we should be using cr api. + db_dml update_content_revision {} + } - if {$create_revision_p} { - set plsql_query "insert into $table_name ([join $name_list ", "]) values ([join $value_list ", "])" - } else { - set plsql_query "update $table_name set [join $update_list ", "] where $item_id_element = :item_id" - } - - # update the type specific data + # Get the type specific attributes - db_dml update_data {} -bind $type_specific_bind_vars - ns_set free $type_specific_bind_vars - } - - # get the generic attributes - - set generic_attr_list [get_attributes -content_type $content_type -storage "generic"] - - if {[llength $generic_attr_list]} { - foreach one_attribute $generic_attr_list { - set attribute_id [ns_set get $one_attribute attribute_id] - set column_name [ns_set get $one_attribute column_name] - set datatype [ns_set get $one_attribute datatype] - - if {[template::element::exists $form_id $column_name]} { - set attr_value [template::element::get_value $form_id $column_name] + set type_specific_attr_list [get_attributes -content_type $content_type -storage "type_specific"] + + if {[llength $type_specific_attr_list]} { + # + # We always reference the item_id + # - if {[string match "date" $datatype]} { - set attr_value [classified-ads::widgets::date_widget_to_sql -date $attr_value] - } - } + set update_list [list] + set name_list [list $item_id_element] + set value_list [list $object_id] + set type_specific_bind_vars [ns_set create] + + foreach one_attribute $type_specific_attr_list { + set column_name [ns_set get $one_attribute column_name] + set table_name [ns_set get $one_attribute table_name] + set datatype [ns_set get $one_attribute datatype] - if {$create_revision_p} { - insert_generic_value -object_id $object_id -attribute_id $attribute_id -attr_value $attr_value - } else { - update_generic_value -object_id $object_id -attribute_id $attribute_id -attr_value $attr_value - } - - } - } - } on_error { - ad_return_complaint 1 "
  • $errmsg" - ad_script_abort - } - - return $object_id - } + if {[template::element::exists $form_id $column_name]} { + lappend name_list $column_name + lappend value_list ":$column_name" + lappend update_list "$column_name = :$column_name" + set one_value [template::element::get_value $form_id $column_name] + if {[string match "date" $datatype]} { + set one_value [classified-ads::widgets::date_widget_to_sql -date $one_value] + } + ns_set put $type_specific_bind_vars $column_name $one_value + } + } - ad_proc -public is_subclass { - {-content_type:required} - {-parent_type:required} - } { - Returns 1 if an object type is a subclass of another - - @param content_type The object type to check - @param parent_type The supertype class the proc test against - } { - return [ad_decode [db_string test_subclass {}] f 0 1] - } + ns_set put $type_specific_bind_vars item_id $object_id + # create the update statement for type specific attributes - ad_proc -public get_attributes { - {-content_type:required} - {-package_id} - {-storage "all"} - } { - Returns a list of ns_sets of the attributes for one content type - - @param content_type This is the content type whose attributes we get - @param package_id Only the attributes belonging to this package is retrieved. - Defaults to current package. - @param storage Only the attributes who belong to this storage type are retrieved. - Can be "type_specific", "generic", or "all". - } { - if {![exists_and_not_null package_id]} { - set package_id [ad_conn package_id] - } + if {$create_revision_p} { + set plsql_query "insert into $table_name ([join $name_list ", "]) values ([join $value_list ", "])" + } else { + set plsql_query "update $table_name set [join $update_list ", "] where $item_id_element = :item_id" + } - if {![string equal $storage "all"]} { - set storage_stub "and storage = '$storage'" - } else { - set storage_stub "" - } + # update the type specific data + + db_dml update_data {} -bind $type_specific_bind_vars + ns_set free $type_specific_bind_vars + } - return [db_list_of_ns_sets select_attributes {}] - } + # get the generic attributes + + set generic_attr_list [get_attributes -content_type $content_type -storage "generic"] + + if {[llength $generic_attr_list]} { + foreach one_attribute $generic_attr_list { + set attribute_id [ns_set get $one_attribute attribute_id] + set column_name [ns_set get $one_attribute column_name] + set datatype [ns_set get $one_attribute datatype] - ad_proc -public get_attribute_names { - {-item_id} - {-storage "all"} - } { - Returns a list of lists of the attribute names for one item - - @param package_id The item id whose attribute names we get - } { - if {![exists_and_not_null package_id]} { - set package_id [ad_conn package_id] - } + if {[template::element::exists $form_id $column_name]} { + set attr_value [template::element::get_value $form_id $column_name] - if {![string equal $storage "all"]} { - set storage_stub "and storage = '$storage'" - } else { - set storage_stub "" - } + if {[string match "date" $datatype]} { + set attr_value [classified-ads::widgets::date_widget_to_sql -date $attr_value] + } + } - set content_type [get_content_type -item_id $item_id] - return [db_list_of_lists select_names {}] - } + if {$create_revision_p} { + insert_generic_value -object_id $object_id -attribute_id $attribute_id -attr_value $attr_value + } else { + update_generic_value -object_id $object_id -attribute_id $attribute_id -attr_value $attr_value + } + } + } + } on_error { + ad_return_complaint 1 "
  • $errmsg" + ad_script_abort + } - ad_proc -public get_attribute_values { - {-item_id:required} - {-item_id_element:required} - {-storage "all"} - {-revision_id} - } { + return $object_id +} - Returns a list of lists of the attribute values for one item - - @param item_id The ID of the object whose values we retrieve - @param storage Only the attribute values who belong to this storage type are retrieved. - Can be "type_specific", "generic", or "all". - } { - set values_list [list] - set cr_subclass_p [is_subclass -content_type [get_content_type \ - -item_id $item_id] \ - -parent_type content_revision] +ad_proc -public classified-ads::is_subclass { + {-content_type:required} + {-parent_type:required} +} { + Returns 1 if an object type is a subclass of another - if {![info exists revision_id] && $cr_subclass_p} { - set revision_id [get_latest_revision -item_id $item_id] - } + @param content_type The object type to check + @param parent_type The supertype class the proc test against +} { + return [ad_decode [db_string test_subclass {}] f 0 1] +} - if {[string match $storage "type_specific"] || [string match $storage "all"]} { - set table_name [get_table_name -content_type [get_content_type -item_id $item_id]] - set names_value_list [get_attribute_names -item_id $item_id -storage type_specific] - set names_list [list] - foreach one_name_value $names_value_list { - lappend names_list [lindex $one_name_value 0] - } - - if {$cr_subclass_p} { - set query_string "select [join $names_list ", "] - from $table_name - where $item_id_element = '$revision_id'" - } else { - set query_string "select [join $names_list ", "] - from $table_name - where $item_id_element = '$item_id'" - } - - db_1row select_values {} -column_array type_specific_row - - foreach one_name_value $names_value_list { - set datatype [lindex $one_name_value 1] - set one_value $type_specific_row([lindex $one_name_value 0]) - - if {[string match "date" $datatype] && ![empty_string_p $one_value]} { - set one_value [classified-ads::widgets::sql_to_date_widget -sql_date $one_value -format "YYYY-MM-DD"] - } - - lappend values_list [list [lindex $one_name_value 0] $one_value] - } - } +ad_proc -public classified-ads::get_attributes { + {-content_type:required} + {-package_id} + {-storage "all"} +} { + Returns a list of ns_sets of the attributes for one content type - if {[string match $storage "generic"] || [string match $storage "all"]} { - if {$cr_subclass_p} { - set query_string "select coalesce(aa.column_name, aa.attribute_name) as column_name, - cav.attr_value, - aa.datatype - from acs_attributes aa, - ca_attribute_values cav - where aa.attribute_id = cav.attribute_id and - cav.object_id = '$revision_id'" - } else { - set query_string "select coalesce(aa.column_name, aa.attribute_name) as column_name, - cav.attr_value, - aa.datatype - from acs_attributes aa, - ca_attribute_values cav - where aa.attribute_id = cav.attribute_id and - cav.object_id = '$item_id'" - } - - set generic_list [db_list_of_lists select_values {}] - - foreach one_name $generic_list { - set datatype [lindex $one_name_value 2] - set one_value [lindex $one_name_value 1] - - if {[string match "date" $datatype] && ![empty_string_p $one_value]} { - set one_value [classified-ads::widgets::sql_to_date_widget -sql_date $one_value -format "YYYY-MM-DD"] - } - lappend values_list [list [lindex $one_name 0] $one_value] - } - } + @param content_type This is the content type whose attributes we get + @param package_id Only the attributes belonging to this package is retrieved. + Defaults to current package. + @param storage Only the attributes who belong to this storage type are retrieved. + Can be "type_specific", "generic", or "all". +} { + if {![exists_and_not_null package_id]} { + set package_id [ad_conn package_id] + } - return $values_list - } + if {![string equal $storage "all"]} { + set storage_stub "and storage = '$storage'" + } else { + set storage_stub "" + } - ad_proc -public get_supertype { - {-content_type:required} - } { - Returns the direct ancestor of one content type - - @param content_type This is the content type whose ancestor we get - } { - return [db_string select_supertype {}] - } + return [db_list_of_ns_sets select_attributes {}] +} +ad_proc -public classified-ads::get_attribute_names { + {-item_id} + {-storage "all"} +} { + Returns a list of lists of the attribute names for one item - ad_proc -public insert_generic_value { - {-object_id:required} - {-attribute_id:required} - {-attr_value ""} - } { + @param package_id The item id whose attribute names we get +} { + if {![exists_and_not_null package_id]} { + set package_id [ad_conn package_id] + } - Inserts one value for a generic attribute - - @param object_id The object id of the objects who owns this value - @param attribute_id The id of the attribute that will contain a new value - @param attr_value The associated value of this attribute for this object - + if {![string equal $storage "all"]} { + set storage_stub "and storage = '$storage'" + } else { + set storage_stub "" + } - } { - return [db_exec_plsql insert_value {}] - } + set content_type [get_content_type -item_id $item_id] + return [db_list_of_lists select_names {}] +} - ad_proc -public update_generic_value { - {-object_id:required} - {-attribute_id:required} - {-attr_value ""} - } { - Updates one value for a generic attribute - - @param object_id The object id of the objects who owns this value - @param attribute_id The id of the attribute that will be updated - @param attr_value The associated value of this attribute for this object - } { - return [db_exec_plsql update_value {}] - } +ad_proc -public classified-ads::get_attribute_values { + {-item_id:required} + {-item_id_element:required} + {-storage "all"} + {-revision_id} +} { + Returns a list of lists of the attribute values for one item - ad_proc -public get_latest_revision { - {-item_id:required} - } { - Returns the latest revision for one item - - @param item_id The id of the item that we want to get the latest revision - } { - return [db_string get_revision {} -default 0] - } + @param item_id The ID of the object whose values we retrieve + @param storage Only the attribute values who belong to this storage type are retrieved. + Can be "type_specific", "generic", or "all". +} { + set values_list [list] + set cr_subclass_p [is_subclass -content_type [get_content_type \ + -item_id $item_id] \ + -parent_type content_revision] - ad_proc -public get_content { - {-revision_id:required} - } { - Returns the content of one item - - @param revision_id The id of the revision to get the data from - } { - return [db_string select_content {}] - } + if {![info exists revision_id] && $cr_subclass_p} { + set revision_id [get_latest_revision -item_id $item_id] + } + if {[string match $storage "type_specific"] || [string match $storage "all"]} { + set table_name [get_table_name -content_type [get_content_type -item_id $item_id]] + set names_value_list [get_attribute_names -item_id $item_id -storage type_specific] + set names_list [list] - ad_proc -public context_bar { - {-node_id} - args - } { - Returns a context bar relative to classified ads - - @param node_id if provided, then we work up from this node - } { - if { ![info exists node_id] } { - set node_id [ad_conn node_id] - } + foreach one_name_value $names_value_list { + lappend names_list [lindex $one_name_value 0] + } - set context [list] - - db_foreach context {} { - lappend context [list $url $object_name] - } - - if { [string match admin/* [ad_conn extra_url]] } { - lappend context [list "[ad_conn package_url]admin/" "Administration"] - } - - if {[llength $args] == 0} { - # fix last element to just be literal string - - set context [lreplace $context end end [lindex [lindex $context end] 1]] - } - - return [ad_context_bar_html [concat $context $args]] - } + if {$cr_subclass_p} { + set query_string "select [join $names_list ", "] + from $table_name + where $item_id_element = '$revision_id'" + } else { + set query_string "select [join $names_list ", "] + from $table_name + where $item_id_element = '$item_id'" + } - ad_proc validate_isbn { isbn } { - Does a simple check-digit verigication of isbn. - @author Ben Bytheway - } { - set isbn [string trim $isbn] - regsub -all {(\D&^Xi&^x)} $isbn "" isbn - - if {![regexp {^(\d|X|x){10}$} $isbn]} { - return 1 - } - - set check 0 - set test_isbn [split $isbn ""] - - if {[lindex $test_isbn end] == "x" || [lindex $test_isbn end] == "X"} { - set test_isbn [lreplace $test_isbn end end 10 ] - } - - for {set i 0} {$i <= 9} {incr i} { - set digit [lindex $test_isbn $i] - set check [expr ($digit * (10 - $i)) + $check] - } + db_1row select_values {} -column_array type_specific_row - set check [expr $check % 11] + foreach one_name_value $names_value_list { + set datatype [lindex $one_name_value 1] + set one_value $type_specific_row([lindex $one_name_value 0]) - if { !$check && [string index $isbn 0] != 6} { - return 0 - } else { - return 1 - } - } + if {[string match "date" $datatype] && ![empty_string_p $one_value]} { + set one_value [classified-ads::widgets::sql_to_date_widget -sql_date $one_value -format "YYYY-MM-DD"] + } + + lappend values_list [list [lindex $one_name_value 0] $one_value] + } + } + + # RBM: FIXME - We shouldn't generate the entire query here? + + if {[string match $storage "generic"] || [string match $storage "all"]} { + if {$cr_subclass_p} { + set query_string "select coalesce(aa.column_name, aa.attribute_name) as column_name, + cav.attr_value, + aa.datatype + from acs_attributes aa, + ca_attribute_values cav + where aa.attribute_id = cav.attribute_id and + cav.object_id = '$revision_id'" + } else { + set query_string "select coalesce(aa.column_name, aa.attribute_name) as column_name, + cav.attr_value, + aa.datatype + from acs_attributes aa, + ca_attribute_values cav + where aa.attribute_id = cav.attribute_id and + cav.object_id = '$item_id'" + } + + set generic_list [db_list_of_lists select_values {}] + + foreach one_name $generic_list { + set datatype [lindex $one_name_value 2] + set one_value [lindex $one_name_value 1] + + if {[string match "date" $datatype] && ![empty_string_p $one_value]} { + set one_value [classified-ads::widgets::sql_to_date_widget -sql_date $one_value -format "YYYY-MM-DD"] + } + lappend values_list [list [lindex $one_name 0] $one_value] + } + } + + return $values_list } + +ad_proc -public classified-ads::get_supertype { + {-content_type:required} +} { + Returns the direct ancestor of one content type + + @param content_type This is the content type whose ancestor we get +} { + return [db_string select_supertype {}] +} + + +ad_proc -public classified-ads::insert_generic_value { + {-object_id:required} + {-attribute_id:required} + {-attr_value ""} +} { + Inserts one value for a generic attribute + + @param object_id The object id of the objects who owns this value + @param attribute_id The id of the attribute that will contain a new value + @param attr_value The associated value of this attribute for this object +} { + return [db_exec_plsql insert_value {}] +} + + +ad_proc -public classified-ads::update_generic_value { + {-object_id:required} + {-attribute_id:required} + {-attr_value ""} +} { + Updates one value for a generic attribute + + @param object_id The object id of the objects who owns this value + @param attribute_id The id of the attribute that will be updated + @param attr_value The associated value of this attribute for this object +} { + return [db_exec_plsql update_value {}] +} + + +ad_proc -public classified-ads::get_latest_revision { + {-item_id:required} +} { + Returns the latest revision for one item + + @param item_id The id of the item that we want to get the latest revision +} { + return [db_string get_revision {} -default 0] +} + + +ad_proc -public classified-ads::get_content { + {-revision_id:required} +} { + Returns the content of one item + + @param revision_id The id of the revision to get the data from +} { + return [db_string select_content {}] +} + + +ad_proc -public classified-ads::context_bar { + {-node_id} + args +} { + Returns a context bar relative to classified ads + + @param node_id if provided, then we work up from this node +} { + if { ![info exists node_id] } { + set node_id [ad_conn node_id] + } + + set context [list] + + db_foreach context {} { + lappend context [list $url $object_name] + } + + if { [string match admin/* [ad_conn extra_url]] } { + lappend context [list "[ad_conn package_url]admin/" "Administration"] + } + + if {[llength $args] == 0} { + # fix last element to just be literal string + + set context [lreplace $context end end [lindex [lindex $context end] 1]] + } + + return [ad_context_bar_html [concat $context $args]] +} + +ad_proc validate_isbn { isbn } { + Does a simple check-digit verigication of isbn. + @author Ben Bytheway +} { + set isbn [string trim $isbn] + regsub -all {(\D&^Xi&^x)} $isbn "" isbn + + if {![regexp {^(\d|X|x){10}$} $isbn]} { + return 1 + } + + set check 0 + set test_isbn [split $isbn ""] + + if {[lindex $test_isbn end] == "x" || [lindex $test_isbn end] == "X"} { + set test_isbn [lreplace $test_isbn end end 10 ] + } + + for {set i 0} {$i <= 9} {incr i} { + set digit [lindex $test_isbn $i] + set check [expr ($digit * (10 - $i)) + $check] + } + + set check [expr $check % 11] + + if { !$check && [string index $isbn 0] != 6} { + return 0 + } else { + return 1 + } +} Index: openacs-4/contrib/packages/classified-ads/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/www/index.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/contrib/packages/classified-ads/www/index.tcl 16 Jul 2003 04:52:32 -0000 1.1 +++ openacs-4/contrib/packages/classified-ads/www/index.tcl 23 Jul 2003 21:08:19 -0000 1.2 @@ -1,12 +1,10 @@ ad_page_contract { - Classified Ads User Interface + Classified Ads Main User Page - @author Deds Castillo (deds@infiniteinfo.com) - @creation-date 2002-10-08 + @author Roberto Mello + @creation-date 2003-07-21 @cvs-id $Id$ } - -ad_returnredirect categories Index: openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.adp 23 Jul 2003 21:08:19 -0000 1.1 @@ -0,0 +1,6 @@ + +@title@ +@context@ +ad.title + + Index: openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.tcl 21 Jul 2003 05:23:56 -0000 1.2 +++ openacs-4/contrib/packages/classified-ads/www/admin/ad-delete.tcl 23 Jul 2003 21:08:19 -0000 1.3 @@ -9,25 +9,40 @@ } { ad_id:integer,notnull title:notnull + description:notnull {return_url "categories"} + context:notnull } +set actions [list [list "Yes, Delete this Ad" delete] [list " Cancel " cancel]] +set action [form get_action ad_delete] + +switch $action { + "delete" { + if {[catch {classified-ads::ads::delete -ad_id $ad_id} errmsg]} { + ad_return_error "Problems deleting ad" "
  • The following error occured during deletion: $errmsg" + ad_script_abort + } + ad_returnredirect $return_url + ad_script_abort + } + "cancel" { + ad_returnredirect "ad-one?ad_id=$ad_id&return_url=[export_vars -url $return_url]" + ad_script_abort + } +} + ad_form -name ad_delete -export ad_id \ -mode display \ - -cancel_label "No" \ - -cancel_url "ad-one?ad_id=$ad_id" \ + -actions $actions \ -form { - {title:text(text) {label "Title"} - {value $title} } - {you_sure:text(inform) {label "Are you sure you want to delete this ad?"} } + {title:text(text) {label "Title"} + {value $title} + {section "Are you sure you want to delete this ad?"}} + {description:text(textarea) {label "Short Description"} + {value $description} + {html {cols 60 rows 3 wrap soft}} } + {context:text(hidden) {value $context}} -} -edit_data { - if {[catch {classified-ads::ads::delete -ad_id $ad_id} errmsg]} { - ad_return_complaint 1 "
  • The following error occured during deletion: $errmsg" - ad_script_abort - } - - ad_returnredirect $return_url - ad_script_abort -} +} Index: openacs-4/contrib/packages/classified-ads/www/admin/ad-one.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/www/admin/ad-one.adp,v diff -u -r1.1 -r1.2 --- openacs-4/contrib/packages/classified-ads/www/admin/ad-one.adp 21 Jul 2003 05:23:56 -0000 1.1 +++ openacs-4/contrib/packages/classified-ads/www/admin/ad-one.adp 23 Jul 2003 21:08:19 -0000 1.2 @@ -1,5 +1,5 @@ -@title@ +@url_title@ @context@ ad.title Index: openacs-4/contrib/packages/classified-ads/www/admin/ad-one.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/www/admin/ad-one.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/contrib/packages/classified-ads/www/admin/ad-one.tcl 21 Jul 2003 05:23:56 -0000 1.1 +++ openacs-4/contrib/packages/classified-ads/www/admin/ad-one.tcl 23 Jul 2003 21:08:19 -0000 1.2 @@ -22,9 +22,11 @@ ##### set actions [list [list " Edit " edit] [list " Delete " delete]] -set title "Ad $ad_id" +set url_title "Ad $ad_id" set context [classified-ads::ads::generate_trail -ad_id $ad_id] +set action [form get_action ad] + ad_form -name ad -cancel_url $return_url -mode display -actions $actions -form { ad_id:key {return_url:text(hidden) {label "return url"} @@ -64,20 +66,19 @@ ad_script_abort } -edit_request { - # RBM: Hack because of ad_form's limitation -} + if { [string equal $action "delete"] } { + # + # If the delete button was pressed + # + set title [template::element::get_value ad title] + set description [template::element::get_value ad description] + ad_returnredirect "ad-delete?[export_vars -url {ad_id title description return_url context}]" -set action [form get_action ad] - -if { [string equal $action "delete"] } { - # - # If the delete button was pressed - # - #rp_form_put title $adinfo(title) - #rp_form_put return_url $return_url - rp_internal_redirect ad-delete - ad_script_abort + #rp_form_put context $context + #rp_internal_redirect ad-delete + ad_script_abort + } } ad_return_template Index: openacs-4/contrib/packages/classified-ads/www/doc/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/classified-ads/www/doc/index.adp,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/classified-ads/www/doc/index.adp 21 Jul 2003 16:08:07 -0000 1.3 +++ openacs-4/contrib/packages/classified-ads/www/doc/index.adp 23 Jul 2003 21:08:19 -0000 1.4 @@ -53,6 +53,7 @@
  • general-comments integration.
  • Make it so custom fields can be added on a per-category basis.
  • general-ratings for users (for the future). +
  • Uploading of images with parameter to allow/disallow.