From c9ab439221fc49acaa06ca203740d40c3717ac66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chrz=C4=85szcz?= Date: Fri, 26 May 2023 11:41:01 +0200 Subject: [PATCH] Refactor --- include/mod_vcard.hrl | 6 +- .../mod_event_pusher_push_plugin_defaults.erl | 11 +-- src/http_upload/mod_http_upload.erl | 6 +- src/inbox/mod_inbox.erl | 19 ++--- src/inbox/mod_inbox_entries.erl | 6 +- src/mam/mod_mam_utils.erl | 18 ++-- src/mod_muc.erl | 14 ++-- src/mod_muc_api.erl | 2 +- src/mod_muc_room.erl | 77 +++++++---------- src/mongoose_data_forms.erl | 47 +++++++---- src/mongoose_disco.erl | 4 +- src/muc_light/mod_muc_light_codec_legacy.erl | 10 +-- src/pubsub/mod_pubsub.erl | 55 ++++++------- src/pubsub/pubsub_form_utils.erl | 24 +++--- src/vcard/mod_vcard.erl | 82 ++++++++----------- src/vcard/mod_vcard_backend.erl | 4 +- src/vcard/mod_vcard_ldap.erl | 21 ++--- src/vcard/mod_vcard_mnesia.erl | 32 ++++---- src/vcard/mod_vcard_rdbms.erl | 32 ++++---- src/vcard/mod_vcard_riak.erl | 7 +- 20 files changed, 219 insertions(+), 258 deletions(-) diff --git a/include/mod_vcard.hrl b/include/mod_vcard.hrl index f8e02ee128..eae8f7a416 100644 --- a/include/mod_vcard.hrl +++ b/include/mod_vcard.hrl @@ -16,9 +16,7 @@ -export_type([vcard_search/0]). -define(TLFIELD(Type, Label, Var), - mongoose_data_forms:form_field(#{var => Var, type => Type, - label => translate:translate(Lang, Label)})). + #{var => Var, type => Type, label => translate:translate(Lang, Label)}). -define(FIELD(Var, Val), - mongoose_data_forms:form_field(#{var => Var, values => [Val]})). - + #{var => Var, values => [Val]}). diff --git a/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl b/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl index a63d513f20..b00ea19537 100644 --- a/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl +++ b/src/event_pusher/mod_event_pusher_push_plugin_defaults.erl @@ -195,14 +195,9 @@ push_notification_iq(Node, Form, PushPayload) -> ]}. -spec make_form(binary(), mod_event_pusher_push:form()) -> exml:element(). -make_form(FormType, Fields) -> - Children = [mongoose_data_forms:form_type_field(FormType) | - [make_form_field(Field) || Field <- Fields]], - mongoose_data_forms:form(Children, <<"submit">>). - --spec make_form_field(mod_event_pusher_push:form_field()) -> exml:element(). -make_form_field({Name, Value}) -> - mongoose_data_forms:form_field(#{var => Name, values => [Value]}). +make_form(FormType, FieldKVs) -> + Fields = [#{var => Name, values => [Value]} || {Name, Value} <- FieldKVs], + mongoose_data_forms:form(#{ns => FormType, type => <<"submit">>, fields => Fields}). -spec maybe_publish_options(mod_event_pusher_push:form()) -> [exml:element()]. maybe_publish_options([]) -> diff --git a/src/http_upload/mod_http_upload.erl b/src/http_upload/mod_http_upload.erl index abfdfd7676..5d53a16111 100644 --- a/src/http_upload/mod_http_upload.erl +++ b/src/http_upload/mod_http_upload.erl @@ -299,10 +299,8 @@ parse_request(Request) -> -spec get_disco_info_form(MaxFileSizeBin :: binary()) -> exml:element(). get_disco_info_form(MaxFileSizeBin) -> - Fields = [mongoose_data_forms:form_type_field(?NS_HTTP_UPLOAD_030), - mongoose_data_forms:form_field(#{var => <<"max-file-size">>, - values => [MaxFileSizeBin]})], - mongoose_data_forms:form(Fields, <<"result">>). + Fields = [#{var => <<"max-file-size">>, values => [MaxFileSizeBin]}], + mongoose_data_forms:form(#{type => <<"result">>, ns => ?NS_HTTP_UPLOAD_030, fields => Fields}). -spec header_to_xmlel({Key :: binary(), Value :: binary()}) -> exml:element(). diff --git a/src/inbox/mod_inbox.erl b/src/inbox/mod_inbox.erl index 40c6658268..3a9b94828a 100644 --- a/src/inbox/mod_inbox.erl +++ b/src/inbox/mod_inbox.erl @@ -433,16 +433,15 @@ build_inbox_form(HostType) -> AllBoxes = mod_inbox_utils:all_valid_boxes_for_query(HostType), OrderOptions = [{<<"Ascending by timestamp">>, <<"asc">>}, {<<"Descending by timestamp">>, <<"desc">>}], - FieldSpecs = [#{var => <<"start">>, type => <<"text-single">>}, - #{var => <<"end">>, type => <<"text-single">>}, - #{var => <<"hidden_read">>, type => <<"text-single">>, values => [<<"false">>]}, - #{var => <<"order">>, type => <<"list-single">>, values => [<<"desc">>], - options => OrderOptions}, - #{var => <<"box">>, type => <<"list-single">>, values => [<<"all">>], - options => AllBoxes}, - #{var => <<"archive">>, type => <<"boolean">>, values => [<<"false">>]}], - Fields = [mongoose_data_forms:form_field(Spec) || Spec <- FieldSpecs], - mongoose_data_forms:form([mongoose_data_forms:form_type_field(?NS_ESL_INBOX) | Fields]). + Fields = [#{var => <<"start">>, type => <<"text-single">>}, + #{var => <<"end">>, type => <<"text-single">>}, + #{var => <<"hidden_read">>, type => <<"text-single">>, values => [<<"false">>]}, + #{var => <<"order">>, type => <<"list-single">>, values => [<<"desc">>], + options => OrderOptions}, + #{var => <<"box">>, type => <<"list-single">>, values => [<<"all">>], + options => AllBoxes}, + #{var => <<"archive">>, type => <<"boolean">>, values => [<<"false">>]}], + mongoose_data_forms:form(#{ns => ?NS_ESL_INBOX, fields => Fields}). %%%%%%%%%%%%%%%%%%% %% iq-set diff --git a/src/inbox/mod_inbox_entries.erl b/src/inbox/mod_inbox_entries.erl index 9610e25d43..b545f67329 100644 --- a/src/inbox/mod_inbox_entries.erl +++ b/src/inbox/mod_inbox_entries.erl @@ -54,14 +54,12 @@ maybe_get_full_entry(SubEl) -> -spec build_inbox_entry_form(mongooseim:host_type()) -> exml:element(). build_inbox_entry_form(HostType) -> AllBoxes = mod_inbox_utils:all_valid_boxes_for_query(HostType), - FieldSpecs = + Fields = [#{var => <<"box">>, type => <<"list-single">>, values => [<<"all">>], options => AllBoxes}, #{var => <<"archive">>, type => <<"boolean">>, values => [<<"false">>]}, #{var => <<"read">>, type => <<"boolean">>, values => [<<"false">>]}, #{var => <<"mute">>, type => <<"text-single">>, values => [<<"0">>]}], - Fields = lists:map(fun mongoose_data_forms:form_field/1, FieldSpecs), - FormType = mongoose_data_forms:form_type_field(?NS_ESL_INBOX_CONVERSATION), - mongoose_data_forms:form([FormType | Fields]). + mongoose_data_forms:form(#{ns => ?NS_ESL_INBOX_CONVERSATION, fields => Fields}). fetch_right_query(HostType, InboxEntryKey, only_properties) -> mod_inbox_backend:get_entry_properties(HostType, InboxEntryKey); diff --git a/src/mam/mod_mam_utils.erl b/src/mam/mod_mam_utils.erl index aedbb80418..317e528894 100644 --- a/src/mam/mod_mam_utils.erl +++ b/src/mam/mod_mam_utils.erl @@ -100,8 +100,6 @@ get_one_of_path/3, is_arcid_elem_for/3, maybe_encode_compact_uuid/2, maybe_last/1, result_query/2, send_message/4, wrap_message/7, wrapper_id/0]). --import(mongoose_data_forms, [form/1, form_type_field/1, form_field/1]). - %-define(MAM_INLINE_UTILS, true). -ifdef(MAM_INLINE_UTILS). @@ -681,19 +679,19 @@ retraction_features(Module, HostType) -> HostType :: mongooseim:host_type(), binary()) -> exml:element(). message_form(Module, HostType, MamNs) -> - Children = message_form_fields(Module, HostType, MamNs), - result_query(form(Children), MamNs). + Fields = message_form_fields(Module, HostType), + Form = mongoose_data_forms:form(#{ns => MamNs, fields => Fields}), + result_query(Form, MamNs). -message_form_fields(Mod, HostType, MamNs) -> +message_form_fields(Mod, HostType) -> TextSearch = case has_full_text_search(Mod, HostType) of - true -> [form_field(#{type => <<"text-single">>, var => <<"full-text-search">>})]; + true -> [#{type => <<"text-single">>, var => <<"full-text-search">>}]; false -> [] end, - [form_type_field(MamNs), - form_field(#{type => <<"jid-single">>, var => <<"with">>}), - form_field(#{type => <<"text-single">>, var => <<"start">>}), - form_field(#{type => <<"text-single">>, var => <<"end">>}) | TextSearch]. + [#{type => <<"jid-single">>, var => <<"with">>}, + #{type => <<"text-single">>, var => <<"start">>}, + #{type => <<"text-single">>, var => <<"end">>} | TextSearch]. -spec form_to_text(_) -> 'undefined' | binary(). form_to_text(#{<<"full-text-search">> := [Text]}) -> diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 0b11975068..14c678af91 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -1088,15 +1088,15 @@ iq_get_register_info(HostType, MucHost, From, Lang) -> ClientReqEl = #xmlel{name = <<"instructions">>, children = [#xmlcdata{content = ClientReqText}]}, EnterNicknameText = translate:translate(Lang, <<"Enter nickname you want to register">>), - EnterNicknameEl = mongoose_data_forms:form_instructions(EnterNicknameText), TitleText = <<(translate:translate(Lang, <<"Nickname Registration at ">>))/binary, MucHost/binary>>, - TitleEl = mongoose_data_forms:form_title(TitleText), - NickField = mongoose_data_forms:form_field(#{type => <<"text-single">>, - label => translate:translate(Lang, <<"Nickname">>), - var => <<"nick">>, - values => [Nick]}), - Registered ++ [ClientReqEl, mongoose_data_forms:form([TitleEl, EnterNicknameEl, NickField])]. + NickField = #{type => <<"text-single">>, + label => translate:translate(Lang, <<"Nickname">>), + var => <<"nick">>, + values => [Nick]}, + Registered ++ [ClientReqEl, mongoose_data_forms:form(#{title => TitleText, + instructions => EnterNicknameText, + fields => [NickField]})]. -spec iq_set_register_info(host_type(), jid:server(), jid:simple_jid() | jid:jid(), nick(), ejabberd:lang()) diff --git a/src/mod_muc_api.erl b/src/mod_muc_api.erl index c485648e22..ec5b334ba5 100644 --- a/src/mod_muc_api.erl +++ b/src/mod_muc_api.erl @@ -535,7 +535,7 @@ declination(Sender, Recipient) -> iq(<<"set">>, Sender, Recipient, [data_submission()]). data_submission() -> - query(?NS_MUC_OWNER, [mongoose_data_forms:form([], <<"submit">>)]). + query(?NS_MUC_OWNER, [mongoose_data_forms:form(#{type => <<"submit">>})]). address_attributes(Sender, Recipient) -> [{<<"from">>, jid:to_binary(Sender)}, diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 44f6a83b15..2e0295c8ad 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -3334,13 +3334,10 @@ get_default_room_maxusers(RoomState) -> get_config(Lang, StateData, From) -> AccessPersistent = access_persistent(StateData), Config = StateData#state.config, - TitleTxt = translate:translate(Lang, <<"Configuration of room ">>), - Res = - [mongoose_data_forms:form_title(<>), - mongoose_data_forms:form_type_field(?NS_MUC_CONFIG), - stringxfield(<<"Room title">>, + Title = <>, + Fields = + [stringxfield(<<"Room title">>, <<"muc#roomconfig_roomname">>, Config#config.title, Lang), stringxfield(<<"Room description">>, @@ -3416,20 +3413,17 @@ get_config(Lang, StateData, From) -> InstructionsTxt = translate:translate( Lang, <<"You need an x:data capable client to configure room">>), {result, [#xmlel{name = <<"instructions">>, children = [#xmlcdata{content = InstructionsTxt}]}, - mongoose_data_forms:form(Res)], + mongoose_data_forms:form(#{title => Title, ns => ?NS_MUC_CONFIG, fields => Fields})], StateData}. --spec getmemberlist_field(Lang :: ejabberd:lang()) -> exml:element(). +-spec getmemberlist_field(Lang :: ejabberd:lang()) -> mongoose_data_forms:field(). getmemberlist_field(Lang) -> LabelTxt = translate:translate( Lang, <<"Roles and affiliations that may retrieve member list">>), Values = [<<"moderator">>, <<"participant">>, <<"visitor">>], Options = [{translate:translate(Lang, Opt), Opt} || Opt <- Values], - mongoose_data_forms:form_field(#{type => <<"list-multi">>, - label => LabelTxt, - var => <<"muc#roomconfig_getmemberlist">>, - values => Values, - options => Options}). + #{type => <<"list-multi">>, label => LabelTxt, + var => <<"muc#roomconfig_getmemberlist">>, values => Values, options => Options}. maxusers_field(Lang, StateData) -> ServiceMaxUsers = get_service_max_users(StateData), @@ -3448,24 +3442,18 @@ maxusers_field(Lang, StateData) -> [integer_to_binary(N) || N <- lists:usort([ServiceMaxUsers, DefaultRoomMaxUsers, MaxUsersRoomInteger | ?MAX_USERS_DEFAULT_LIST]), N =< ServiceMaxUsers], - mongoose_data_forms:form_field(#{type => <<"list-single">>, - label => LabelTxt, - var => <<"muc#roomconfig_maxusers">>, - values => [MaxUsersRoomString], - options => Options}). + #{type => <<"list-single">>, label => LabelTxt, + var => <<"muc#roomconfig_maxusers">>, values => [MaxUsersRoomString], options => Options}. --spec whois_field(Lang :: ejabberd:lang(), Config :: config()) -> exml:element(). +-spec whois_field(Lang :: ejabberd:lang(), Config :: config()) -> mongoose_data_forms:field(). whois_field(Lang, Config) -> Value = if Config#config.anonymous -> <<"moderators">>; true -> <<"anyone">> end, Options = [{translate:translate(Lang, <<"moderators only">>), <<"moderators">>}, {translate:translate(Lang, <<"anyone">>), <<"anyone">>}], - mongoose_data_forms:form_field(#{type => <<"list-single">>, - label => translate:translate(Lang, <<"moderators only">>), - var => <<"muc#roomconfig_whois">>, - values => [Value], - options => Options}). + #{type => <<"list-single">>, label => translate:translate(Lang, <<"moderators only">>), + var => <<"muc#roomconfig_whois">>, values => [Value], options => Options}. -spec set_config([{binary(), [binary()]}], state()) -> any(). set_config(XData, StateData) -> @@ -4564,34 +4552,27 @@ decode_reason(Elem) -> -spec make_voice_approval_form(From :: jid:simple_jid() | jid:jid(), Nick :: binary(), Role :: binary()) -> exml:element(). make_voice_approval_form(From, Nick, Role) -> - FieldSpecs = - [#{var => <<"muc#role">>, type => <<"text-single">>, value => Role, - label => <<"Request role">>}, - #{var => <<"muc#jid">>, type => <<"jid-single">>, value => jid:to_binary(From), - label => <<"User ID">>}, - #{var => <<"muc#roomnick">>, type => <<"text-single">>, value => Nick, - label => <<"Room Nickname">>}, - #{var => <<"muc#request_allow">>, type => <<"boolean">>, value => <<"false">>, - label => <<"Grant voice to this person?">>}], - FormChildren = - [mongoose_data_forms:form_title(<<"Voice request">>), - mongoose_data_forms:form_instructions( - <<"To approve this request", - " for voice, select the "Grant voice to this person?" checkbox", - " and click OK. To skip this request, click the cancel button.">>), - mongoose_data_forms:form_type_field(?NS_MUC_REQUEST) | - lists:map(fun mongoose_data_forms:form_field/1, FieldSpecs)], - Form = mongoose_data_forms:form(FormChildren), + Title = <<"Voice request">>, + Instructions = <<"To approve this request" + " for voice, select the "Grant voice to this person?" checkbox" + " and click OK. To skip this request, click the cancel button.">>, + Fields = [#{var => <<"muc#role">>, type => <<"text-single">>, + label => <<"Request role">>, values => [Role]}, + #{var => <<"muc#jid">>, type => <<"jid-single">>, + label => <<"User ID">>, values => [jid:to_binary(From)]}, + #{var => <<"muc#roomnick">>, type => <<"text-single">>, + label => <<"Room Nickname">>, values => [Nick]}, + #{var => <<"muc#request_allow">>, type => <<"boolean">>, + label => <<"Grant voice to this person?">>, values => [<<"false">>]}], + Form = mongoose_data_forms:form(#{title => Title, instructions => Instructions, + ns => ?NS_MUC_REQUEST, fields => Fields}), #xmlel{name = <<"message">>, children = [Form]}. --spec xfield(binary(), any(), binary(), binary(), ejabberd:lang()) -> exml:element(). +-spec xfield(binary(), any(), binary(), binary(), ejabberd:lang()) -> mongoose_data_forms:field(). xfield(Type, Label, Var, Val, Lang) -> - mongoose_data_forms:form_field(#{type => Type, - label => translate:translate(Lang, Label), - var => Var, - values => [Val]}). + #{type => Type, label => translate:translate(Lang, Label), var => Var, values => [Val]}. --spec boolxfield(any(), binary(), any(), ejabberd:lang()) -> exml:element(). +-spec boolxfield(any(), binary(), any(), ejabberd:lang()) -> mongoose_data_forms:field(). boolxfield(Label, Var, Val, Lang) -> xfield(<<"boolean">>, Label, Var, case Val of diff --git a/src/mongoose_data_forms.erl b/src/mongoose_data_forms.erl index 1f4e91f64f..c55b38e11d 100644 --- a/src/mongoose_data_forms.erl +++ b/src/mongoose_data_forms.erl @@ -6,27 +6,23 @@ form_type/1, find_form/1, find_form/2, form_to_kvs/1, form_to_kvs/2, - form_to_map/1, form_to_map/2, - form_fields_to_kvs/1]). + form_to_map/1, form_to_map/2]). %% Form construction --export([form/1, form/2, - form_type_field/1, - form_field/1, - form_title/1, - form_instructions/1, - reported_element/1]). +-export([form/1]). -include_lib("exml/include/exml.hrl"). -include("mongoose_ns.hrl"). +-type form() :: #{type => binary(), title => binary(), instructions => binary(), ns => binary(), + fields => [field()], reported => [field()], items => [[field()]]}. -type field() :: #{var => binary(), type => binary(), label => binary(), values => [binary()], options => [option()]}. -type option() :: binary() | {binary(), binary()}. -type kv_list() :: [{binary(), [binary()]}]. -type kv_map() :: #{binary() => [binary()]}. --export_type([field/0, option/0, kv_list/0, kv_map/0]). +-export_type([form/0, field/0, option/0, kv_list/0, kv_map/0]). -ignore_xref([form_to_map/2]). % exported for consistency, might be used later @@ -88,15 +84,28 @@ form_field_to_kv(_) -> %% Form construction --spec form([exml:element()]) -> exml:element(). -form(Children) -> - form(Children, <<"form">>). - --spec form([exml:element()], binary()) -> exml:element(). -form(Children, Type) -> +-spec form(form()) -> exml:element(). +form(Spec) -> #xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, Type}], - children = Children}. + attrs = [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, maps:get(type, Spec, <<"form">>)}], + children = lists:flatmap(fun(Item) -> form_children(Item, Spec) end, + [title, instructions, ns, fields, reported]) + }. + +form_children(title, #{title := Title}) -> + [form_title(Title)]; +form_children(instructions, #{instructions := Instructions}) -> + [form_instructions(Instructions)]; +form_children(ns, #{ns := NS}) -> + [form_type_field(NS)]; +form_children(fields, #{fields := Fields}) -> + [form_field(Field) || Field <- Fields]; +form_children(reported, #{reported := ReportedFields}) -> + [reported_element([form_field(Field) || Field <- ReportedFields])]; +form_children(items, #{items := Items}) -> + [item_element([form_field(Field) || Field <- ItemFields]) || ItemFields <- Items]; +form_children(_, #{}) -> + []. -spec form_type_field(binary()) -> exml:element(). form_type_field(NS) when is_binary(NS) -> @@ -121,6 +130,10 @@ form_instructions(Instructions) -> reported_element(Fields) -> #xmlel{name = <<"reported">>, attrs = [], children = Fields}. +-spec item_element([exml:element()]) -> exml:element(). +item_element(Fields) -> + #xmlel{name = <<"item">>, attrs = [], children = Fields}. + -spec form_field_option(option()) -> exml:element(). form_field_option({Label, Value}) -> #xmlel{name = <<"option">>, diff --git a/src/mongoose_disco.erl b/src/mongoose_disco.erl index 6ea5463dea..3884873e8b 100644 --- a/src/mongoose_disco.erl +++ b/src/mongoose_disco.erl @@ -217,6 +217,4 @@ identity_to_xml(Identity) -> -spec info_to_xml(info()) -> exml:element(). info_to_xml(#{xmlns := NS, fields := Fields}) -> - Children = [mongoose_data_forms:form_type_field(NS) | - [mongoose_data_forms:form_field(Field) || Field <- Fields]], - mongoose_data_forms:form(Children, <<"result">>). + mongoose_data_forms:form(#{type => <<"result">>, ns => NS, fields => Fields}). diff --git a/src/muc_light/mod_muc_light_codec_legacy.erl b/src/muc_light/mod_muc_light_codec_legacy.erl index 40a39749ff..a0cb171acf 100644 --- a/src/muc_light/mod_muc_light_codec_legacy.erl +++ b/src/muc_light/mod_muc_light_codec_legacy.erl @@ -258,11 +258,11 @@ encode_meta({get, #disco_items{ rooms = Rooms, id = ID, rsm = RSMOut }}, || {{RoomU, RoomS}, RoomName, _RoomVersion} <- Rooms ], {iq_reply, ?NS_DISCO_ITEMS, jlib:rsm_encode(RSMOut) ++ DiscoEls, ID}; encode_meta({get, #config{} = Config}, _RoomJID, _SenderJID, _HandleFun, _Acc) -> - ConfigEls = [ mongoose_data_forms:form_field(#{var => K, type => <<"text-single">>, values => [V]}) - || {K, V} <- Config#config.raw_config ], - FormType = mongoose_data_forms:form_type_field(<<"http://jabber.org/protocol/muc#roomconfig">>), - FormTitle = mongoose_data_forms:form_title(<<"Configuration form for the room">>), - XEl = mongoose_data_forms:form([FormTitle, FormType | ConfigEls]), + Fields = [#{var => K, type => <<"text-single">>, values => [V]} + || {K, V} <- Config#config.raw_config], + XEl = mongoose_data_forms:form(#{title => <<"Configuration form for the room">>, + ns => <<"http://jabber.org/protocol/muc#roomconfig">>, + fields => Fields}), {iq_reply, ?NS_MUC_OWNER, [XEl], Config#config.id}; encode_meta({get, #affiliations{} = Affs}, _RoomJID, _SenderJID, _HandleFun, _Acc) -> AffEls = [ aff_user_to_item(AffUser) || AffUser <- Affs#affiliations.aff_users ], diff --git a/src/pubsub/mod_pubsub.erl b/src/pubsub/mod_pubsub.erl index 60109b0375..2dab6b86dd 100644 --- a/src/pubsub/mod_pubsub.erl +++ b/src/pubsub/mod_pubsub.erl @@ -1619,10 +1619,9 @@ send_pending_node_form(Request, Host, Owner, Plugins) -> {error, mongoose_xmpp_errors:feature_not_implemented()}; Ps -> Options = get_pending_nodes(Host, Owner, Ps), - Field = mongoose_data_forms:form_field(#{type => <<"list-single">>, - var => <<"pubsub#node">>, - options => lists:usort(Options)}), - Form = mongoose_data_forms:form([Field]), + Field = #{type => <<"list-single">>, var => <<"pubsub#node">>, + options => lists:usort(Options)}, + Form = mongoose_data_forms:form(#{fields => [Field]}), adhoc:produce_response(Request, executing, <<"execute">>, [Form]) end. @@ -1693,31 +1692,27 @@ get_node_subscriptions_transaction(Owner, #pubsub_node{id = Nidx, type = Type}) send_authorization_request(#pubsub_node{nodeid = {Host, Node}, owners = Owners}, Subscriber) -> Lang = <<"en">>, - FormChildren = [mongoose_data_forms:form_title( - translate:translate(Lang, <<"PubSub subscriber request">>)), - mongoose_data_forms:form_instructions( - translate:translate(Lang, <<"Choose whether to approve this entity's " - "subscription.">>)), - mongoose_data_forms:form_type_field(?NS_PUBSUB_SUB_AUTH), - mongoose_data_forms:form_field( - #{var => <<"pubsub#node">>, - type => <<"text-single">>, - label => translate:translate(Lang, <<"Node ID">>), - values => [Node]}), - mongoose_data_forms:form_field( - #{var => <<"pubsub#subscriber_jid">>, - type => <<"jid-single">>, - label => translate:translate(Lang, <<"Subscriber Address">>), - values => [jid:to_binary(Subscriber)]}), - mongoose_data_forms:form_field( - #{var => <<"pubsub#allow">>, - type => <<"boolean">>, - label => translate:translate(Lang, <<"Allow this Jabber ID to subscribe to " - "this pubsub node?">>), - values => [<<"false">>]})], + Title = translate:translate(Lang, <<"PubSub subscriber request">>), + Instructions = translate:translate(Lang, <<"Choose whether to approve this entity's " + "subscription.">>), + Fields = [#{var => <<"pubsub#node">>, + type => <<"text-single">>, + label => translate:translate(Lang, <<"Node ID">>), + values => [Node]}, + #{var => <<"pubsub#subscriber_jid">>, + type => <<"jid-single">>, + label => translate:translate(Lang, <<"Subscriber Address">>), + values => [jid:to_binary(Subscriber)]}, + #{var => <<"pubsub#allow">>, + type => <<"boolean">>, + label => translate:translate(Lang, <<"Allow this Jabber ID to subscribe to " + "this pubsub node?">>), + values => [<<"false">>]}], + Form = mongoose_data_forms:form(#{title => Title, instructions => Instructions, + ns => ?NS_PUBSUB_SUB_AUTH, fields => Fields}), Stanza = #xmlel{name = <<"message">>, attrs = [{<<"id">>, mongoose_bin:gen_from_crypto()}], - children = [mongoose_data_forms:form(FormChildren)]}, + children = [Form]}, lists:foreach(fun(Owner) -> ejabberd_router:route(service_jid(Host), jid:make(Owner), Stanza) end, Owners). @@ -3774,10 +3769,8 @@ max_items(Host, Options) -> get_option(Options, Var, []))). configure_form(Type, Options, Lang, Groups) -> - TypeField = mongoose_data_forms:form_type_field(?NS_PUBSUB_NODE_CONFIG), - Fields = [mongoose_data_forms:form_field(Spec) || - Spec <- get_configure_xfields(Options, Lang, Groups)], - mongoose_data_forms:form([TypeField | Fields], Type). + Fields = get_configure_xfields(Options, Lang, Groups), + mongoose_data_forms:form(#{type => Type, ns => ?NS_PUBSUB_NODE_CONFIG, fields => Fields}). get_configure_xfields(Options, Lang, Groups) -> [?BOOL_CONFIG_FIELD(<<"Deliver payloads with event notifications">>, diff --git a/src/pubsub/pubsub_form_utils.erl b/src/pubsub/pubsub_form_utils.erl index d324940cfa..1aa2256a44 100644 --- a/src/pubsub/pubsub_form_utils.erl +++ b/src/pubsub/pubsub_form_utils.erl @@ -13,9 +13,7 @@ -export([make_sub_xform/1, parse_sub_xform/1]). --include("mongoose_logger.hrl"). -include("mongoose_ns.hrl"). --include_lib("exml/include/exml.hrl"). -type convert_from_binary_fun() :: fun(([binary()]) -> any()). -type convert_to_binary_fun() :: fun((any()) -> [binary()]). @@ -45,7 +43,7 @@ %% TODO: Right now -spec make_sub_xform(Options :: mod_pubsub:subOptions()) -> {ok, exml:element()}. make_sub_xform(Options) -> - XFields = [make_field_xml(OptDefinition, Options) || OptDefinition <- sub_form_options()], + XFields = [make_field(OptDefinition, Options) || OptDefinition <- sub_form_options()], {ok, make_sub_xform_xml(XFields)}. %% The list of options returned by this function may be a subset of the options schema. @@ -65,16 +63,16 @@ parse_sub_xform(XForm) -> -spec make_sub_xform_xml(XFields :: [exml:element()]) -> exml:element(). make_sub_xform_xml(XFields) -> - mongoose_data_forms:form(XFields, ?NS_PUBSUB_SUB_OPTIONS). - --spec make_field_xml(OptDefinition :: option_definition(), - Options :: mod_pubsub:subOptions()) -> exml:element(). -make_field_xml({VarName, Key, #{ label := Label, form_type := FormType } = VarProps}, Options) -> - mongoose_data_forms:form_field(#{var => VarName, - type => FormType, - label => Label, - options => make_choices(VarProps), - values => make_values(Key, Options, VarProps)}). + mongoose_data_forms:form(#{ns => ?NS_PUBSUB_SUB_OPTIONS, fields => XFields}). + +-spec make_field(OptDefinition :: option_definition(), + Options :: mod_pubsub:subOptions()) -> mongoose_data_forms:field(). +make_field({VarName, Key, #{ label := Label, form_type := FormType } = VarProps}, Options) -> + #{var => VarName, + type => FormType, + label => Label, + options => make_choices(VarProps), + values => make_values(Key, Options, VarProps)}. make_choices(#{ possible_choices := PossibleChoices }) -> [ {Label, Value} || {Value, Label} <- PossibleChoices ]; diff --git a/src/vcard/mod_vcard.erl b/src/vcard/mod_vcard.erl index 77649eb03e..c3db9a16d8 100644 --- a/src/vcard/mod_vcard.erl +++ b/src/vcard/mod_vcard.erl @@ -503,7 +503,7 @@ do_route(HostType, LServer, From, To, Acc, do_route(HostType, LServer, From, To, Acc, #iq{type = get, xmlns = ?NS_SEARCH, lang = Lang} = IQ) -> Instr = search_instructions(Lang), - Form = search_res_form(To, mod_vcard_backend:search_fields(HostType, LServer), Lang), + Form = search_form(To, mod_vcard_backend:search_fields(HostType, LServer), Lang), ResIQ = make_search_form_result_iq(IQ, [Instr, Form]), ejabberd_router:route(To, From, Acc, jlib:iq_to_xml(ResIQ)); do_route(_HostType, _LServer, From, To, Acc, @@ -551,19 +551,15 @@ make_search_form_result_iq(IQ, Elements) -> }]}. search_instructions(Lang) -> - %% This is not in the form, but the helper function can be reused - mongoose_data_forms:form_instructions( - translate:translate(Lang, <<"You need an x:data capable client to search">>)). - -search_res_form(JID, SearchFields, Lang) -> - Contents = - [mongoose_data_forms:form_title( - <<(translate:translate(Lang, <<"Search users in ">>))/binary, - (jid:to_binary(JID))/binary>>), - mongoose_data_forms:form_instructions( - translate:translate(Lang, <<"Fill in fields to search for any matching Jabber User">>)) - ] ++ lists:map(fun ({X, Y}) -> ?TLFIELD(<<"text-single">>, X, Y) end, SearchFields), - mongoose_data_forms:form(Contents, <<"result">>). + Text = translate:translate(Lang, <<"You need an x:data capable client to search">>), + #xmlel{name = <<"instructions">>, attrs = [], children = [#xmlcdata{content = Text}]}. + +search_form(JID, SearchFields, Lang) -> + Title = <<(translate:translate(Lang, <<"Search users in ">>))/binary, + (jid:to_binary(JID))/binary>>, + Instructions = <<"Fill in fields to search for any matching Jabber User">>, + Fields = lists:map(fun ({X, Y}) -> ?TLFIELD(<<"text-single">>, X, Y) end, SearchFields), + mongoose_data_forms:form(#{title => Title, instructions => Instructions, fields => Fields}). route_search_iq_set(HostType, LServer, From, To, Acc, Lang, SubEl, IQ) -> XDataEl = mongoose_data_forms:find_form(SubEl), @@ -585,7 +581,7 @@ route_search_iq_set(HostType, LServer, From, To, Acc, Lang, SubEl, IQ) -> end. make_search_result_iq(IQ, SearchResult, RSMOutEls) -> - Form = mongoose_data_forms:form(SearchResult, <<"result">>), + Form = mongoose_data_forms:form(SearchResult), IQ#iq{ type = result, sub_el = [#xmlel{name = <<"query">>, @@ -610,27 +606,25 @@ identity(Lang) -> name => translate:translate(Lang, <<"vCard User Search">>)}. search_result(HostType, LServer, Lang, JID, Data, RSMIn) -> - Text = translate:translate(Lang, <<"Search Results for ">>), - TitleEl = #xmlel{name = <<"title">>, - children = [#xmlcdata{content = [Text, jid:to_binary(JID)]}]}, + Title = translate:translate(Lang, <<"Search Results for ", (jid:to_binary(JID))/binary>>), ReportedFields = mod_vcard_backend:search_reported_fields(HostType, LServer, Lang), Results1 = mod_vcard_backend:search(HostType, LServer, Data), Results2 = lists:filtermap( fun(Result) -> case search_result_get_jid(Result) of - {ok, ResultJID} -> + [ResultJID] -> {true, {ResultJID, Result}}; - undefined -> + [] -> false end end, Results1), %% mnesia does not guarantee sorting order Results3 = lists:sort(Results2), - {Results4, RSMOutEls} = - apply_rsm_to_search_results(Results3, RSMIn, none), + {Results4, RSMOutEls} = apply_rsm_to_search_results(Results3, RSMIn, none), Results5 = [Result || {_, Result} <- Results4], - {[TitleEl, ReportedFields | Results5], RSMOutEls}. + Form = #{type => <<"result">>, title => Title, reported => ReportedFields, items => Results5}, + {Form, RSMOutEls}. %% No RSM input, create empty apply_rsm_to_search_results(Results, none, RSMOut) -> @@ -719,15 +713,8 @@ apply_rsm_to_search_results([], _, #rsm_out{} = RSMOut1) -> RSMOut2 = RSMOut1#rsm_out{index = undefined}, {[], jlib:rsm_encode(RSMOut2)}. -search_result_get_jid(#xmlel{name = <<"item">>, - children = Children}) -> - Fields = mongoose_data_forms:form_fields_to_kvs(Children), - case lists:keysearch(<<"jid">>, 1, Fields) of - {value, {<<"jid">>, JID}} -> - {ok, list_to_binary(JID)}; - false -> - undefined - end. +search_result_get_jid(Fields) -> + [list_to_binary(JID) || #{var := <<"jid">>, value := JID} <- Fields]. parse_vcard(LUser, VHost, VCARD) -> FN = xml:get_path_s(VCARD, [{elem, <<"FN">>}, cdata]), @@ -803,23 +790,22 @@ prepare_index_allow_emoji(FieldName, Value) -> prepare_index(FieldName, Sanitized). --spec get_default_reported_fields(binary()) -> exml:element(). +-spec get_default_reported_fields(binary()) -> [mongoose_data_forms:field()]. get_default_reported_fields(Lang) -> - #xmlel{name = <<"reported">>, - children = [ - ?TLFIELD(<<"jid-single">>, <<"Jabber ID">>, <<"jid">>), - ?TLFIELD(<<"text-single">>, <<"Full Name">>, <<"fn">>), - ?TLFIELD(<<"text-single">>, <<"Name">>, <<"first">>), - ?TLFIELD(<<"text-single">>, <<"Middle Name">>, <<"middle">>), - ?TLFIELD(<<"text-single">>, <<"Family Name">>, <<"last">>), - ?TLFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>), - ?TLFIELD(<<"text-single">>, <<"Birthday">>, <<"bday">>), - ?TLFIELD(<<"text-single">>, <<"Country">>, <<"ctry">>), - ?TLFIELD(<<"text-single">>, <<"City">>, <<"locality">>), - ?TLFIELD(<<"text-single">>, <<"Email">>, <<"email">>), - ?TLFIELD(<<"text-single">>, <<"Organization Name">>, <<"orgname">>), - ?TLFIELD(<<"text-single">>, <<"Organization Unit">>, <<"orgunit">>) - ]}. + [ + ?TLFIELD(<<"jid-single">>, <<"Jabber ID">>, <<"jid">>), + ?TLFIELD(<<"text-single">>, <<"Full Name">>, <<"fn">>), + ?TLFIELD(<<"text-single">>, <<"Name">>, <<"first">>), + ?TLFIELD(<<"text-single">>, <<"Middle Name">>, <<"middle">>), + ?TLFIELD(<<"text-single">>, <<"Family Name">>, <<"last">>), + ?TLFIELD(<<"text-single">>, <<"Nickname">>, <<"nick">>), + ?TLFIELD(<<"text-single">>, <<"Birthday">>, <<"bday">>), + ?TLFIELD(<<"text-single">>, <<"Country">>, <<"ctry">>), + ?TLFIELD(<<"text-single">>, <<"City">>, <<"locality">>), + ?TLFIELD(<<"text-single">>, <<"Email">>, <<"email">>), + ?TLFIELD(<<"text-single">>, <<"Organization Name">>, <<"orgname">>), + ?TLFIELD(<<"text-single">>, <<"Organization Unit">>, <<"orgunit">>) + ]. config_metrics(Host) -> mongoose_module_metrics:opts_for_module(Host, ?MODULE, [backend]). diff --git a/src/vcard/mod_vcard_backend.erl b/src/vcard/mod_vcard_backend.erl index 647a8e6560..ef8d2ca7a8 100644 --- a/src/vcard/mod_vcard_backend.erl +++ b/src/vcard/mod_vcard_backend.erl @@ -95,7 +95,7 @@ get_vcard(HostType, LUser, LServer) -> mongoose_backend:call_tracked(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args). -spec search(mongooseim:host_type(), jid:lserver(), Data) -> - Res :: term() when + Res :: [[mongoose_data_forms:field()]] when Data :: term(). search(HostType, LServer, Data) -> Args = [HostType, LServer, Data], @@ -107,7 +107,7 @@ search_fields(HostType, LServer) -> mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args). -spec search_reported_fields(mongooseim:host_type(), jid:lserver(), Lang) -> - Res :: term() when + Res :: [mongoose_data_forms:field()] when Lang :: binary(). search_reported_fields(HostType, LServer, Lang) -> Args = [HostType, LServer, Lang], diff --git a/src/vcard/mod_vcard_ldap.erl b/src/vcard/mod_vcard_ldap.erl index fcd5130249..41cc5e9faa 100644 --- a/src/vcard/mod_vcard_ldap.erl +++ b/src/vcard/mod_vcard_ldap.erl @@ -156,7 +156,8 @@ get_vcard(HostType, LUser, LServer) -> set_vcard(_HostType, _User, _LServer, _VCard, _VCardSearch) -> {error, mongoose_xmpp_errors:not_allowed()}. --spec search(mongooseim:host_type(), jid:lserver(), [{binary(), [binary()]}]) -> [eldap_utils:eldap_entry()]. +-spec search(mongooseim:host_type(), jid:lserver(), [{binary(), [binary()]}]) -> + [[mongoose_data_forms:field()]]. search(HostType, LServer, Data) -> State = get_state(HostType, LServer), search_internal(State, Data). @@ -166,13 +167,13 @@ search_fields(HostType, LServer) -> State = get_state(HostType, LServer), State#state.search_fields. --spec search_reported_fields(mongooseim:host_type(), jid:lserver(), binary()) -> exml:element(). +-spec search_reported_fields(mongooseim:host_type(), jid:lserver(), binary()) -> + [mongoose_data_forms:field()]. search_reported_fields(HostType, LServer, Lang) -> State = get_state(HostType, LServer), SearchReported = State#state.search_reported, - Fields = [?TLFIELD(<<"text-single">>, Name, Value) || - {Name, Value} <- [{<<"Jabber ID">>, <<"jid">>} | SearchReported]], - mongoose_data_forms:reported_element(Fields). + [?TLFIELD(<<"text-single">>, Name, Value) || + {Name, Value} <- [{<<"Jabber ID">>, <<"jid">>} | SearchReported]]. %%-------------------------------------------------------------------- %% API @@ -355,10 +356,10 @@ limited_results(E, _) -> E. search_items(Entries, State) -> - lists:flatmap(fun(#eldap_entry{attributes = Attrs}) -> attrs_to_item_xml(Attrs, State) end, + lists:flatmap(fun(#eldap_entry{attributes = Attrs}) -> attrs_to_item(Attrs, State) end, Entries). -attrs_to_item_xml(Attrs, #state{uids = UIDs} = State) -> +attrs_to_item(Attrs, #state{uids = UIDs} = State) -> case eldap_utils:find_ldap_attrs(UIDs, Attrs) of {U, UIDAttrFormat} -> case eldap_utils:get_user_part(U, UIDAttrFormat) of @@ -380,9 +381,9 @@ make_user_item_if_exists(Username, Attrs, {Username, LServer})} end, SearchReported), - Result = [?FIELD(<<"jid">>, <>)] ++ - [?FIELD(Name, search_item_value(Name, Value, BinFields)) || {Name, Value} <- RFields], - [#xmlel{name = <<"item">>, attrs = [], children = Result}]; + [[?FIELD(<<"jid">>, <>)] ++ + [?FIELD(Name, search_item_value(Name, Value, BinFields)) || + {Name, Value} <- RFields]]; _ -> [] end. diff --git a/src/vcard/mod_vcard_mnesia.erl b/src/vcard/mod_vcard_mnesia.erl index a1338045de..1c40c49da4 100644 --- a/src/vcard/mod_vcard_mnesia.erl +++ b/src/vcard/mod_vcard_mnesia.erl @@ -57,6 +57,7 @@ set_vcard(HostType, User, LServer, VCard, VCardSearch) -> mongoose_hooks:vcard_set(HostType, LServer, LUser, VCard), ok. +-spec search(mongooseim:host_type(), jid:lserver(), term()) -> [[mongoose_data_forms:field()]]. search(HostType, LServer, Data) -> MatchHead = make_matchhead(LServer, Data), R = do_search(HostType, LServer, MatchHead), @@ -84,6 +85,8 @@ do_search(HostType, LServer, MatchHeadIn) -> search_fields(_HostType, _LServer) -> mod_vcard:default_search_fields(). +-spec search_reported_fields(mongooseim:host_type(), jid:lserver(), ejabberd:lang()) -> + [mongoose_data_forms:field()]. search_reported_fields(_HostType, _LServer, Lang) -> mod_vcard:get_default_reported_fields(Lang). @@ -181,18 +184,17 @@ make_val(ValBin) -> record_to_item(R) -> {User, Server} = R#vcard_search.user, - #xmlel{name = <<"item">>, - children = [ - ?FIELD(<<"jid">>, <>), - ?FIELD(<<"fn">>, (R#vcard_search.fn)), - ?FIELD(<<"last">>, (R#vcard_search.family)), - ?FIELD(<<"first">>, (R#vcard_search.given)), - ?FIELD(<<"middle">>, (R#vcard_search.middle)), - ?FIELD(<<"nick">>, (R#vcard_search.nickname)), - ?FIELD(<<"bday">>, (R#vcard_search.bday)), - ?FIELD(<<"ctry">>, (R#vcard_search.ctry)), - ?FIELD(<<"locality">>, (R#vcard_search.locality)), - ?FIELD(<<"email">>, (R#vcard_search.email)), - ?FIELD(<<"orgname">>, (R#vcard_search.orgname)), - ?FIELD(<<"orgunit">>, (R#vcard_search.orgunit)) - ]}. + [ + ?FIELD(<<"jid">>, <>), + ?FIELD(<<"fn">>, (R#vcard_search.fn)), + ?FIELD(<<"last">>, (R#vcard_search.family)), + ?FIELD(<<"first">>, (R#vcard_search.given)), + ?FIELD(<<"middle">>, (R#vcard_search.middle)), + ?FIELD(<<"nick">>, (R#vcard_search.nickname)), + ?FIELD(<<"bday">>, (R#vcard_search.bday)), + ?FIELD(<<"ctry">>, (R#vcard_search.ctry)), + ?FIELD(<<"locality">>, (R#vcard_search.locality)), + ?FIELD(<<"email">>, (R#vcard_search.email)), + ?FIELD(<<"orgname">>, (R#vcard_search.orgname)), + ?FIELD(<<"orgunit">>, (R#vcard_search.orgunit)) + ]. diff --git a/src/vcard/mod_vcard_rdbms.erl b/src/vcard/mod_vcard_rdbms.erl index ddd56b23b2..033d22913c 100644 --- a/src/vcard/mod_vcard_rdbms.erl +++ b/src/vcard/mod_vcard_rdbms.erl @@ -163,10 +163,13 @@ search_fields(_HostType, _VHost) -> mod_vcard:default_search_fields(). %% Search vCards reported fields callback +-spec search_reported_fields(mongooseim:host_type(), jid:lserver(), ejabberd:lang()) -> + [mongoose_data_forms:field()]. search_reported_fields(_HostType, _VHost, Lang) -> mod_vcard:get_default_reported_fields(Lang). %% Search vCards callback +-spec search(mongooseim:host_type(), jid:lserver(), term()) -> [[mongoose_data_forms:field()]]. search(HostType, LServer, Data) -> Filters = make_filters(LServer, Data), case Filters of @@ -379,18 +382,17 @@ record_to_items(Records) -> record_to_item({Username, VCardVHost, FN, Family, Given, Middle, Nickname, BDay, CTRY, Locality, EMail, OrgName, OrgUnit}) -> - #xmlel{name = <<"item">>, - children = [ - ?FIELD(<<"jid">>, <>), - ?FIELD(<<"fn">>, FN), - ?FIELD(<<"last">>, Family), - ?FIELD(<<"first">>, Given), - ?FIELD(<<"middle">>, Middle), - ?FIELD(<<"nick">>, Nickname), - ?FIELD(<<"bday">>, BDay), - ?FIELD(<<"ctry">>, CTRY), - ?FIELD(<<"locality">>, Locality), - ?FIELD(<<"email">>, EMail), - ?FIELD(<<"orgname">>, OrgName), - ?FIELD(<<"orgunit">>, OrgUnit) - ]}. + [ + ?FIELD(<<"jid">>, <>), + ?FIELD(<<"fn">>, FN), + ?FIELD(<<"last">>, Family), + ?FIELD(<<"first">>, Given), + ?FIELD(<<"middle">>, Middle), + ?FIELD(<<"nick">>, Nickname), + ?FIELD(<<"bday">>, BDay), + ?FIELD(<<"ctry">>, CTRY), + ?FIELD(<<"locality">>, Locality), + ?FIELD(<<"email">>, EMail), + ?FIELD(<<"orgname">>, OrgName), + ?FIELD(<<"orgunit">>, OrgUnit) + ]. diff --git a/src/vcard/mod_vcard_riak.erl b/src/vcard/mod_vcard_riak.erl index 38648f57d3..0f7568837b 100644 --- a/src/vcard/mod_vcard_riak.erl +++ b/src/vcard/mod_vcard_riak.erl @@ -62,6 +62,7 @@ get_vcard(HostType, LUser, LServer) -> Other end. +-spec search(mongooseim:host_type(), jid:lserver(), term()) -> [[mongoose_data_forms:field()]]. search(HostType, LServer, Data) -> YZQuery = make_yz_query(Data, []), do_search(YZQuery, HostType, LServer). @@ -85,6 +86,8 @@ do_search(YZQueryIn, HostType, LServer) -> search_fields(_HostType, _LServer) -> mod_vcard:default_search_fields(). +-spec search_reported_fields(mongooseim:host_type(), jid:lserver(), ejabberd:lang()) -> + [mongoose_data_forms:field()]. search_reported_fields(_HostType, _LServer, Lang) -> mod_vcard:get_default_reported_fields(Lang). @@ -116,9 +119,7 @@ make_val(Val) -> end. doc2item(HostType, LServer, Props) -> - Vals = lists:map(pa:bind(fun extract_field/2, Props), search_fields(HostType, LServer)), - #xmlel{name = <<"item">>, - children = Vals}. + lists:map(pa:bind(fun extract_field/2, Props), search_fields(HostType, LServer)). extract_field(Props, {_, <<"user">>}) -> {_, Username} = lists:keyfind(riak_search_mapping(<<"user">>), 1, Props),