--- /dev/null
+package OpenILS::Application::Actor::Settings;
+use strict; use warnings;
+use base 'OpenILS::Application';
+use OpenSRF::AppSession;
+use OpenSRF::Utils::Logger q/$logger/;
+use OpenILS::Application::AppUtils;
+use OpenILS::Utils::CStoreEditor q/:funcs/;
+use OpenILS::Utils::Fieldmapper;
+use OpenSRF::Utils::JSON;
+use OpenILS::Event;
+my $U = "OpenILS::Application::AppUtils";
+
+
+__PACKAGE__->register_method (
+ method => 'retrieve_settings',
+ api_name => 'open-ils.actor.settings.retrieve',
+ stream => 1,
+ signature => {
+ desc => q/
+ Returns org unit, user, and workstation setting values
+ for the requested setting types.
+
+ The API makes a best effort to find the correct setting
+ value based on the available context data.
+
+ If no auth token is provided, only publicly visible org
+ unit settings may be returned.
+
+ If no workstation is linked to the provided auth token, only
+ user settings and perm-visible org unit settings may be
+ returned.
+
+ If no org unit is provided, but a workstation is linked to the
+ auth token, the owning lib of the workstation is used as the
+ context org unit.
+ /,
+ params => [
+ {desc => 'settings. List of setting names', type => 'array'},
+ {desc => 'authtoken. Optional', type => 'string'},
+ {desc => 'org_id. Optional', type => 'number'}
+ ],
+ return => {
+ desc => q/
+ Stream of setting name=>value pairs in the same order
+ as the provided list of setting names. No key-value
+ pair is returned for settings that have no value defined./,
+ type => 'string'
+ }
+ }
+);
+
+sub retrieve_settings {
+ my ($self, $client, $settings, $auth, $org_id) = @_;
+
+ my ($aou_id, $user_id, $ws_id, $evt) = get_context($auth, $org_id);
+ return $evt if $evt; # bogus auth token
+
+ return OpenILS::Event->new('BAD_PARAMS',
+ desc => 'Cannot retrieve settings without a user or org unit')
+ unless ($user_id || $aou_id);
+
+ # Setting names may only contains letters, numbers, unders, and dots.
+ s/[^a-zA-Z0-9_\.]//g foreach @$settings;
+
+ # Encode as a db-friendly array.
+ my $settings_str = '{' . join(',', @$settings) . '}';
+
+ # Some settings could be bulky, so fetch them as a stream from
+ # cstore, relaying values back to the caller as they arrive.
+ my $ses = OpenSRF::AppSession->create('open-ils.cstore');
+ my $req = $ses->request('open-ils.cstore.json_query', {
+ from => [
+ 'actor.get_setting_batch',
+ $settings_str, $aou_id, $user_id, $ws_id
+ ]
+ });
+
+ # The DB responds in setting-name order.
+ while (my $resp = $req->recv) {
+ my $json = $resp->content->{'actor.get_setting_batch'};
+ $client->respond(
+ {$settings->[0] => OpenSRF::Utils::JSON->JSON2perl($json)})
+ if defined $json;
+ shift @$settings;
+ }
+
+ $ses->kill_me;
+
+ return undef;
+}
+
+# Returns ($org_id, $user_id, $ws_id, $evt);
+# Any value may be undef.
+sub get_context {
+ my ($auth, $org_id) = @_;
+
+ return ($org_id) unless $auth;
+
+ my $e = new_editor(authtoken => $auth);
+ return (undef, undef, undef, $e->event) unless $e->checkauth;
+
+ my $user_id = $e->requestor->id;
+ my $ws_id = $e->requestor->wsid;
+
+ # default to the workstation org if needed.
+ $org_id = $e->requestor->ws_ou if $ws_id && !$org_id;
+
+ return ($org_id, $user_id, $ws_id);
+}
+
+1;