package App::Web;
use strict;
use vars qw($VERSION);
use Log::Log4perl qw( get_logger );
use Workflow::Factory qw( FACTORY );
use XML::Simple qw( :strict );
$VERSION = '0.01';
my ( $log );
my %ACTION_DATA = ();
my %DISPATCH = ();
sub initialize_mappings {
my ( $class, $mapping_file ) = @_;
$log ||= get_logger();
my %options = (
ForceArray => [ 'url-mapping', 'action-display' ],
KeyAttr => [],
);
my $config = XMLin( $mapping_file, %options );
no strict 'refs';
foreach my $url_map ( @{ $config->{'url-mapping'} } ) {
my $map_class = $url_map->{class};
my $map_method = $url_map->{method};
eval "require $map_class";
if ( $@ ) {
die "Cannot include class '$map_class': $@\n";
}
my $method = \&{ $map_class . '::' . $map_method };
unless ( $method ) {
die "No method '$map_class->$map_method'\n";
}
$DISPATCH{ $url_map->{url} } = $method;
}
foreach my $action_template ( @{ $config->{'action-display'} } ) {
$ACTION_DATA{ $action_template->{name} } = $action_template->{template};
}
return $config;
}
########################################
# DISPATCH MAPPINGS
#
# Each of these routines returns a template name, stuffing data used
# by the template into \%params and any outbound cookies into
# \%cookies_out.
sub lookup_dispatch {
my ( $class, $action_name ) = @_;
return $DISPATCH{ $action_name };
}
sub create_workflow {
my ( $client, $request, $cookies_in, $cookies_out, $params ) = @_;
my $wf = FACTORY->create_workflow( 'Ticket' );
$params->{workflow} = $wf;
$cookies_out->{workflow_id} = $wf->id;
return 'workflow_created.tmpl';
}
sub fetch_workflow {
my ( $client, $request, $cookies_in, $cookies_out, $params ) = @_;
my $wf = _get_workflow( $params, $cookies_in );
$cookies_out->{workflow_id} = $wf->id;
return 'workflow_fetched.tmpl';
}
sub list_history {
my ( $client, $request, $cookies_in, $cookies_out, $params ) = @_;
my $wf = _get_workflow( $params, $cookies_in );
my @history = $wf->get_history();
$params->{history_list} = \@history;
return 'workflow_history.tmpl';
}
sub execute_action {
my ( $client, $request, $cookies_in, $cookies_out, $params ) = @_;
my $wf = _get_workflow( $params, $cookies_in );
my $action = $params->{action};
unless ( $action ) {
die "To execute an action you must specify an action name!\n";
}
# If they haven't entered data yet, add the fields (as a map) to
# the parameters and redirect to the form for entering it
unless ( $params->{_action_data_entered} || ! $ACTION_DATA{ $action } ) {
$params->{status_msg} =
"Action cannot be executed until you enter its data";
my @fields = $wf->get_action_fields( $action );
my %by_name = map { $_->name => $_ } @fields;
$params->{ACTION_FIELDS} = \%by_name;
return $ACTION_DATA{ $action };
}
# Otherwise, set the user data directly into the workflow context...
$wf->context->param( $params );
# ...and execute the action
eval { $wf->execute_action( $params->{action} ) };
# ...if we catch a condition/validation exception, display the
# error and go back to the data entry form
if ( $@ && ( $@->isa( 'Workflow::Exception::Condition' ) ||
$@->isa( 'Workflow::Exception::Validation' ) ) ) {
$log->error( "One or more conditions not met to execute action: $@; ",
"redirecting to form" );
$params->{error_msg} = "Failed to execute action: $@";
return $ACTION_DATA{ $action };
}
$params->{status_msg} = "Action '$action' executed ok";
return list_history( $client, $request, $cookies_in, $cookies_out, $params );
}
sub login {
my ( $client, $request, $cookies_in, $cookies_out, $params ) = @_;
if ( $params->{current_user} ) {
$cookies_out->{current_user} = $params->{current_user};
}
else {
$params->{error_msg} = "Please specify a login name I can use!";
}
return 'index.tmpl';
}
sub _get_workflow {
my ( $params, $cookies_in ) = @_;
return $params->{workflow} if ( $params->{workflow} );
my $log = get_logger();
my $wf_id = $params->{workflow_id} || $cookies_in->{workflow_id};
unless ( $wf_id ) {
die "No workflow ID given! Please fetch a workflow or create ",
"a new one.\n";
}
$log->debug( "Fetching workflow with ID '$wf_id'" );
my $wf = FACTORY->fetch_workflow( 'Ticket', $wf_id );
if ( $wf ) {
$log->debug( "Workflow found, current state is '", $wf->state, "'" );
$params->{workflow} = $wf;
}
else {
$log->warn( "No workflow found with ID '$wf_id'" );
die "No workflow found with ID '$wf_id'\n";
}
return $wf;
}
1;
syntax highlighted by Code2HTML, v. 0.9.1