blob: af1833bf963b5abc9a996b152cace14a98341c58 [file] [log] [blame]
Nils Diewald5d1ffb42014-05-21 17:45:34 +00001package Korap::Plugin::Notifications;
2use Mojo::Base 'Mojolicious::Plugin';
3use Mojo::Util qw/camelize/;
4
5our $TYPE_RE = qr/^[-a-zA-Z_]+$/;
6
Nils Diewald64bab252014-05-22 11:04:04 +00007# This will be separated published as Mojolicious::Plugin::Notifications
8# (wasn't exclusively developed for KorAP)
9
Nils Diewald5d1ffb42014-05-21 17:45:34 +000010# Todo: Support multiple notification center,
11# so the notifications can be part of
12# json as well as XML
13# Possibly use 'n!.a' for flash as this will be in the cookie!
14
15sub register {
16 my ($plugin, $mojo, $param) = @_;
17
18 $param ||= {};
19
20 # Load parameter from Config file
21 if (my $config_param = $mojo->config('Notifications')) {
22 $param = { %$config_param, %$param };
23 };
24
25 my $debug = $mojo->mode eq 'development' ? 1 : 0;
26
Nils Diewald64bab252014-05-22 11:04:04 +000027 my $center = camelize(
28 delete $param->{use} // __PACKAGE__ . '::HTML'
29 );
Nils Diewald5d1ffb42014-05-21 17:45:34 +000030
31 if (index($center,'::') < 0) {
32 $center = __PACKAGE__ . '::' . $center;
33 };
34
35 my $center_plugin = $mojo->plugins->load_plugin($center);
36 $center_plugin->register($mojo, $param);
37
38 # Add notifications
39 $mojo->helper(
40 notify => sub {
41 my $c = shift;
42 my $type = shift;
43
44 return if $type !~ $TYPE_RE || (!$debug && $type eq 'debug');
45
46 my $array;
47
48 # New notifications
49 if ($array = $c->stash('notify.array')) {
50 push @$array, [$type => @_];
51 }
52
53 # Notifications already set
54 else {
55 $c->stash->{'notify.array'} = [[$type => @_]];
56 };
57 }
58 );
59
60 # Make notifications flash in case of a redirect
61 $mojo->hook(
62 after_dispatch => sub {
63 my ($c) = @_;
64 if ($c->stash('notify.array') && $c->res->is_status_class(300)) {
65 $c->flash('notify.array' => delete $c->stash->{'notify.array'});
66 };
67 }
68 );
69
70 # Embed notification display
71 $mojo->helper(
72 notifications => sub {
73 my $c = shift;
74
75 my @notify_array;
76
77 # Get flash notifications
78 my $flash = $c->flash('notify.array');
79 if ($flash && ref $flash eq 'ARRAY') {
80
81 # Ensure that no harmful types are injected
82 push @notify_array, grep { $_->[0] =~ $TYPE_RE } @$flash;
83
84 $c->flash('notify.array' => undef);
85 };
86
87 # Get stash notifications
88 if ($c->stash('notify.array')) {
89 push @notify_array, @{ delete $c->stash->{'notify.array'} };
90 };
91
92 # Nothing to do
93 return '' unless @notify_array or @_;
94
95 # Forward messages to notification center
96 $center_plugin->notifications($c, \@notify_array, @_);
97 }
98 );
99};
100
101
1021;
103
104
105__END__
106
107=head2 notify
108
109 $c->notify(error => 'Something went wrong');
110 $c->notify(error => { timeout => 4000 } => 'Something went wrong');
111
112=head2 notifications
113
114 %= include_notification_center
115 %= include_notification_center qw/warn error success/
116
117The notification won't be included in case no notifications are
118in the queue and no parameters are passed.