File Coverage

CGI/AppBuilder.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package CGI::AppBuilder;
2              
3             # Perl standard modules
4 1     1   26033 use strict;
  1         3  
  1         42  
5 1     1   6 use warnings;
  1         2  
  1         34  
6 1     1   3606 use Getopt::Std;
  1         75  
  1         93  
7 1     1   1222 use POSIX qw(strftime);
  1         8959  
  1         11  
8 1     1   6807 use CGI;
  1         34401  
  1         9  
9 1     1   1906 use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
  1         4308  
  1         10  
10 1     1   1862 use CGI::Pretty ':standard';
  1         2442  
  1         8  
11 1     1   8169 use CGI::AppBuilder::Config qw(:all);
  0            
  0            
12             use CGI::AppBuilder::Message qw(:all);
13             use CGI::AppBuilder::Log qw(:all);
14             use CGI::AppBuilder::Form qw(:all);
15             use CGI::AppBuilder::Table qw(:all);
16             use CGI::AppBuilder::Header qw(:all);
17             use CGI::AppBuilder::Frame qw(:all);
18              
19             our $VERSION = 0.12;
20             warningsToBrowser(1);
21              
22             require Exporter;
23             our @ISA = qw(Exporter);
24             our @EXPORT = qw(start_app end_app);
25             our @IMPORT_OK = (@CGI::AppBuilder::Config::EXPORT_OK,
26             @CGI::AppBuilder::Message::EXPORT_OK,
27             @CGI::AppBuilder::Log::EXPORT_OK,
28             @CGI::AppBuilder::Form::EXPORT_OK,
29             @CGI::AppBuilder::Table::EXPORT_OK,
30             @CGI::AppBuilder::Header::EXPORT_OK,
31             @CGI::AppBuilder::Frame::EXPORT_OK
32             );
33             our @EXPORT_OK = (qw(start_app end_app),@IMPORT_OK);
34             our %EXPORT_TAGS = (
35             app => [qw(start_app end_app build_html_header)],
36             config => [@CGI::AppBuilder::Config::EXPORT_OK],
37             echo_msg => [@CGI::AppBuilder::Message::EXPORT_OK],
38             log => [@CGI::AppBuilder::Log::EXPORT_OK],
39             form => [@CGI::AppBuilder::Form::EXPORT_OK],
40             table => [@CGI::AppBuilder::Table::EXPORT_OK],
41             header => [@CGI::AppBuilder::Header::EXPORT_OK],
42             frame => [@CGI::AppBuilder::Frame::EXPORT_OK],
43             all => [@EXPORT_OK, @IMPORT_OK]
44             );
45              
46             =head1 NAME
47              
48             CGI::AppBuilder - CGI Application Builder
49              
50             =head1 SYNOPSIS
51              
52             use CGI::AppBuilder;
53              
54             my $cg = CGI::AppBuilder->new('ifn', 'my_init.cfg', 'opt', 'vhS:a:');
55             my $ar = $cg->get_inputs;
56              
57             =head1 DESCRIPTION
58              
59             There are already many application builders out there. Why you need
60             another one? Well, if you are already familiar with CGI::Builder or
61             CGI::Application, this one will provide some useful methods to you to
62             read your configuration file and pre-process your templates.
63             Please read on.
64              
65             =cut
66              
67             =head3 new (ifn => 'file.cfg', opt => 'hvS:')
68              
69             Input variables:
70              
71             $ifn - input/initial file name.
72             $opt - options for Getopt::Std
73              
74             Variables used or routines called:
75              
76             None
77              
78             How to use:
79              
80             my $ca = new CGI::AppBuilder; # or
81             my $ca = CGI::AppBuilder->new; # or
82             my $ca = CGI::AppBuilder->new(ifn=>'file.cfg',opt=>'hvS:'); # or
83             my $ca = CGI::AppBuilder->new('ifn', 'file.cfg','opt','hvS:');
84              
85             Return: new empty or initialized CGI::AppBuilder object.
86              
87             This method constructs a Perl object and capture any parameters if
88             specified. It creates and defaults the following variables:
89            
90             $self->{ifn} = ""
91             $self->{opt} = 'hvS:';
92              
93             =cut
94              
95             sub new {
96             my $caller = shift;
97             my $caller_is_obj = ref($caller);
98             my $class = $caller_is_obj || $caller;
99             my $self = bless {}, $class;
100             my %arg = @_; # convert rest of inputs into hash array
101             foreach my $k ( keys %arg ) {
102             if ($caller_is_obj) {
103             $self->{$k} = $caller->{$k};
104             } else {
105             $self->{$k} = $arg{$k};
106             }
107             }
108             $self->{ifn} = "" if ! exists $arg{ifn};
109             $self->{opt} = 'hvS:' if ! exists $arg{opt};
110             return $self;
111             }
112              
113             =head3 start_app ($prg,$arg,$nhh)
114              
115             Input variables:
116              
117             $prg - program name
118             $arg - array ref for arguments - %ARGV
119             $nhh - no html header pre-printed
120             1 - no HTML header is set in any circumstance
121             0 - HTML header will be set when it is possible
122              
123             Variables used or routines called:
124              
125             build_html_header - build HTML header array
126             Debug::EchoMessage
127             echo_msg - echo messages
128             start_log - start and write message log
129             CGI::Getopt
130             get_inputs - read input file and/or CGI form inputs
131            
132              
133             How to use:
134              
135             my ($q, $ar, $ar_log) = $self->start_app($0,\@ARGV);
136              
137             Return: ($q,$ar,$ar_log) where
138              
139             $q - a CGI object
140             $ar - hash ref containing parameters from input file and/or
141             CGI form inputs and the following elements:
142             ifn - initial file name
143             opt - command input options
144             cfg - configuratoin array
145             html_header - HTML header parameters (hash ref)
146             msg - contain message hash
147             $ar_log - hash ref containing log information
148              
149             This method performs the following tasks:
150              
151             1) initial a CGI object
152             2) read initial file if specified or search for a default file
153             (the same as $prg with .ini extension) and save the file name
154             to $ar->{ifn}.
155             3) define message level
156             4) start HTML header and body using I and I
157             if they are defined.
158             5) parse CGI form inputs and combine them with parameters defined
159             in initial file
160             6) read configuration file ($prg.cfg) if it exists and save the
161             array to $ar->{cfg}
162             7) prepare log record if write log is enabled
163              
164             It checks the parameters read from initial file for page_title,
165             page_style, page_author, page_meta, top_nav, bottom_nav, and js_src.
166              
167             =cut
168              
169             sub start_app {
170             my $s = shift;
171             my ($prg, $ar_arg, $nhh) = @_;
172             my $args = ($ar_arg && $ar_arg =~ /ARRAY/)?(join " ", @$ar_arg):'';
173             my $ifn = $prg; $ifn =~ s/\.(\w+)$/\.ini/;
174             my $cfg = $prg; $cfg =~ s/\.(\w+)$/\.cfg/;
175             my $opt = 'a:v:hS:';
176             my ($q, $ar);
177             # 0. need to decide it is in verbose mode or not
178             my $web_flag = 0;
179             if (exists $ENV{HTTP_HOST} || exists $ENV{QUERY_STRING}) {
180             $q = CGI->new;
181             my $v1 = $q->param('v');
182             my $v2 = $q->Vars->{v};
183             if ((defined($v1) && $v1) || (defined($v2) && $v2)) {
184             $web_flag = 1;
185             print $q->header("text/html") if !$nhh;
186             }
187             }
188             #
189             # 1-3,5. Read initial file
190             ($q,$ar) = $s->get_inputs($ifn,$opt);
191             $s->echo_msg(" += Starting application...");
192             $s->echo_msg(" ++ Reading initial file $ifn...") if -f $ifn;
193             $s->echo_msg(" + Initial file - $ifn: not found.") if !-f $ifn;
194             # if user has defined messages in the initial file, we need to
195             # convert it into hash.
196             $ar->{msg} = eval $ar->{msg} if exists $ar->{msg};
197              
198             # 4. start HTML header
199             my %ar_hdr = $s->build_html_header($q, $ar);
200             $ar->{html_header} = \%ar_hdr if ! exists $ar->{html_header};
201              
202             # 5. start the HTML page
203             if (!$nhh && (
204             exists $ENV{HTTP_HOST} || exists $ENV{QUERY_STRING})) {
205             print $q->header("text/html") if ! $web_flag;
206             print $q->start_html(%ar_hdr), "\n";
207             print $ar->{top_nav} if exists $ar->{top_nav} && $ar->{top_nav};
208             }
209              
210             # 6. read configuration file
211             if (-f $cfg) {
212             $s->echo_msg(" ++ Reading config file $cfg...");
213             $ar->{cfg} = $s->read_cfg_file($cfg);
214             }
215              
216             # 7. set log array
217             my ($ds,$log_dir,$log_brf, $log_dtl) = ('/',"","","");
218             $log_dir = (exists ${$ar}{log_dir})?${$ar}{log_dir}:'.';
219             my $lgf = $ifn; $lgf =~ s/\.\w+//; $lgf =~ s/.*[\/\\](\w+)$/$1/;
220             my $tmp = strftime "%Y%m%d", localtime time;
221             $log_brf = join $ds, $log_dir, "${lgf}_brief.log";
222             $log_dtl = join $ds, $log_dir, "${lgf}_${tmp}.log";
223             my ($lfh_brf,$lfh_dtl,$txt,$ar_log) = ("","","","");
224             if (exists ${$ar}{write_log} && ${$ar}{write_log}) {
225             $ar_log = $s->start_log($log_dtl,$log_brf,"",$args,2);
226             }
227             $s->echo_msg($ar,5);
228             $s->echo_msg($ar_log,5);
229             return ($q,$ar,$ar_log);
230             }
231              
232             =head3 end_app ($q, $ar, $ar_log, $nhh)
233              
234             Input variables:
235              
236             $q - CGI object
237             $ar - array ref for parameters
238             $ar_log - hash ref for log record
239             $nhh - no html header pre-printed
240             1 - no HTML is printed in any circumstance
241             0 - HTML header will be printed when it is possible
242              
243             Variables used or routines called:
244              
245             Debug::EchoMessage
246             echo_msg - echo messages
247             end_log - start and write message log
248             set_param - get a parameter from hash array
249              
250             How to use:
251              
252             my ($q, $ar, $ar_log) = $self->start_app($0,\@ARGV);
253             $self->end_app($q, $ar, $ar_log);
254              
255             Return: none
256              
257             This method performs the following tasks:
258              
259             1) ends HTML document
260             2) writes log records to log files
261             3) close database connection if it finds DB handler in {dbh}
262              
263             =cut
264              
265             sub end_app {
266             my $s = shift;
267             my ($q, $ar, $ar_log, $nhh) = @_;
268             if (exists ${$ar}{write_log} && ${$ar}{write_log}) {
269             $s->end_log($ar_log);
270             }
271             my $dbh = $s->set_param('dbh', $ar);
272             $dbh->disconnect() if $dbh;
273             if (exists $ENV{HTTP_HOST} || exists $ENV{QUERY_STRING}) {
274             print $ar->{bottom_nav} if exists $ar->{bottom_nav} && !$nhh;
275             print $q->end_html if !$nhh;
276             }
277             }
278              
279             1;
280              
281             =head1 HISTORY
282              
283             =over 4
284              
285             =item * Version 0.10
286              
287             This version is to extract out the app methods from CGI::Getopt class.
288             It was too much for CGI::Getopt to include the start_app, end_app,
289             build_html_header, and disp_form methods.
290              
291             0.11 Rewrote start_app method so that content-type can be changed.
292             0.12 Moved disp_form to CGI::AppBuilder::Form,
293             moved build_html_header to CGI::AppBuilder::Header, and
294             imported all the methods in sub-classes into this class.
295              
296             =item * Version 0.20
297              
298             =cut
299              
300             =head1 SEE ALSO (some of docs that I check often)
301              
302             Oracle::Loader, Oracle::Trigger, CGI::Getopt, File::Xcopy,
303             CGI::AppBuilder, CGI::AppBuilder::Message, CGI::AppBuilder::Log,
304             CGI::AppBuilder::Config, etc.
305              
306             =head1 AUTHOR
307              
308             Copyright (c) 2005 Hanming Tu. All rights reserved.
309              
310             This package is free software and is provided "as is" without express
311             or implied warranty. It may be used, redistributed and/or modified
312             under the terms of the Perl Artistic License (see
313             http://www.perl.com/perl/misc/Artistic.html)
314              
315             =cut
316              
317