Forum OpenACS Development: Problem Using AMS

Collapse
Posted by Jorge Alcaraz on
Hello, I have a business need: Extend the user attributes in the whole platform, so I started a research and I've found AMS, that solved my problem untill the moment of apply it to my environment.

I have created the corresponding list and added the attributes to the register form using this methods:

#This after the ad_form call
ad_form -extend -name register -form [ams::ad_form::elements -package_key "acs-subsite" -object_type "person" -list_name "custom_fields"]

#And this inside the on_submit
ams::ad_form::save -package_key "acs-subsite" -object_type "person" -list_name "custom_fields" -form_name "register" -object_id $user_id

And it works, I can create users with those attributes, but the problem is in the user_info form. I can see it doesn't use get_registration_form_elements and it create the elements one by one. So I add the form elements in the same way:

#This to add the form elements
ad_form -extend -name user_info -form [ams::ad_form::elements -package_key "acs-subsite" -object_type "person" -list_name "custom_fields"]

#And this to fill the values
ams::ad_form::values -package_key "acs-subsite" -object_type "person" -list_name "custom_fields" -form_name "user_info" -object_id $user_id

And it works, the problem is in the the on_submit part of the ad_form, using the same method, I always got the following error:

Error in include template "/var/lib/aolserver/openacs/packages/acs-subsite/lib/user-info": Transaction aborted: Element "born_date" does not exist in form "user_info"

I think the problem is for the way the form is been built. The complete code of my user-info.tcl is this, I hope somebody have fixed that.

#
# Expects:
# user_id:optional
# return_url:optional
# edit_p:optional
# message:optional
# show_groups_p:optional

if { ![exists_and_not_null user_id] } {
set user_id [ad_conn untrusted_user_id]
} elseif { $user_id != [auth::get_user_id -account_status closed] } {
permission::require_permission -object_id $user_id -privilege admin
}

puts "Id de Usuario $user_id"

set extra_vals [ams::values -package_key "acs-subsite" -object_type "person" -list_name "custom_fields" -object_id $user_id]

array set return_array [list]

foreach {section attribute pretty_name value} $extra_vals {
set return_array($attribute) [lang::util::localize $value]
}

puts "Fecha de nacimiento $return_array(born_date)"

if { ![exists_and_not_null return_url] } {
set return_url [ad_conn url]
}

if { ![exists_and_not_null show_groups_p] } {
set show_groups_p 0
}

set action_url "[subsite::get_element -element url]user/basic-info-update"

acs_user::get -user_id $user_id -array user -include_bio

set authority_name [auth::authority::get_element -authority_id $user(authority_id) -element pretty_name]

set form_elms { authority_id username first_names last_name email screen_name url bio }
foreach elm $form_elms {
set elm_mode($elm) {}
}
set read_only_elements [auth::sync::get_sync_elements -authority_id $user(authority_id)]
set read_only_notice_p [expr {[llength $read_only_elements] > 0}]
if { ![acs_user::site_wide_admin_p] } {
lappend read_only_elements authority_id username
}
foreach elm $read_only_elements {
set elm_mode($elm) {display}
}

set edit_mode_p [expr ![empty_string_p [form::get_action user_info]]]

set form_mode display
if { [exists_and_equal edit_p 1] } {
set form_mode edit
}

ad_form -name user_info -cancel_url $return_url -action $action_url -mode $form_mode -form {
{user_id:integer(hidden),optional}
{return_url:text(hidden),optional}
{message:text(hidden),optional}
}

# Fill the form elements list
set elms_list [list]

if { [llength [auth::authority::get_authority_options]] > 1 } {
lappend elms_list {
authority_id:text(select)
{mode $elm_mode(authority_id)}
{label "[_ acs-subsite.Authority]"}
{options {[auth::authority::get_authority_options]}}
}
} else {
lappend read_only_elements authority_id
}

if { $user(authority_id) != [auth::authority::local] || ![auth::UseEmailForLoginP] || \
([acs_user::site_wide_admin_p] && [llength [auth::authority::get_authority_options]] > 1) } {
lappend elms_list {
username:text(text)
{label "[_ acs-subsite.Username]"}
{mode $elm_mode(username)}
}
} else {
lappend read_only_elements username
}

# TODO: Use get_registration_form_elements, or auto-generate the form somehow? Deferred.

lappend elms_list {
first_names:text
{label "[_ acs-subsite.First_names]"}
{html {size 50}}
{mode $elm_mode(first_names)}
} {
last_name:text
{label "[_ acs-subsite.Last_name]"}
{html {size 50}}
{mode $elm_mode(last_name)}
} {
email:text
{label "[_ acs-subsite.Email]"}
{html {size 50}}
{mode $elm_mode(email)}
}

if { [acs_user::ScreenName] ne "none" } {
lappend elms_list [list screen_name:text[ad_decode [acs_user::ScreenName] "solicit" ",optional" ""] \
{label "[_ acs-subsite.Screen_name]"} \
{html {size 50}} \
{mode $elm_mode(screen_name)} \
]
}

lappend elms_list {
url:text,optional
{label "[_ acs-subsite.Home_page]"}
{html {size 50}}
{mode $elm_mode(url)}
} {
bio:text(textarea),optional
{label "[_ acs-subsite.Biography]"}
{html {rows 8 cols 60}}
{mode $elm_mode(bio)}
{display_value {[ad_text_to_html -- $user(bio)]}}
}

set locale_options [list]
db_foreach get_locales {} {
if { [lang::message::message_exists_p $locale acs-lang.this-language] } {
set label "[lang::message::lookup $locale acs-lang.this-language]"
}
lappend locale_options [list ${label} $locale]
}

