1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved.
# Email: evdb@mysociety.org. WWW: http://www.mysociety.org
package FixMyStreet::Cobrand;
use strict;
use warnings;
use FixMyStreet;
use Carp;
use Package::Stash;
use Module::Pluggable
sub_name => '_cobrands',
search_path => ['FixMyStreet::Cobrand'],
require => 1;
my @ALL_COBRAND_CLASSES = __PACKAGE__->_cobrands;
=head2 get_allowed_cobrands
Return an array reference of allowed cobrand monikers and hostname substrings.
=cut
sub get_allowed_cobrands {
my $class = shift;
my @allowed_cobrands = map {
ref $_ ? { moniker => keys %$_, host => values %$_ }
: { moniker => $_, host => $_ }
} @{ $class->_get_allowed_cobrands };
return \@allowed_cobrands;
}
=head2 _get_allowed_cobrands
Simply returns the config variable (so this function can be overridden in test suite).
=cut
sub _get_allowed_cobrands {
my $allowed = FixMyStreet->config('ALLOWED_COBRANDS') || [];
# If the user has supplied a string, convert to an arrayref
$allowed = [ $allowed ] unless ref $allowed;
return $allowed;
}
=head2 available_cobrand_classes
@available_cobrand_classes =
FixMyStreet::Cobrand->available_cobrand_classes();
Return an array of all the classes from get_allowed_cobrands, in
the order of get_allowed_cobrands, with added class information
for those that have found classes.
=cut
sub available_cobrand_classes {
my $class = shift;
my %all = map { $_->moniker => $_ } @ALL_COBRAND_CLASSES;
my @avail;
foreach (@{ $class->get_allowed_cobrands }) {
#next unless $all{$_->{moniker}};
$_->{class} = $all{$_->{moniker}};
push @avail, $_;
}
return @avail;
}
=head2 class
=cut
sub class {
my $avail = shift;
return $avail->{class} if $avail->{class};
my $moniker = "FixMyStreet::Cobrand::$avail->{moniker}";
my $class = bless {}, $moniker;
my $stash = Package::Stash->new($moniker);
my $isa = $stash->get_or_add_symbol('@ISA');
@{$isa} = ('FixMyStreet::Cobrand::Default');
return $moniker;
}
=head2 get_class_for_host
$cobrand_class = FixMyStreet::Cobrand->get_class_for_host( $host );
Given a host determine which cobrand we should be using.
=cut
sub get_class_for_host {
my $class = shift;
my $host = shift;
my @available = $class->available_cobrand_classes;
# If only one entry, always use it
return class($available[0]) if 1 == @available;
# If more than one entry, pick first whose regex (or
# name by default) matches hostname
foreach my $avail ( @available ) {
return class($avail) if $host =~ /$avail->{host}/;
}
# if none match then use the default
return 'FixMyStreet::Cobrand::Default';
}
=head2 get_class_for_moniker
$cobrand_class = FixMyStreet::Cobrand->get_class_for_moniker( $moniker );
Given a moniker determine which cobrand we should be using.
=cut
sub get_class_for_moniker {
my $class = shift;
my $moniker = shift;
foreach my $avail ( $class->available_cobrand_classes ) {
return class($avail) if $moniker eq $avail->{moniker};
}
# Special case for old blank cobrand entries in fixmystreet.com.
return 'FixMyStreet::Cobrand::FixMyStreet' if $moniker eq '';
# if none match then use the default
return 'FixMyStreet::Cobrand::Default';
}
=head2 exists
FixMyStreet::Cobrand->exists( $moniker );
Given a moniker, returns true if that cobrand is available to us for use
=cut
sub exists {
my ( $class, $moniker ) = @_;
foreach my $avail ( $class->available_cobrand_classes ) {
return 1 if $moniker eq $avail->{moniker};
}
return 0;
}
sub body_handler {
my ($class, $areas) = @_;
foreach my $avail ( $class->available_cobrand_classes ) {
my $cobrand = $class->get_class_for_moniker($avail->{moniker})->new({});
next unless $cobrand->can('council_area_id');
return $cobrand if $areas->{$cobrand->council_area_id};
}
}
1;
|