Add code from gists 12311[56]
[catagits/CatalystX-DynamicComponent.git] / t / lib / TestComplexApp / Model / PaymentProvider.pm
CommitLineData
d4db6430 1package TestComplexApp::Model::PaymentProvider;
2use Moose;
3use Moose::Meta::Class;
4use namespace::autoclean;
5
6extends 'Catalyst::Model';
7
8=head1 NAME
9
10PaymentApp::Model::PaymentProvider - Provider Model factory
11
12=head1 DESCRIPTION
13
14This module creates dynamic Catalyst Models based on configured
15payment providers and the requested payment profile.
16
17The Model instance is created at request time, not at setup time, and
18so we can inspect the message to see which enterprise and profile is
19required. We then load that profile using the ProfileDB Model, and
20instantiate the Model. The corresponding generated controller then
21invokes the appropriate method on this Model.
22
23We create a Model class per configured payment provider, and we
24require this configuration:
25
26 Model::PaymentProvider:
27 providers:
28 - PaymentProvider::Datacash
29 - PaymentProvider::Cybersource
30 - PaymentProvider::Null
31
32The Model instances may be accessed like so:
33
34 $c->model('PaymentProvider::Datacash')
35
36with the enterprise and profile names in the stash.
37
38=head1 TODO
39
40More graceful handling of missing enterprise and/or profile. We should
41do something other than just not return a model.
42
43=head1 SEE ALSO
44
45PaymentApp::Controller::PaymentProvider - this module's partner in crime.
46
47=cut
48
49sub COMPONENT {
50 my $self = shift->next::method(@_);
51
52 my $provider_classes = $self->{providers};
53
54 for my $provider_class (@$provider_classes) {
55 eval "require $provider_class";
56 if ($@) {
57 die "loading $provider_class: $@";
58 }
59
60 my $provider_model_name = "PaymentApp::Model::${provider_class}";
61 my $provider = Moose::Meta::Class->create($provider_model_name);
62 $provider->add_method('ACCEPT_CONTEXT',
63 sub {
64 my ($model, $c) = @_;
65 my $profile = $self->load_profile($c);
66 my $provider_model = $provider_class->new($profile);
67 return $provider_model;
68 });
69 }
70
71 return $self;
72}
73
74# Load the given profile and instantiate the provider
75sub load_profile {
76 my ($self, $c) = @_;
77
78 my $profile_name = $c->stash->{profile};
79 my $enterprise_name = $c->stash->{enterprise};
80
81 my $enterprise = $c->model('ProfileDB::Enterprise')->single(
82 {name => $enterprise_name}
83 );
84 my $profile = $c->model('ProfileDB::Profile')->single(
85 {name => $profile_name, enterprise_id => $enterprise->id}
86 );
87
88 my $profile_data = {};
89 my $set_rs = $c->model('ProfileDB::ProfileSetting')->search(
90 {profile_id => $profile->id}
91 );
92 while (my $set = $set_rs->next) {
93 $profile_data->{$set->name} = $set->value;
94 }
95
96 return $profile_data;
97}
98
991;
100