if { [llength $locale_options] > 1 } {
lappend elms_list {
site_wide_locale:text(select_locales),optional
{label "[_ acs-lang.Your_Preferred_Locale]"}
{options $locale_options}
}
}

lappend elms_list [list \
timezone:text(select),optional \
{label "[_ acs-lang.Your_timezone]"} \
[list options [db_list_of_lists get_timezones {}]]]

# Setting focus on the first editable element of the form
set first_element {}
foreach elm $form_elms {
if { $elm_mode($elm) eq "" && ( [lsearch $read_only_elements $elm] eq -1) } {
set first_element $elm
break
}
}
set focus "user_info.$first_element"

ad_form -extend -name user_info -form $elms_list -on_request {
foreach var { authority_id first_names last_name email username screen_name url bio } {
set $var $user($var)
}

ad_form -extend -name user_info -form [ams::ad_form::elements -package_key "acs-subsite" -object_type "person" -list_name "custom_fields"]

ams::ad_form::values -package_key "acs-subsite" -object_type "person" -list_name "custom_fields" -form_name "user_info" -object_id $user_id

set site_wide_locale [ad_conn locale]

set timezone [lang::user::timezone]
if { $timezone eq "" } {
set timezone [lang::system::timezone]
}

} -on_submit {

# Makes the email an image or text according to the level of privacy
catch {email_image::edit_email_image -user_id $user_id -new_email $email} errmsg

set user_info(authority_id) $user(authority_id)
foreach elm { authority_id first_names last_name email username screen_name url bio } {
set user_info(username) $user(username)
if { $elm_mode($elm) eq "" && [info exists $elm] } {
set user_info($elm) [string trim [set $elm]]
}
}

array set result [auth::update_local_account \
-authority_id $user(authority_id) \
-username $user(username) \
-array user_info]

ams::ad_form::save -package_key "acs-subsite" -object_type "person" -list_name "custom_fields" -form_name "user_info" -object_id $user_id



# Handle authentication problems
switch $result(update_status) {
ok {
# Updating locale/tz data
if { [info exists site_wide_locale] } {
lang::user::set_locale $site_wide_locale
}
lang::user::set_timezone $timezone
}
default {
# Adding the error to the first element, but only if there are no element messages
if { [llength $result(element_messages)] == 0 } {
form set_error user_info $first_element $result(update_message)
}

# Element messages
foreach { elm_name elm_error } $result(element_messages) {
form set_error user_info $elm_name $elm_error
}
break
}
}

} -after_submit {
if {[ad_conn account_status] eq "closed"} {
auth::verify_account_status
}

ad_returnredirect $return_url
ad_script_abort
}

# LARS HACK: Make the URL and email elements real links
#I didn't add this because OpenACS doesn't allow me post this

Thanks!

Collapse
2: Re: Problem Using AMS (response to 1)
Posted by Dave Bauer on
You might want to check out ACS Object Management package
Collapse
3: Re: Problem Using AMS (response to 2)
Posted by Jorge Alcaraz on
I have to install that package? Or is it part of the API? I couldn't find documentation in my first extra fast search.

Thanks for your answer :)

Collapse
4: Re: Problem Using AMS (response to 3)
Posted by Dave Bauer on
Hi,

Sorry hit submit too soon. ACS Object Management is a web-based admin UI and API to manage attributes and forms. Its totally unrealted to AMS so it would take some work to convert. It seems like its more recently maintained.

You'd you have to get it from CVS

http://cvs.openacs.org/browse/OpenACS/openacs-4/packages/acs-object-management

Collapse
5: Re: Problem Using AMS (response to 2)
Posted by Jorge Alcaraz on
I think it will not apply for my case, because of this:

https://openacs.org/forums/message-view?message_id=3508127

I'm already using xowiki for CMS. :\

Collapse
6: Re: Problem Using AMS (response to 1)
Posted by Michael Steigman on
The last post on the page you reference indicates that a fix was applied for the issue with Xowiki. In fact many (including us) are using the two together with no problems.

If you're planning to stick with the platform, you should give serious consideration to using the new object management package over AMS - it was designed after considering all of the various solutions (including AMS) to this problem in the toolkit's past.

If there are any specific question you have on the new package, several of us on the forums would be happy to help out.

Collapse
8: Re: Problem Using AMS (response to 6)
Posted by Jorge Alcaraz on
Thanks a lot Michael, well, I'd like to know how did you install the Acs Object Management, like I said before, I already have xowiki installed and I got this error when installing:

psql:acs-views-create.sql:20: ERROR: relation "acs_views" already exists
psql:acs-views-create.sql:61: ERROR: relation "acs_view_attributes" already exists
psql:acs-views-create.sql:303: ERROR: column dotlrn_member_rels.portal_id does not exist

And then:

ERROR: current transaction is aborted

Thanks!

Collapse
9: Re: Problem Using AMS (response to 8)
Posted by Michael Steigman on
It looks like you've already tried to install the package once before - acs_views and acs_view_attributes are part of AOM. I would run the drop script: packages/acs-object-management/sql/postgresql/acs-object-management-drop.sql first, then run the metadata updates I mention in the other thread. The data model install script creates default attribute views for all objects but it chokes when there is bad metadata. The issues mentioned in the other thread are probably common if you have .LRN installed. Copying those data model updates and running them on your system (on test system first!) would probably do the trick but you could also run the datamodel__acs_object_type_check test case at /test/admin as Jeff indicated to see what's going on in your specific install and clean up your object metadata as necessary. Let us know how you make out.
Collapse
7: Re: Problem Using AMS (response to 1)
Posted by Brian Fenton on
Hi Jorge

you could also take a look at Dynfields which is based on AMS and is still maintained. http://www.project-open.org/en/dynfield_design

hope this helps
Brian