File Coverage

lib/Mojolicious/Plugin/Fondation/Helpers.pm
Criterion Covered Total %
statement 73 77 94.8
branch 9 10 90.0
condition 2 2 100.0
subroutine 15 16 93.7
pod 0 1 0.0
total 99 106 93.4


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Fondation::Helpers;
2             # ABSTRACT: All Fondation helpers in one place -- keeps Fondation.pm minimal
3             $Mojolicious::Plugin::Fondation::Helpers::VERSION = '0.02';
4 13     13   70 use Mojo::Base -base, -signatures;
  13         22  
  13         82  
5 13     13   3030 use Mojo::ByteStream 'b';
  13         20  
  13         11209  
6              
7 68     68 0 105 sub register ($class, $app, $manager) {
  68         105  
  68         136  
  68         92  
  68         87  
8              
9             # ═══════════════════════════════════════════════════════════════════════
10             # ── Core identity ──
11             # ═══════════════════════════════════════════════════════════════════════
12 68     76   451 $app->helper(manager => sub { $manager });
  76         7681  
13              
14             # Stable public API (recommended over direct manager access)
15 68     1   3755 $app->helper(fondation => sub { $manager->api });
  1         120  
16              
17             # ═══════════════════════════════════════════════════════════════════════
18             # ── Fallback helpers -- overridden by specialized plugins ──
19             # Must be registered BEFORE load_plugin_recursive so plugins can override.
20             # ═══════════════════════════════════════════════════════════════════════
21              
22             # Overridden by I18N-like plugins
23 68     1   2606 $app->helper(l => sub { $_[1] });
  1         94  
24              
25             # Fallback i18n_js -- injected by layout before app JS.
26             # Identity function when I18N absent; overridden by I18N-like plugins.
27 0     0   0 $app->helper(i18n_js => sub ($c) {
  0         0  
  0         0  
28 0         0 return Mojo::ByteStream->new(
29             q{}
30             );
31 68         2613 });
32              
33             # Overridden by a Notification plugin
34 68     1   2670 $app->helper(notify_user => sub { Mojo::Promise->resolve() });
  1         20  
35              
36             # Overridden by a Authorization plugin -- permissive fallback (allow all)
37 68     3   2473 $app->helper(check_group => sub { 1 });
  3         47  
38 68     4   2383 $app->helper(check_perm => sub { 1 });
  4         74  
39              
40             # ═══════════════════════════════════════════════════════════════════════
41             # ── Route conditions ──
42             # ── check_perm/check_group are no-ops above until Authorization plugin
43             # ── overrides them.
44             # ═══════════════════════════════════════════════════════════════════════
45              
46             $app->routes->add_condition('fondation.perm' => sub {
47 5     5   64578 my ($route, $c, $captures, $perm) = @_;
48 5 100       29 return 1 if $c->check_perm($perm);
49 2         45 $c->render(text => 'Forbidden', status => 403);
50 2         966 return undef;
51 68         2316 });
52              
53             $app->routes->add_condition('fondation.group' => sub {
54 4     4   24261 my ($route, $c, $captures, $group) = @_;
55 4 100       30 return 1 if $c->check_group($group);
56 2         39 $c->render(text => 'Forbidden', status => 403);
57 2         1035 return undef;
58 68         1191 });
59              
60              
61             # ═══════════════════════════════════════════════════════════════════════
62             # ── Real helpers (not no-ops) ──
63             # ═══════════════════════════════════════════════════════════════════════
64              
65             # Check whether a helper exists (Mojo helpers are not visible via $c->can).
66 5     5   1960 $app->helper(has_helper => sub ($c, $name) {
  5         9  
  5         6  
  5         6  
67 5         13 return exists $c->app->renderer->helpers->{$name};
68 68         993 });
69              
70              
71             # ═══════════════════════════════════════════════════════════════════════
72             # ── Zone system ──
73             # ═══════════════════════════════════════════════════════════════════════
74              
75 6     6   33 $app->helper(render_zone_type => sub ($c, $type, $zone) {
  6         9  
  6         8  
  6         10  
  6         7  
76 6         21 my $manager = $c->app->manager;
77 6         19 my $output = '';
78              
79 6         11 for my $long (@{$manager->load_order}) {
  6         14  
80 14         9113 my $entry = $manager->registry->{$long};
81 14 50       55 next unless $entry;
82              
83 14   100     47 my $files = $entry->{zones}{$type}{$zone} // [];
84 14 100       38 next unless @$files;
85              
86 4 100       10 if ($type eq 'html') {
87 3         5 for my $template (@$files) {
88 3         11 $output .= $c->render_to_string(
89             template => $template,
90             layout => undef,
91             );
92             }
93             }
94             else {
95 1         3 for my $content (@$files) {
96 1         3 $output .= $content;
97             }
98             }
99             }
100              
101 6         7185 return $output;
102 68         3041 });
103              
104 4     4   416 $app->helper(render_zone => sub ($c, $zone) {
  4         7  
  4         6  
  4         5  
105 4         25 return $c->render_zone_type('html', $zone);
106 68         2548 });
107              
108 2     2   199 $app->helper(render_zone_js => sub ($c, $zone) {
  2         4  
  2         3  
  2         3  
109 2         7 return $c->render_zone_type('js', $zone);
110 68         2417 });
111              
112 68         2331 return;
113             }
114              
115             1;
116              
117             __END__