]> git.decadent.org.uk Git - maypole.git/blob - lib/Apache/MVC.pm
Apache2 fix in Apache::MVC (bug 13888)
[maypole.git] / lib / Apache / MVC.pm
1 package Apache::MVC;
2
3 our $VERSION = '2.10';
4
5 use strict;
6 use warnings;
7
8 use base 'Maypole';
9 use Maypole::Headers;
10
11 BEGIN {
12     my $version;
13     eval 'use mod_perl2; $version = $mod_perl2::VERSION; ';
14     if ($@) {
15         warn "no mod_perl 2.x using mod_perl 1.x\n";
16         use mod_perl;
17         $version = 0;
18         require Apache;
19         require Apache::Request;
20     } else {
21         require Apache2::RequestIO;
22         require Apache2::RequestRec;
23         require Apache2::RequestUtil;
24         require APR::URI;
25         require Apache2::Request;
26     }
27
28     use constant APACHE2 => $version;
29
30 }
31
32 sub get_request {
33     my ( $self, $r ) = @_;
34     $self->{ar} = (APACHE2) ? Apache2::Request->new($r) : Apache::Request->new($r);
35 }
36
37 sub parse_location {
38     my $self = shift;
39
40     # Reconstruct the request headers
41     $self->headers_in(Maypole::Headers->new);
42     my %headers;
43     if (APACHE2) { %headers = %{$self->{ar}->headers_in};
44     } else { %headers = $self->{ar}->headers_in; }
45     for (keys %headers) {
46         $self->headers_in->set($_, $headers{$_});
47     }
48
49     $self->{path} = $self->{ar}->uri;
50     my $loc = $self->{ar}->location;
51     no warnings 'uninitialized';
52     $self->{path} .= '/' if $self->{path} eq $loc;
53     $self->{path} =~ s/^($loc)?\///;
54     $self->parse_path;
55     $self->parse_args;
56 }
57
58 sub parse_args {
59     my $self = shift;
60     $self->{params} = { $self->_mod_perl_args( $self->{ar} ) };
61     $self->{query}  = { $self->_mod_perl_args( $self->{ar} ) };
62 }
63
64 sub send_output {
65     my $r = shift;
66     $r->{ar}->content_type(
67           $r->{content_type} =~ m/^text/
68         ? $r->{content_type} . "; charset=" . $r->{document_encoding}
69         : $r->{content_type}
70     );
71     $r->{ar}->headers_out->set(
72         "Content-Length" => do { use bytes; length $r->{output} }
73     );
74
75     foreach ($r->headers_out->field_names) {
76         next if /^Content-(Type|Length)/;
77         $r->{ar}->headers_out->set($_ => $r->headers_out->get($_));
78     }
79
80     APACHE2 || $r->{ar}->send_http_header;
81     $r->{ar}->print( $r->{output} );
82 }
83
84 sub get_template_root {
85     my $r = shift;
86     $r->{ar}->document_root . "/" . $r->{ar}->location;
87 }
88
89 sub _mod_perl_args {
90     my ( $self, $apr ) = @_;
91     my %args;
92     foreach my $key ( $apr->param ) {
93         my @values = $apr->param($key);
94         $args{$key} = @values == 1 ? $values[0] : \@values;
95     }
96     return %args;
97 }
98
99 1;
100
101 =head1 NAME
102
103 Apache::MVC - Apache front-end to Maypole
104
105 =head1 SYNOPSIS
106
107     package BeerDB;
108     use base 'Apache::MVC';
109     BeerDB->setup("dbi:mysql:beerdb");
110     BeerDB->config->uri_base("http://your.site/");
111     BeerDB->config->display_tables([qw[beer brewery pub style]]);
112     # Now set up your database:
113     # has-a relationships
114     # untaint columns
115
116     1;
117
118 =head1 DESCRIPTION
119
120 A mod_perl platform driver for Maypole. Your application can inherit from
121 Apache::MVC directly, but it is recommended that you use
122 L<Maypole::Application>.
123
124 =head1 INSTALLATION
125
126 Create a driver module like the one above.
127
128 Put the following in your Apache config:
129
130     <Location /beer>
131         SetHandler perl-script
132         PerlHandler BeerDB
133     </Location>
134
135 Copy the templates found in F<templates/factory> into the
136 F<beer/factory> directory off the web root. When the designers get
137 back to you with custom templates, they are to go in
138 F<beer/custom>. If you need to do override templates on a
139 database-table-by-table basis, put the new template in
140 F<beer/I<table>>. 
141
142 This will automatically give you C<add>, C<edit>, C<list>, C<view> and
143 C<delete> commands; for instance, a list of breweries, go to 
144
145     http://your.site/beer/brewery/list
146
147 For more information about how the system works and how to extend it,
148 see L<Maypole>.
149
150 =head1 Implementation
151
152 This class overrides a set of methods in the base Maypole class to provide it's
153 functionality. See L<Maypole> for these:
154
155 =over
156
157 =item get_request
158
159 =item get_template_root
160
161 =item parse_args
162
163 =item parse_location
164
165 =item send_output
166
167 =back
168
169 =head1 AUTHOR
170
171 Simon Cozens, C<simon@cpan.org>
172 Marcus Ramberg, C<marcus@thefeed.no>
173 Screwed up by Sebastian Riedel, C<sri@oook.de>
174
175 =head1 LICENSE
176
177 You may distribute this code under the same terms as Perl itself.
178
179 =cut