1 # Vend::Page - Handle Interchange page routing
3 # $Id: Page.pm,v 2.26 2008-04-15 19:37:57 racke Exp $
5 # Copyright (C) 2002-2008 Interchange Development Group
6 # Copyright (C) 1996-2002 Red Hat, Inc.
8 # This program was originally based on Vend 0.2 and 0.3
9 # Copyright 1995 by Andrew M. Wilcox <amw@wilcoxsolutions.com>
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public
22 # License along with this program; if not, write to the Free
23 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
31 use Vend::Interpolate;
47 use vars qw/$VERSION/;
49 $VERSION = substr(q$Revision: 2.26 $, 10);
53 sub display_special_page {
54 my($name, $subject) = @_;
57 undef $Vend::write_redirect;
59 $name =~ m/[\[<]|[\@_]_[A-Z]\w+_[\@_]|\@\@[A-Z]\w+\@\@/
62 "Security violation -- scripting character in page name '%s'.",
65 $name = find_special_page('violation');
66 1 while $subject =~ s/[\@_]_/_/g;
69 $subject ||= 'unspecified error';
72 $noname =~ s:^\.\./::;
74 $page = readfile($noname, $Global::NoAbsolute, 1) || readin($name);
76 die ::get_locale_message(412, qq{Missing special page "%s" for subject "%s"\n}, $name, $subject)
78 $page =~ s#\[subject\]#$subject#ig;
79 $Global::Variable->{MV_SUBJECT} = $subject;
81 interpolate_html($page, 1);
85 # Displays the catalog page NAME. If the file is not found, displays
86 # the special page 'missing'.
93 $name ||= $CGI::values{mv_nextpage};
95 $name =~ m/[\[<]|[\@_]_[A-Z]\w+_[\@_]|\@\@[A-Z]\w+\@\@/
98 "Security violation -- scripting character in page name '%s'.",
101 $name = find_special_page('violation');
102 return display_special_page($name);
105 if($Vend::Cfg->{ExtraSecure} and
106 $Vend::Cfg->{AlwaysSecure}->{$name}
108 $name = find_special_page('violation');
111 $page = $Vend::VirtualPage || readin($name);
113 if (defined $page && $Vend::Track) {
114 $Vend::Track->view_page($name);
119 # Try for on-the-fly if not there
120 if(! defined $page) {
121 $page = Vend::Interpolate::fly_page($name)
122 and $inth_opt->{onfly} = 1;
125 # Try one last time for page with index
126 if(! defined $page and $Vend::Cfg->{DirectoryIndex}) {
128 $try =~ s!/*$!/$Vend::Cfg->{DirectoryIndex}!;
129 $page = readin($try);
134 if ($opt->{return}) {
135 return ::interpolate_html($page, 1, $inth_opt);
137 ::interpolate_html($page, 1, $inth_opt);
145 if(my $subname = $Vend::Cfg->{SpecialSub}{missing}) {
146 my $sub = $Vend::Cfg->{Sub}{$subname} || $Global::GlobalSub->{$subname};
147 ($handled, $newpage) = $sub->($name)
151 return display_page($newpage) if $newpage;
154 HTML::Entities::encode($name, $ESCAPE_CHARS::std);
155 display_special_page(find_special_page('missing'), $name);
161 # Display the catalog page NAME.
167 sub _check_search_file {
171 if ($c->{mv_search_file}) {
172 my(@files) = grep /\S/, split /\s*[,\0]\s*/, $c->{mv_search_file}, -1;
174 unless (grep { $f eq $_ } @{$Vend::Cfg->{AllowRemoteSearch}}) {
175 ::logGlobal("Security violation, trying to remote search '%s', doesn't match '%s'",
176 $f, join ',' => @{$Vend::Cfg->{AllowRemoteSearch}});
177 die "Security violation";
188 # If search parameters not passed in via function, then safely pull them from
191 $c = find_search_params(\%CGI::values);
192 _check_search_file($c);
195 if ($c->{mv_more_matches}) {
196 $Vend::Session->{last_search} = "scan/MM=$c->{mv_more_matches}";
197 $c->{mv_more_matches} =~ m/([a-zA-Z0-9])+/;
198 $c->{mv_cache_key} = $1;
201 create_last_search($c);
204 $c->{mv_cache_key} = generate_key($Vend::Session->{last_search})
205 unless defined $c->{mv_cache_key};
207 my $retval = perform_search($c);
210 $::Instance->{SearchObject}{''} = $retval;
211 $CGI::values{mv_nextpage} = $retval->{mv_search_page}
212 || find_special_page('search')
213 if ! $CGI::values{mv_nextpage};
219 # Same as search except path is source of search info
225 $Vend::ScanPassed = "scan/$path";
226 find_search_params($c,$path);
228 _check_search_file($c);
230 if ($c->{mv_more_matches}) {
231 $Vend::Session->{last_search} = "scan/MM=$c->{mv_more_matches}";
232 $Vend::More_in_progress = 1;
233 $c->{mv_more_id} = $CGI::values{mv_more_id} || undef;
234 $c->{mv_more_matches} =~ m/([a-zA-Z0-9])+/;
235 $c->{mv_cache_key} = $1;
236 $CGI::values{mv_nextpage} = $c->{mv_nextpage}
237 if ! defined $CGI::values{mv_nextpage};
240 $c->{mv_cache_key} = generate_key(create_last_search($c));
243 $::Instance->{SearchObject}{''} = perform_search($c);
244 $CGI::values{mv_nextpage} = $::Instance->{SearchObject}{''}->{mv_search_page}
245 || find_special_page('search')
246 if ! $CGI::values{mv_nextpage};
253 return '' unless $ary = $Vend::OutPtr{lc $tag};
255 next unless $Vend::Output[$_];
256 next unless length(${$Vend::Output[$_]});
265 return '' unless $ary = $Vend::OutPtr{lc $tag};
268 next unless $Vend::Output[$_];
269 $out .= ${$Vend::Output[$_]};
270 undef $Vend::Output[$_];
272 $out =~ s/^\s+// if $::Pragma->{strip_white};
279 return '' unless $ary = $Vend::OutPtr{lc $tag};
282 next unless $Vend::Output[$_];
283 push @out, ${$Vend::Output[$_]};
284 undef $Vend::Output[$_];
292 for(@$Vend::Output) {
294 $out .= ${$Vend::Output[$_]};
295 undef $Vend::Output[$_];
302 $template ||= $Vend::Cfg->{PageTemplate} || '{:REST}';
303 #::logDebug("Templatizing, template length=" . length($template));
304 my $body = $template;
306 $body =~ s!\{\{\@([A-Z][A-Z_0-9]*[A-Z0-9])\}\}(.*?)\{\{/\@\1\}\}!
309 return '' unless $ary = $Vend::OutPtr{$tag};
313 my $ref = $Vend::Output[$_]
316 $chunk =~ s/\{$tag\}/$$ref/;
317 undef $Vend::Output[$_];
322 1 while $body =~ s!\{\{([A-Z][A-Z_0-9]*[A-Z0-9])\?\}\}(.*?)\{\{/\1\?\}\}! output_test(lc $1) ? $2 : ''!egs;
323 1 while $body =~ s!\{\{([A-Z][A-Z_0-9]*[A-Z0-9])\:\}\}(.*?)\{\{/\1\:\}\}! output_test(lc $1) ? '' : $2!egs;
324 $body =~ s!\{\{([A-Z][A-Z_0-9]*[A-Z0-9])\}\}!output_cat($1)!eg;
325 $body =~ s!\{\{:DEFAULT\}\}!output_cat('')!e;
326 $body =~ s!\{\{:REST\}\}!output_rest('')!e;
327 @Vend::Output = (\$body);