]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Trigger.pm
start of the event firing code -- build the environment for validators, reactors...
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Trigger.pm
1 package OpenILS::Application::Trigger;
2 use OpenILS::Application;
3 use base qw/OpenILS::Application/;
4
5 use OpenSRF::EX qw/:try/;
6
7 use OpenSRF::AppSession;
8 use OpenSRF::Utils::SettingsClient;
9 use OpenSRF::Utils::Logger qw/:level/;
10
11 use OpenILS::Utils::Fieldmapper;
12 use OpenILS::Utils::CStoreEditor q/:funcs/;
13 use OpenILS::Application::Trigger::ModRunner;
14
15
16 my $log = 'OpenSRF::Utils::Logger';
17
18 sub initialize {}
19 sub child_init {}
20
21 sub build_env {
22     my $event = shift;
23     my $environment = shift || {};
24     my $cstore = new_editor();
25
26     my $def = $cstore->retrieve_action_trigger_event_definition( $event->event_def );
27     my $hook = $cstore->retrieve_action_trigger_hook( $def->hook );
28     my $class = _fm_class_by_hint( $hook->core_type );
29
30     my $meth = "retreive_" . $class;
31     $meth =~ s/Fieldmapper:://;
32     $meth =~ s/::/_/;
33
34     my $target = $cstore->$meth( $event->target );
35     $$environment{target} = $target;
36     $$environment{event} = $event->to_bare_hash;
37
38     my @env_list = $cstore->search_action_trigger_environment( { event_def => $event->event_def } );
39     my @param_list = $cstore->search_action_trigger_params( { event_def => $event->event_def } );
40
41     $$environment{params}{ $_->param } = eval $_->value for ( @param_list );
42
43     for my $e ( @env_list ) {
44         my (@label, @path);
45         @path = split('.', $e->path) if ($e->path);
46         @label = split('.', $e->label) if ($e->label);
47
48         my $collector = $e->collector;
49         _object_by_path( $cstore, $target, $collector, \@label, $environment, @path );
50     }
51
52     return $environment;
53 }
54
55 sub _fm_class_by_hint {
56     my $hint = shift;
57
58     my ($class) = grep {
59         OpenILS::Utils::Fieldmapper->publish_fieldmapper->{$_}->{hint} eq $hint
60     } keys %{ OpenILS::Utils::Fieldmapper->publish_fieldmapper };
61
62     return $class;
63 }
64
65 sub _object_by_path {
66     my $cstore = shift;
67     my $context = shift;
68     my $collector = shift;
69     my $label = shift;
70     my $env = shift;
71     my @path = @_;
72
73     my $step = shift(@path);
74     
75     my $fhint = OpenILS::Utils::Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{class};
76     my $fclass = _fm_class_by_hint( $fhint );
77
78     my $ffield = OpenILS::Utils::Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{key};
79     my $rtype = OpenILS::Utils::Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{reltype};
80
81     my $meth = 'retrieve_';
82     my $multi = 0;
83     my $lfield = $step;
84     if ($rtype eq 'has_many') {
85         $meth = 'search_';
86         $multi = 1;
87         $lfield = $context->Identity;
88     }
89
90     $meth .= $fclass;
91     $meth =~ s/Fieldmapper:://;
92     $meth =~ s/::/_/;
93
94     my $obj = $cstore->$meth( { $ffield => $context->$lfield() } );
95
96     if (@path) {
97
98         my $obj_list = [];
99         if (!$multi) {
100             $obj_list = [$obj] if ($obj);
101         } else {
102             $obj_list = $obj;
103         }
104
105         _object_by_path( $cstore, $_, $collector, $label, $env, @path ) for (@$obj_list);
106
107         $obj = $$obj_list[0] if (!$multi);
108         $context->$step( $obj ) if ($obj && !$label);
109
110     } else {
111
112         if ($collector) {
113             my $obj_list = [$obj] if ($obj && !$multi);
114             $obj_list = $obj if ($multi);
115
116             my @new_obj_list;
117             for my $o ( @$obj_list ) {
118                 push @new_obj_list,
119                     OpenILS::Application::Trigger::ModRunner
120                         ->new( $collector, $o )
121                         ->run
122                         ->final_result;
123             }
124
125             if (!$multi) {
126                 $obj = $new_obj_list[0];
127             } else {
128                 $obj = \@new_obj_list;
129             }
130         }
131
132         if ($label) {
133             my $node = $env;
134             my $i = 0; my $max = scalar(@$label) - 1;
135             for (; $i < $max; $i++) {
136                 my $part = $$label[$i];
137                 $$node{$part} ||= {};
138                 $node = $$node{$part};
139             }
140             $$node{$$label[-1]} = $obj;
141         } else {
142             $context->$step( $obj ) if ($obj);
143         }
144     }
145
146     return $obj;
147 }
148
149 1;