File Coverage

lib/CGI/PathRequest.pm
Criterion Covered Total %
statement 240 301 79.7
branch 84 128 65.6
condition 15 27 55.5
subroutine 37 48 77.0
pod 22 32 68.7
total 398 536 74.2


line stmt bran cond sub pod time code
1             package CGI::PathRequest;
2 5     5   103189 use strict;
  5         13  
  5         160  
3 5     5   25 use warnings;
  5         8  
  5         177  
4 5     5   6627 use File::MMagic;
  5         122578  
  5         204  
5 5     5   59 use base 'File::PathInfo::Ext';
  5         9  
  5         6369  
6 5     5   42517 use Carp;
  5         14  
  5         302  
7 5     5   12855 use CGI;
  5         121949  
  5         43  
8 5     5   5363 use HTML::Entities;
  5         45250  
  5         630  
9 5     5   50 use vars qw/$VERSION $DEBUG/;
  5         9  
  5         13382  
10             $VERSION = sprintf "%d.%02d", q$Revision: 1.19 $ =~ /(\d+)/g;
11             $DEBUG = 0;
12 1     1 0 16 sub DEBUG : lvalue { $DEBUG }
13              
14             sub new {
15 20     20 1 61913 my ($class, $self) = (shift, shift);
16 20 100 66     707 if (defined $self and ref $self ne 'HASH'){
17 1         14 $self = __PACKAGE__->SUPER::new($self);
18             }
19            
20 20   50     315 $self ||= {};
21 20   50     242 $self->{param_name} ||= 'rel_path';
22 20   50     164 $self->{default} ||= undef; # what is the default
23 20 50       74 $self->{tainted_request} and ( $self->{rel_path} = $self->{tainted_request} );
24 20   100     98 $self->{rel_path} ||= undef;
25 20   50     163 $self->{excerpt_size} ||= 255; # chars if excerpt is called for
26 20         80 $self->{status} = [];
27 20         67 $self->{request_made} = 0; # was a request received
28              
29 20 50       72 $self->{tainted_request}
30             and carp('warning: argument tainted_path to CGI::PathRequest is deprecated.');
31 20 50       59 $self->{default}
32             and carp("use of 'default' to CGI::PathRequest is deprecated");
33              
34 20         82 bless $self, $class;
35              
36              
37 20 100       114 if ($self->_arg){
38             ### settiong
39 19 100       64 $self->set( $self->_arg ) or return; #or $self->{data}->{exists} = 0;
40             }
41              
42             ### ok
43 14         3715 return $self;
44             }
45              
46             sub exists {
47 310     310 0 54875 my $self = shift;
48 310 100       1054 if (defined $self->{data}->{exists}){
49 297         779 return $self->{data}->{exists};
50             }
51 13 50       42 ( -e $self->abs_path ) ? ( $self->{data}->{exists} = 1) : ($self->{data}->{exists} = 0);
52 13         626 return $self->{data}->{exists};
53             }
54              
55              
56              
57              
58             # run once!?
59             sub _arg {
60 39     39   73 my $self = shift;
61            
62 39 100       280 unless ( defined $self->{_arg} ){
63             ### getting _arg
64 20         41 my $argument = undef;
65            
66 20 100       112 if (defined $self->{rel_path}){
    100          
67             #### from constructor
68 14         50 $self->{request_method} = 'constructor argument';
69            
70 14         54 $argument = $self->{rel_path};
71             }
72              
73            
74             elsif ( my $fromcgi = $self->_get_rel_path_from_cgi ){
75             #### from cgi
76 5         16 $self->{request_method} = 'from cgi';
77 5         9 $argument= $fromcgi;
78             }
79              
80             else {
81             #### none
82 1         25 $self->{request_method} = 'none';
83             }
84            
85             # if( $argument ){
86             # $argument=~s/^\///; # hack
87             # }
88            
89             #$argument ||= $self->DOCUMENT_ROOT;
90             #### $argument
91              
92 20 100       67 defined $argument or return;
93 19 50       318 $self->DOCUMENT_ROOT or die("DOCUMENT_ROOT not defined?");
94 19 100       2647 if ( -e $self->DOCUMENT_ROOT .'/'.$argument ){
95 13         541 $argument = $self->DOCUMENT_ROOT .'/'.$argument;
96             }
97            
98            
99 19         403 $self->{_arg} = $argument;
100             }
101            
102 38         247 return $self->{_arg};
103             }
104              
105             # NETWORK METHODS ...... cgi and host etc. www. etc etc
106              
107             sub _network {
108 42     42   58 my $self = shift;
109              
110 42 100       107 unless (defined $self->{_data}->{_network}){
111              
112 5         18 my $data = { server_name => undef };
113              
114 5 50       49 if (defined $self->{SERVER_NAME}){
    50          
    50          
115 0         0 $data->{server_name} = $self->{SERVER_NAME};
116             }
117              
118             elsif (defined $ENV{SERVER_NAME}){
119 0         0 $data->{server_name} = $ENV{SERVER_NAME};
120             }
121              
122             elsif ($self->get_cgi->server_name) {
123 5         195 $data->{server_name} = $self->get_cgi->server_name;
124             }
125              
126 5 50       40 if ( $data->{server_name} ) { # we can get server name
127              
128 5 50       17 if ($self->get_cgi->https){
129 0         0 $data->{www} = 'https://'.$data->{server_name};
130             }
131             else {
132 5         471 $data->{www} = 'http://'.$data->{server_name};
133             }
134              
135             # how we see from the net
136 5         39 $data->{url} = $data->{www} .'/'.$self->rel_path;
137              
138             }
139            
140 5         92 $self->{_data}->{_network} = $data;
141             }
142            
143 42         158 return $self->{_data}->{_network};
144             }
145              
146             sub server_name {
147 0     0 0 0 my $self = shift;
148             #return $self->get_cgi->server_name;
149 0         0 return $self->_network->{server_name};
150             }
151              
152             sub url {
153 0     0 0 0 my $self = shift;
154 0         0 return $self->_network->{url};
155             }
156              
157             sub www {
158 0     0 0 0 my $self = shift;
159 0         0 return $self->_network->{www};
160             }
161              
162             sub get_cgi {
163 26     26 0 40 my $self = shift;
164 26   66     123 $self->{ cgi } ||= new CGI;
165 26         11666 return $self->{cgi};
166             }
167              
168              
169              
170              
171              
172              
173              
174              
175              
176              
177              
178              
179              
180              
181              
182              
183              
184              
185              
186              
187              
188             # test existancem, type, etc
189             # will attempt to default IF DOES NOT EXIST
190             sub _extended {
191 74     74   97 my $self = shift;
192              
193 74 50       171 croak($self->errstr) if $self->errstr;
194              
195 74 100       674 if (defined $self->{_data}->{_extended}){
196 65         225 return $self->{_data}->{_extended};
197             }
198              
199              
200 9         19 my $data = {};
201            
202              
203             # TODO: presently not doing anything for other file types, pipes, etc
204            
205 9 100       33 if ($self->is_dir){
    50          
206 2         32 $data->{filetype}='d';
207             }
208             elsif ($self->is_file){
209 7         98 $data->{filetype}='f';
210             }
211             else {
212 0         0 warn "filetype for $$data{abs_path} is not d or f, unsupported.";
213             }
214              
215 9 50       50 $data->{is_root} = ( $self->is_DOCUMENT_ROOT ? 1 : 0 );
216              
217 9 50       320 $data->{filename_pretty}= $self->filename_only or die('filename_only returns nothing?'.$self->abs_path);
218 9         111 $data->{filename_pretty}=~s/_/ /sg;
219 9         49 $data->{filename_pretty} = join '', map {ucfirst lc} split (/(?=\s)/, $data->{filename_pretty}); # http://perlmonks.org/?node_id=471292
  9         58  
220              
221 9         34 $data->{alt} = $data->{filename_pretty};
222 9         33 $data->{is_html} = $self->is_html;
223 9         144 $self->{_data}->{_extended} = $data;
224              
225 9         54 return $self->{_data}->{_extended};
226             }
227              
228             sub is_html {
229 11     11 0 716 my $self = shift;
230 11 100       44 $self->is_text or return 0;
231 6 100       978 $self->ext=~/s?html?$/i or return 0;
232 2         35 return 1;
233             }
234              
235             sub is_root {
236 8     8 0 2275 my $self = shift;
237 8         34 return $self->_extended->{is_root};
238             }
239              
240             sub filename_pretty {
241 0     0 0 0 my $self = shift;
242 0         0 return $self->_extended->{filename_prety};
243             }
244             sub alt {
245 0     0 1 0 my $self = shift;
246 0         0 return $self->_extended->{alt};
247             }
248              
249             sub filetype {
250 0     0 0 0 my $self = shift;
251            
252 0         0 return $self->_extended->{filetype};
253             }
254              
255              
256             # mime type etc, maybe should be in File::PathInfo.. ?? hmmmm
257             sub _more {
258 40     40   52 my $self = shift;
259            
260 40 50       114 croak($self->errstr) if $self->errstr;
261              
262 40 100       279 unless (defined $self->{_data}->{_extended_more} ){
263            
264 9         19 my $mime_type = undef;;
265 9 100       29 unless ($self->is_dir){
266 7         165 my $m = new File::MMagic;
267 7         4030 $mime_type = $m->checktype_filename( $self->abs_path );
268             }
269            
270              
271 9 100 100     105237 my $data = {
272             is_image => ( $self->is_file ? ( $mime_type=~m/image/ or 0 ) : 0 ),
273             mime_type => $mime_type,
274             };
275            
276 9         261 $self->{_data}->{_extended_more} = $data;
277             }
278              
279 40         194 return $self->{_data}->{_extended_more};
280             }
281              
282             sub is_image {
283 4     4 1 2121 my $self = shift;
284 4         21 return $self->_more->{is_image};
285             }
286              
287             sub mime_type {
288 6     6 1 3818 my $self = shift;
289 6         17 return $self->_more->{mime_type};
290             }
291              
292              
293              
294             # content and excerpt
295             sub _guts {
296 33     33   45 my $self = shift;
297              
298 33 50       100 croak($self->errstr) if $self->errstr;
299              
300 33 100       250 $self->is_text or return {}; # TODO: is this right?
301            
302            
303 31 100       29764 unless( defined $self->{_data}->{_guts} ){
304 4         11 my $guts = {};
305            
306 4         6 my $slurp;
307             {
308 4         9 local (*INPUT, $/);
  4         26  
309 4         35 open (INPUT, $self->abs_path);
310 4         507 $slurp = ;
311 4         83 close INPUT;
312             }
313 4         17 $guts->{content} = $slurp;
314 4   50     18 $guts->{content} ||= undef;
315              
316            
317 4 50       16 if( $guts->{content} ){
318              
319 4   50     28 $self->{excerpt_size} ||= 255;
320 4         12 my $limit = $self->{excerpt_size};
321            
322 4         14 $guts->{excerpt} = $guts->{content};
323 4         119 $guts->{excerpt}=~s/\<[^<>]+\>/ /sg; # take out html
324            
325 4         94 $guts->{excerpt}=~s/^(.{1,$limit}).+/$1\.\.\./s;
326            
327 4         30 $guts->{excerpt_encoded} = encode_entities($guts->{excerpt});
328            
329             }
330 4         111 $self->{_data}->{_guts} = $guts;
331            
332             }
333              
334 31         128 return $self->{_data}->{_guts};
335             }
336              
337             sub get_content {
338 1     1 1 3 my $self = shift;
339 1         8 return $self->_guts->{content};
340             }
341              
342             sub get_excerpt {
343 1     1 1 315 my $self = shift;
344 1         3 return $self->_guts->{excerpt};
345             }
346              
347             # made decision not to do this 'by default' with the whole content to be more frugal
348             sub get_content_encoded {
349 1     1 1 6 my $self = shift;
350 1         5 my $out = encode_entities( $self->_guts->{content} );
351 1         56 return $out;
352             }
353              
354             sub get_excerpt_encoded {
355 0     0 1 0 my $self = shift;
356 0         0 return $self->_guts->{excerpt_encoded};
357             }
358              
359              
360              
361              
362              
363              
364              
365              
366              
367              
368              
369              
370              
371             # LS METHODS
372              
373              
374             # must be loaded
375             sub _ls {
376 20     20   70 my $self = shift;
377 20 50 0     80 $self->is_dir or warn $self->abs_path ."is not a dir" and return {};
378            
379              
380 20 100       27458 unless ( defined $self->{_data}->{_ls} ){
381 4         10 my $data={};
382              
383 4 50       33 opendir(DIR, $self->abs_path)
384             or croak("$! - cant open dir ".$self->abs_path.", check permissions?");
385 4         481 my @ls = sort grep { !/^\.+$/ } readdir DIR;
  16         338  
386 4         77 closedir DIR;
387              
388            
389 4         13 my @lsd = grep { -d $self->abs_path."/$_" } @ls;
  8         225  
390 4         67 my @lsf = grep { -f $self->abs_path."/$_" } @ls;
  8         174  
391              
392 4         93 $data->{ls} = \@ls;
393 4         26 $data->{lsd} = \@lsd;
394 4         153 $data->{lsf} = \@lsf;
395            
396 4         18 $data->{ls_count} = scalar @ls;
397 4         17 $data->{lsd_count} = scalar @lsd;
398 4         17 $data->{lsf_count} = scalar @lsf;
399              
400 4         23 $self->{_data}->{_ls} = $data;
401             }
402              
403 20         121 return $self->{_data}->{_ls};
404             }
405              
406             sub ls {
407 5     5 1 15689 my $self = shift;
408 5         23 return $self->_ls->{ls};
409             }
410              
411             sub lsd {
412 4     4 1 8 my $self = shift;
413 4         13 return $self->_ls->{lsd};
414             }
415              
416             sub lsf {
417 4     4 1 8 my $self = shift;
418 4         14 return $self->_ls->{lsf};
419             }
420              
421             sub ls_count {
422 4     4 1 23 my $self = shift;
423 4         32 return $self->_ls->{ls_count};
424             }
425              
426             sub lsd_count {
427 1     1 1 574 my $self = shift;
428 1         4 return $self->_ls->{lsd_count};
429             }
430              
431             sub lsf_count {
432 2     2 1 4 my $self = shift;
433 2         5 return $self->_ls->{lsf_count};
434             }
435              
436             sub is_empty_dir {
437 11     11 1 53857 my $self = shift;
438 11 100       77 $self->is_dir or return;
439 3 100       72 $self->ls_count or return 1;
440 2         12 return 0;
441             }
442              
443              
444              
445              
446             # HTML::Template METHODS
447              
448             sub nav_prepped {
449 1     1 1 3 my $self = shift;
450              
451 1 50       7 unless ( defined $self->{_data}->{nav_loop} ){
452            
453 1         2 my $onetime=0;
454              
455 1         2 my @nav_loop=();
456              
457 1         3 my $r = $self; # start by self
458              
459            
460            
461 1         6 until ( $r->is_DOCUMENT_ROOT){
462            
463             # 1 step
464 1 50       39 my $element = {
465             rel_path => $r->rel_path,
466             abs_path => $r->abs_path,
467             rel_loc => $r->rel_loc,
468             abs_loc => $r->abs_loc,
469             filename => $r->filename,
470             filetype => ($r->is_dir ? 'd' : 'f' ),
471             ext => $r->ext,
472             };
473              
474             {
475 5     5   43 no warnings;
  5         9  
  5         6680  
  1         33  
476             # if we dont eliminate unset ones, HTML::Template will produce errors
477 1         3 for (keys %{$element}){
  1         5  
478 7 100       29 $element->{$_}=~/\w/ or delete $element->{$_};
479             }
480             };
481            
482 1 50       6 unless ($onetime) {
483 1         6 $element->{'last'} = 1;
484 1         3 $onetime=1;
485             } # indicate this is first element, i know
486             # it says last.. thing is we reeverse it for html template.. so that.. anyway.
487            
488 1         2 push @nav_loop, $element;
489 1         5 my $abs_next = $r->abs_loc;
490 1         14 $r = new File::PathInfo;
491 1         16 $r->set($abs_next);
492            
493            
494             }
495              
496             #### @nav_loop
497              
498 1         272 $self->{_data}->{nav_loop} = [ reverse @nav_loop ];
499             # TODO: I keep getting errors here when the array length is 0- errors from
500             # HTML Template
501              
502             }
503            
504            
505 1         7 return $self->{_data}->{nav_loop};
506             }
507              
508              
509              
510              
511              
512             sub lsd_prepped {
513 0     0 1 0 my $self = shift;
514 0 0       0 $self->is_dir or return;
515 0 0       0 if ( scalar @{$self->lsd} ){
  0         0  
516 0         0 my $prepped = [];
517              
518 0         0 for (@{$self->lsd}){
  0         0  
519 0         0 push @{$prepped}, {
  0         0  
520             filename => $_,
521             rel_path => $self->rel_path."/$_",
522             rel_loc => $self->rel_path,
523             abs_path =>$self->abs_path."/$_",
524             abs_loc => $self->abs_path,
525             filetype => 'd',
526             is_dir => 1,
527             is_file => 0,
528             is_root => 0,
529             };
530             }
531 0         0 return $prepped;
532             }
533 0         0 return [];
534             }
535              
536             sub lsf_prepped {
537 0     0 1 0 my $self = shift;
538 0 0       0 $self->is_dir or return;
539 0 0       0 if (scalar @{$self->lsf}){
  0         0  
540 0         0 my $prepped = [];
541              
542 0         0 for (@{$self->lsf}){
  0         0  
543 0         0 push @{$prepped}, {
  0         0  
544             filename => $_,
545             rel_path => $self->rel_path."/$_",
546             rel_loc => $self->rel_path,
547             abs_path =>$self->abs_path."/$_",
548             abs_loc => $self->abs_path,
549             filetype => 'f',
550             is_dir => 0,
551             is_file => 1,
552             is_root => 0,
553             };
554             }
555 0         0 return $prepped;
556             }
557 0         0 return [];
558             }
559              
560             sub ls_prepped {
561 0     0 1 0 my $self = shift;
562 0 0       0 $self->is_dir or return;
563              
564 0 0       0 if (scalar @{$self->ls}){
  0         0  
565 0         0 my $prepped = [];
566 0         0 push @{$prepped}, @{$self->lsd_prepped};
  0         0  
  0         0  
567 0         0 push @{$prepped}, @{$self->lsf_prepped};
  0         0  
  0         0  
568 0         0 return $prepped;
569             }
570              
571 0         0 return [];
572             }
573              
574              
575             ## ALL DATA METHODS
576              
577             sub get_datahash_prepped {
578 5     5 1 2188 my $self = shift;
579 5         25 my $data = $self->get_datahash;
580 5         10 my $prepped;
581 5         11 for (keys %{$data}) {
  5         66  
582 224 50       441 if(ref $data->{$_} ){ next;}
  0         0  
583 224 100       387 defined $data->{$_} or next;
584 219 100       671 $data->{$_}=~/\w/ or next;
585 215         461 $prepped->{$_} = $data->{$_};
586             }
587              
588 5         168 return $prepped;
589             }
590            
591              
592              
593             # WHOLE HASH
594            
595             sub get_datahash{
596 6     6 1 92 my $self = shift;
597              
598 6         57 my $data = $self->SUPER::get_datahash;
599            
600 6         97 for (keys %{$self->_network}){
  6         28  
601 18 50       36 if (defined $self->_network->{$_}){
602 18         37 $data->{$_} = $self->_network->{$_};
603             }
604             }
605            
606 6         12 for (keys %{$self->_guts}){
  6         24  
607 12 50       30 if (defined $self->_guts->{$_}){
608 12         24 $data->{$_} = $self->_guts->{$_};
609             }
610             }
611              
612 6         40 for (keys %{$self->_extended}){
  6         22  
613 30 50       52 if (defined $self->_extended->{$_}){
614 30         57 $data->{$_} = $self->_extended->{$_};
615             }
616             }
617              
618 6         15 for (keys %{$self->_more}){
  6         23  
619 12 50       28 if (defined $self->_more->{$_}){
620 12         28 $data->{$_} = $self->_more->{$_};
621             }
622             }
623              
624 6         29 return $data;
625             }
626              
627              
628              
629              
630             sub elements {
631 0     0 1 0 my $self = shift;
632 0         0 my @elements = sort keys %{$self->get_datahash};
  0         0  
633 0         0 return \@elements;
634             }
635              
636              
637              
638              
639              
640              
641              
642              
643              
644              
645              
646              
647             # obscure way of getting pathrequest from cgi...
648             sub _get_rel_path_from_cgi {
649 6     6   11 my $self = shift;
650              
651 6 100       22 my $req = $self->get_cgi->param($self->{param_name}) or return;
652              
653 5         114 my $wasfullurl = 0;
654 5 50       32 if ($req=~s/^https\:\/\/|^http\:\/\///){
655 0         0 $wasfullurl++;
656             }
657 5 50       16 if ($req=~s/^www\.//){
658 0         0 $wasfullurl++;
659             }
660            
661 5 50       15 if (my $server = $self->get_cgi->server_name){
662 5         61 $req=~s/^$server//;
663             }
664            
665 5 50 33     18 if ($wasfullurl and !$req){
666 0         0 return '/';
667             }
668            
669 5 50       11 $req or return;
670 5         18 return $req;
671             }
672              
673              
674              
675            
676             1;
677