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   523574 use Mojo::Base -strict;
  24         8084  
  24         245  
3              
4 24     24   3815 use Mojo::Base 'Mojolicious';
  24         54  
  24         93  
5 24     24   2369074 use File::Spec::Functions qw(splitdir catdir catfile);
  24         68  
  24         1927  
6 24     24   143 use Mojo::Util 'class_to_path';
  24         43  
  24         1249  
7 24     24   119 use List::Util 'first';
  24         33  
  24         2602  
8              
9             our $AUTHORITY = 'cpan:BEROV';
10             our $VERSION = '0.932';
11             our $CODENAME = 'U+2C0A GLAGOLITIC CAPITAL LETTER INITIAL IZHE (Ⰺ)';
12              
13 24     24   13227 use Ado::Control;
  24         70  
  24         235  
14 24     24   11301 use Ado::Sessions;
  24         52  
  24         236  
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 1420 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   96 my ($app) = @_;
45 25         115 my $home = $app->home;
46 25         258 my $mode = $app->mode;
47 25         723 my $ado_home = $app->ado_home;
48              
49             # add paths to bundled files if needed.
50 25         710 my $templates_dir = $ado_home->rel_dir('templates');
51 25         339 my $site_templates = $home->rel_dir('site_templates');
52 25         260 my $renderer_paths = $app->renderer->paths;
53 25         212 my $public_dir = $ado_home->rel_dir('public');
54 25         238 my $static_paths = $app->static->paths;
55             push @$renderer_paths, $templates_dir
56 25 100   25   521 unless (first { $_ eq $templates_dir } @$renderer_paths);
  25         127  
57             push @$static_paths, $public_dir
58 25 100   25   213 unless (first { $_ eq $public_dir } @$static_paths);
  25         103  
59              
60 25         173 $app->secrets([Mojo::Util::sha1_sum($app->moniker . $mode . $home),]);
61 25 50       1733 unshift @$renderer_paths, $site_templates if -d $site_templates;
62 25         240 $app->controller_class("${CLASS}::Control");
63 25         231 $app->routes->namespaces(["${CLASS}::Control"]);
64 25         343 $app->plugins->namespaces(['Mojolicious::Plugin', "${CLASS}::Plugin",]);
65 25         248 unshift @{$app->commands->namespaces}, "${CLASS}::Command";
  25         157  
66 25         1239 return $app;
67             }
68              
69             # This method will run once at server start
70             sub startup {
71 25     25 1 290142 shift->_initialise()->load_config()->load_plugins()->load_routes()->define_mime_types();
72 25         71 return;
73             }
74              
75             #load ado.conf
76             sub load_config {
77 25     25 1 70 my ($app) = @_;
78 25   66     239 $ENV{MOJO_CONFIG} //= catfile($app->home, 'etc', $app->moniker . '.conf');
79 25         684 $app->plugin('Config');
80 25         76221 return $app;
81             }
82              
83             sub load_plugins {
84 25     25 1 75 my ($app) = @_;
85              
86 25   100     94 my $plugins = $app->config('plugins') || [];
87 25         326 foreach my $plugin (@$plugins) {
88 185 100       511877 $app->log->debug('Loading Plugin ' . (ref $plugin ? $plugin->{name} : $plugin));
89 185 100       11043 if (ref $plugin eq 'HASH') {
    100          
90 23         262 $app->plugin($plugin->{name} => $plugin->{config});
91             }
92             elsif ($plugin) {
93 161         605 $app->plugin($plugin);
94             }
95             }
96              
97 25         149 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     472 $config_routes ||= $app->config('routes') || [];
      66        
104 121         816 my $routes = $app->routes;
105              
106             # Hide Ado::Control methods and attributes from router.
107 121         1214 $routes->hide(
108             qw(
109             debug config require_format list_for_json
110             validate_input
111             )
112             );
113              
114 121         1364 foreach my $route (@$config_routes) {
115             my ($pattern, $over, $to, $via, $params) =
116 357         8372 ($route->{route}, $route->{over}, $route->{to}, $route->{via}, $route->{params});
117              
118 357 100       833 next unless $to;
119 333 100       1603 my $r = $params ? $routes->route($pattern, %$params) : $routes->route($pattern);
120              
121 333 100       64865 if ($over) {
122 27 100       165 if (ref $over eq 'HASH') { $r->over(%$over); }
  26         181  
123 1         4 else { $r->over($over); }
124             }
125 333 100       2282 if ($via) {
126 286         885 $r->via(@$via);
127             }
128 333 100       4861 $r->to(ref $to eq 'HASH' ? %$to : $to);
129             }
130              
131             # Default "/perldoc" page is Ado/Manual
132 121         3516 my $perldoc = $routes->lookup('perldocmodule');
133 121 100       2606 if ($perldoc) { $perldoc->to->{module} = 'Ado/Manual'; }
  119         329  
134              
135 121         1481 return $app;
136             }
137              
138             sub define_mime_types {
139 25     25 1 59 my ($app) = @_;
140 25   100     96 my $mimes = $app->config('types') || {}; #HASHREF
141 25         330 foreach my $mime (keys %$mimes) {
142              
143             # Add new MIME type or redefine any existing
144 46         2034 $app->types->type($mime => $mimes->{$mime});
145             }
146 25         315 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