aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/Cobrand.pm
blob: 9f61635d89e1306bca3e24747ee5155cca97d11a (plain)
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
# 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;
}

1;