Yeah! As it seems CGI::Application was updated just few days ago - didnt know that.
But still, there are things (allready mentioned) that I simply dont like on CGI::Application, and some things that I miss (that "plugin" or however you want to call it possibility).
Eventialy, what I want to do. Create a plugin, it will be (use base/ISA) child of my mai<bn module so that I could use it's data (configs, db connections ...etc). And then be able to put simple tag to call that plugin in any template on my site (since everything goes over CGI::App)
To be precise, all requests except for graphic/css/similar, are processed by mod_rewrite and call index.cgi (yeah only one). Based on parameters, my main module derived from CGI::App calls specified modules. All works great, but it's not soo good as I hope.
I simply want more integration that more screens in one place. Basicly I want whole site, in central unit that does specific things (auth for instance) and then call on itself the rest of the code from specific modules/sections.
As it turned out I actualy faked OOP by passing $self as first param. And as I said, everything is working, but not as easy to maintan as I would like
For instance: (code included here)
package MList_Manager;
use base 'CGI::Application';
use base 'MList_Manager::settings';
use base 'MList_Manager::mailing_lists';
use base 'MList_Manager::subscribers';
use base 'MList_Manager::admin_subscribers';
use base 'MList_Manager::admin_messages';
########
########
######## When I add new section I need to add it here
########
########
use CGI::Session;
use Config::Trivial;
use DBI;
sub setup {
my $self = shift;
$self->mode_param('action');
$self->start_mode('main');
$self->run_modes([qw/
not_loged
login
logout
main
settings
mailing_lists
subscribers
admin_subscribers
admin_messages
/]);
########
########
######## And here also ...
########
########
}
sub cgiapp_prerun() {
my $self = shift;
my $q = $self->query();
my $f = $q->Vars();
my $run_mode = $self->get_current_runmode();
unless($run_mode eq 'subscribers'){
my $session = CGI::Session->new('driver::File',$q,{Directory
+ => 'sessions'});
my $cookie = $q->cookie(CGISESSID => $session->id);
$self->header_add(-cookie => [$cookie]);
$self->param('session' => $session);
# Configs
my $c = $self->param('settings');
unless($run_mode eq 'login'){
unless(defined($session->param('admin_user')) && ($sess
+ion->param('admin_user') eq $c->{'admin_user'}) &&
($session->param('admin_pass') eq $c->{'admin_pass'})){
$self->prerun_mode('not_loged');
}
}
}
}
sub not_loged {
my $self = shift;
my $comments = shift;
my $t = $self->load_tmpl(filename => 'login.html',die_on_bad_para
+m=>0);
$t->param(%{$comments}) if defined $comments;
return $t->output();
}
sub login {
my $self = shift;
my $q = $self->query();
my $f = $q->Vars();
# Configs
my $c = $self->param('settings');
if($f->{admin_pass} eq $c->{admin_pass} && $f->{admin_user} eq $c
+->{admin_user}) {
# Login OK
my $session = $self->param('session');
$session->param('admin_user' => $c->{admin_user});
$session->param('admin_pass' => $c->{admin_pass});
$session->expire('+5h');
my $cookie = $q->cookie(CGISESSID => $session->id);
$self->header_add(-cookie => [$cookie]);
my $settings = {};
my $config;
if(-e 'config.dat'){
$config = Config::Trivial->new(config_file => 'config.d
+at');
$settings = $config->read();
}
# Fix !! Strip off everything after ? in the $f->{index}
$f->{index} = split(/\?/,$f->{index}) if defined $f->{index}
+;
$settings->{'index_url'} = $f->{'index'} if ! defined $setti
+ngs->{'index_url'};
Config::Trivial->write(
config_file => 'config.dat',
configuration => $settings
);
return $self->main();
} else {
# Login ERROR
return $self->not_loged({'message' => 'Wrong username or pas
+sword'});
}
}
sub logout {
# He is allready loged in ...
my $self = shift;
my $session = $self->param('session');
$session->param('admin_user' => '');
$session->param('admin_pass' => '');
my $t = $self->load_tmpl(filename => 'logout.html', die_on_bad_pa
+rams => 0);
return $t->output();
}
sub main {
my $self = shift;
my $t = $self->load_tmpl(filename => 'main.html', die_on_bad_param
+s => 0);
my $c = $self->param('settings');
if(defined $c->{total_ok} && $c->{total_ok} == 1){
$t->param({'mailing_lists' => $self->DB_execute({'sql' => 'S
+ELECT COUNT(*) FROM mailing_lists',
'method' => 'fetchro
+w_array'}),
'subscribers' => $self->DB_execute({'sql' =>
+'SELECT COUNT(*) FROM subscribers WHERE status = ?',
'data' => ['subscrib
+ed'],
'method' => 'fetchro
+w_array'})
});
} else {
$t->param({'mailing_lists'=> "<FONT COLOR=red><A title=\"Ple
+ase confirm that your settings are all OK\"> N/A </A></FONT>",
'subscribers' => "<FONT COLOR=red><A title=\"Plea
+se confirm that your settings are all OK\"> N/A </A></FONT>"});
}
$t->param('index_url' => $c->{index_url});
return $t->output();
}
1;
That is actualy nice compared to what those sections look like :
package MList_Manager::mailing_lists;
....
sub mailing_lists {
my $self = shift;
my $q = $self->query();
my $f = $q->Vars();
# Code that calls each section from the file that it's
# part of. In case some section doesnt exists, AUTOLOADER
# is called automaticly.
# If nothig is to be called, it calls mailing_lists_main
if (defined($f->{section}) && (length($f->{section})>=1)){
my $section = $_file . $f->{section};
return &$section($self);
########
######## faking it here since this is actualy
######## executed as main module wich inherited this
######## methods ...
########
########
}
return $self->mailing_lists_main();
}
....
OK it's probably partialy my fault as I was only starting with OOP when I wrote that but still ...
Any ideas of how do acomplish something like this, but in a more elegant way?