File Coverage

blib/lib/Ado.pm
Criterion Covered Total %
statement 81 81 100.0
branch 25 26 96.1
condition 10 12 83.3
subroutine 16 16 100.0
pod 6 6 100.0
total 138 141 97.8


line stmt bran cond sub pod time code
1             package Ado;
2 24     24   642715 use Mojo::Base -strict;
  24         8909  
  24         213  
3              
4 24     24   3865 use Mojo::Base 'Mojolicious';
  24         83  
  24         95  
5 24     24   2232052 use File::Spec::Functions qw(splitdir catdir catfile);
  24         76  
  24         1827  
6 24     24   134 use Mojo::Util 'class_to_path';
  24         40  
  24         1091  
7 24     24   113 use List::Util 'first';
  24         37  
  24         2287  
8              
9             our $AUTHORITY = 'cpan:BEROV';
10             our $VERSION = '0.933';
11             our $CODENAME = 'U+2C0A GLAGOLITIC CAPITAL LETTER INITIAL IZHE (Ⰺ)';
12              
13 24     24   12715 use Ado::Control;
  24         50  
  24         236  
14 24     24   10769 use Ado::Sessions;
  24         58  
  24         195  
15             my $CLASS = __PACKAGE__;
16              
17             has ado_home => sub {
18             my @home = splitdir $INC{class_to_path $CLASS};
19             while (pop @home) {
20             return Mojo::Home->new->parts([@home])
21             if -s catfile(@home, 'bin', lc $CLASS); # bin/..
22             }
23             Carp::croak("$CLASS installation directory not found!");
24             };
25              
26 1     1 1 1370 sub CODENAME { return $CODENAME }
27             has sessions => sub { Ado::Sessions::get_instance(shift->config) };
28              
29             has home => sub {
30             my ($app) = @_;
31             my $class = ref $app;
32             return $app->SUPER::home if $ENV{MOJO_HOME}; # MOJO_HOME was forced
33             my @home = splitdir $INC{class_to_path $class};
34             my $moniker = $app->moniker;
35             while (pop @home) {
36             return Mojo::Home->new->parts([@home])
37             if -s catfile(@home, 'bin', $moniker); # bin/..
38             }
39             return $app->SUPER::home; #fallback to Mojo::Home
40             };
41              
42              
43             sub _initialise {
44 25     25   59 my ($app) = @_;
45 25         101 my $home = $app->home;
46 25         236 my $mode = $app->mode;
47 25         658 my $ado_home = $app->ado_home;
48              
49             # add paths to bundled files if needed.
50 25         644 my $templates_dir = $ado_home->rel_dir('templates');
51 25         312 my $site_templates = $home->rel_dir('site_templates');
52 25         246 my $renderer_paths = $app->renderer->paths;
53 25         204 my $public_dir = $ado_home->rel_dir('public');
54 25         221 my $static_paths = $app->static->paths;
55             push @$renderer_paths, $templates_dir
56 25 100   25   491 unless (first { $_ eq $templates_dir } @$renderer_paths);
  25         118  
57             push @$static_paths, $public_dir
58 25 100   25   178 unless (first { $_ eq $public_dir } @$static_paths);
  25         92  
59              
60 25         135 $app->secrets([Mojo::Util::sha1_sum($app->moniker . $mode . $home),]);
61 25 50       1608 unshift @$renderer_paths, $site_templates if -d $site_templates;
62 25         214 $app->controller_class("${CLASS}::Control");
63 25         217 $app->routes->namespaces(["${CLASS}::Control"]);
64 25         305 $app->plugins->namespaces(['Mojolicious::Plugin', "${CLASS}::Plugin",]);
65 25         219 unshift @{$app->commands->namespaces}, "${CLASS}::Command";
  25         147  
66 25         1114 return $app;
67             }
68              
69             # This method will run once at server start
70             sub startup {
71 25     25 1 266195 shift->_initialise()->load_config()->load_plugins()->load_routes()->define_mime_types();
72 25         67 return;
73             }
74              
75             #load ado.conf
76             sub load_config {
77 25     25 1 49 my ($app) = @_;
78 25   66     255 $ENV{MOJO_CONFIG} //= catfile($app->home, 'etc', $app->moniker . '.conf');
79 25         622 $app->plugin('Config');
80 25         66374 return $app;
81             }
82              
83             sub load_plugins {
84 25     25 1 60 my ($app) = @_;
85              
86 25   100     84 my $plugins = $app->config('plugins') || [];
87 25         303 foreach my $plugin (@$plugins) {
88 185 100       480631 $app->log->debug('Loading Plugin ' . (ref $plugin ? $plugin->{name} : $plugin));
89 185 100       10409 if (ref $plugin eq 'HASH') {
    100          
90 23         248 $app->plugin($plugin->{name} => $plugin->{config});
91             }
92             elsif ($plugin) {
93 161         579 $app->plugin($plugin);
94             }
95             }
96              
97 25         120 return $app;
98             }
99              
100             #load routes defined in ado.conf
101             sub load_routes {
102 121     121 1 246 my ($app, $config_routes) = @_;
103 121   100     480 $config_routes ||= $app->config('routes') || [];
      66        
104 121         841 my $routes = $app->routes;
105              
106             # Hide Ado::Control methods and attributes from router.
107 121         1266 $routes->hide(
108             qw(
109             debug config require_format list_for_json
110             validate_input
111             )
112             );
113              
114 121         1476 foreach my $route (@$config_routes) {
115             my ($pattern, $over, $to, $via, $params) =
116 357         8330 ($route->{route}, $route->{over}, $route->{to}, $route->{via}, $route->{params});
117              
118 357 100       895 next unless $to;
119 333 100       1642 my $r = $params ? $routes->route($pattern, %$params) : $routes->route($pattern);
120              
121 333 100       65395 if ($over) {
122 27 100       179 if (ref $over eq 'HASH') { $r->over(%$over); }
  26         154  
123 1         23 else { $r->over($over); }
124             }
125 333 100       2371 if ($via) {
126 286         866 $r->via(@$via);
127             }
128 333 100       5101 $r->to(ref $to eq 'HASH' ? %$to : $to);
129             }
130              
131             # Default "/perldoc" page is Ado/Manual
132 121         3743 my $perldoc = $routes->lookup('perldocmodule');
133 121 100       2519 if ($perldoc) { $perldoc->to->{module} = 'Ado/Manual'; }
  119         345  
134              
135 121         1569 return $app;
136             }
137              
138             sub define_mime_types {
139 25     25 1 64 my ($app) = @_;
140 25   100     173 my $mimes = $app->config('types') || {}; #HASHREF
141 25         370 foreach my $mime (keys %$mimes) {
142              
143             # Add new MIME type or redefine any existing
144 46         2103 $app->types->type($mime => $mimes->{$mime});
145             }
146 25         319 return $app;
147             }
148              
149             1;
150              
151              
152             =pod
153              
154             =encoding utf8
155              
156             =head1 NAME
157              
158             Ado - a rapid active commotion (framework for web-projects on Mojolicious)
159              
160             =head1 SYNOPSIS
161              
162             require Mojolicious::Commands;
163             Mojolicious::Commands->start_app('Ado');
164              
165             =head1 DESCRIPTION
166              
167             L is a framework for web-projects based on L, written in the
168             L. This is the base
169             application class. Ado C L. For a more detailed description
170             on what Ado is and how to get started with Ado see B>.
171              
172             =head1 ATTRIBUTES
173              
174             Ado inherits all attributes from Mojolicious and implements the following new
175             ones.
176              
177             =head2 ado_home
178              
179             Returns an instance of L pointing to the base directory where
180             L is installed.
181              
182             ~$ ado eval 'say app->ado_home'
183             /home/berov/opt/public_dev/Ado
184              
185             =head2 CODENAME
186              
187             Returns the current C.
188              
189             =head2 home
190              
191             #/where/is/your_app/rootdir
192             $app->home;
193              
194             Returns the root directory into which $app is installed. The guessing order is
195             the following:
196              
197             =over
198              
199             =item 1. If C<$ENV{MOJO_HOME}> is defined, it is honored.
200              
201             =item 2. The upper directory of the directory in which the starting executable
202             C<$app-Emoniker> is found, e.g. C. This may happen to be the same
203             as L.
204              
205             =item 3. Fallback to L. This is the usual behavior of any L
206             application.
207              
208             =back
209              
210             =head2 sessions
211              
212             Access the L instance. Instantiates one of
213             L, L
214             or L depending on configuration and returns it.
215             By default (no configuration in C)
216             a L is returned.
217              
218              
219             =head1 METHODS
220              
221             Ado inherits all methods from Mojolicious and implements
222             the following new ones.
223              
224              
225             =head2 startup
226              
227             Sets various default paths like C, C, C.
228             Defines L as sha1_sum of C<$moniker.$mode. $home>. Sets
229             L and L to
230             L<${CLASS}::Control>. Sets L to
231             C<['Mojolicious::Plugin', "${CLASS}::Plugin"]>. Sets
232             L to C<${CLASS}::Command>. C<$CLASS> is
233             usually L. Then calls the following methods in the order they are listed.
234             Returns void.
235              
236             You can amend this behavior in the application configuration file.
237              
238             =head2 load_config
239              
240             Checks C<$ENV{MOJO_CONFIG}> and if not set sets it to
241             C<$app-Ehome/etc/ado.conf>. Loads L to do the
242             rest of the dirty work. Returns $app.
243              
244             =head2 load_plugins
245              
246             Does not accept any parameters. Loads plugins listed in
247             C<$config-E{plugins}>. C<$config-E{plugins}> is an C in
248             which each element is a C with keys C and C or string
249             representing the plugin name. The name of the plugin is expected to be string
250             that can be passed to L. The C values is another
251             C containing the configuration for the plugin. Plugins can be
252             L or L specific plugins. Every L::Foo must
253             inherit from L which C L. Of course
254             Mojolicious plugins can be used - we count on this. There are plenty of
255             examples on CPAN. Returns $app.
256              
257             =head2 load_routes
258              
259             Does not accept any parameters. Loads predefined routes from
260             C<$config-Eroutes>. C<$config-Eroutes> is an C in which each
261             element is a C with keys corresponding to a method name and value the
262             parameters that will be passed to the method. Currently we use the C
263             value to pass it to L,C value is the second
264             parameter to instantiate the route. C and C values are passed to the
265             newly created route. See L and
266             L for more.
267              
268             Returns $app.
269              
270             =head2 define_mime_types
271              
272             Defines any MIME types listed in C in C {...}>. Returns
273             $app.
274              
275             =head1 SPONSORS
276              
277             The original author.
278              
279             Become a sponsor and help make L the ERP for the enterprise!
280              
281             =head1 SEE ALSO
282              
283             L, L,
284             L,
285              
286             =head1 AUTHOR
287              
288             Красимир Беров (Krasimir Berov)
289              
290             =head1 COPYRIGHT AND LICENSE
291              
292             Copyright 2013-2016 Красимир Беров (Krasimir Berov).
293              
294             This program is free software, you can redistribute it and/or modify it under
295             the terms of the GNU Lesser General Public License v3 (LGPL-3.0). You may
296             copy, distribute and modify the software provided that modifications are open
297             source. However, software that includes the license may release under a
298             different license.
299              
300             See http://opensource.org/licenses/lgpl-3.0.html for more information.
301              
302             =cut