|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # vim:ts=8:sw=2:et:sta:sts=2  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #########  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Author: rmp  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Created: 2007-03-28  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # method id action  aspect  result CRUD  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # =====================================  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # POST   n  create  -       create    *  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # POST   y  create  update  update    *  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # POST   y  create  delete  delete    *  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # GET    n  read    -       list  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # GET    n  read    add     add/new  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # GET    y  read    -       read      *  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # GET    y  read    edit    edit  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package ClearPress::controller;  | 
| 
18
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
38231
 | 
 use strict;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
    | 
| 
19
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
26
 | 
 use warnings;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
    | 
| 
20
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
26
 | 
 use English qw(-no_match_vars);  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
21
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
1719
 | 
 use Carp;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
280
 | 
    | 
| 
22
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
1417
 | 
 use ClearPress::decorator;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
    | 
| 
23
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
1403
 | 
 use ClearPress::view::error;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
24
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
157
 | 
 use CGI;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
25
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
276
 | 
 use HTTP::Status qw(:constants :is);  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1728
 | 
    | 
| 
26
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
35
 | 
 use HTTP::Headers;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16290
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = q[477.1.4];  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $CRUD    = { # these map HTTP verbs to $action  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		POST    => 'create',  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		GET     => 'read',  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		PUT     => 'update',  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		DELETE  => 'delete',  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 OPTIONS => 'options',  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 HEAD    => 'null',  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 TRACE   => 'null',  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       };  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $REST   = { # these assist sanitising $aspect  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       create  => 'POST',  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       read    => 'GET',  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       update  => 'PUT|POST',  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       delete  => 'DELETE|POST',  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       add     => 'GET',  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       edit    => 'GET',  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       list    => 'GET',  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                options => 'OPTIONS',  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                null    => 'HEAD|TRACE'  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      };  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub accept_extensions {  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return [  | 
| 
53
 | 
238
 | 
 
 | 
 
 | 
  
238
  
 | 
  
1
  
 | 
4980
 | 
 	  {'.html' => q[]},  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.xml'  => q[_xml]},  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.png'  => q[_png]},  | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.svg'  => q[_svg]},  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.svgz' => q[_svgz]},  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.jpg'  => q[_jpg]},  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.rss'  => q[_rss]},  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.atom' => q[_atom]},  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.js'   => q[_json]},  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.json' => q[_json]},  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.ical' => q[_ical]},  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.txt'  => q[_txt]},  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.xls'  => q[_xls]},  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.csv'  => q[_csv]},  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'.ajax' => q[_ajax]},  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 ];  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub accept_headers {  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return [  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	  {'text/html'        => q[]},  | 
| 
74
 | 
119
 | 
 
 | 
 
 | 
  
119
  
 | 
  
1
  
 | 
773
 | 
 	  {'application/json' => q[_json]},  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {'text/xml'         => q[_xml]},  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 ];  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
80
 | 
119
 | 
 
 | 
 
 | 
  
119
  
 | 
  
1
  
 | 
91538
 | 
   my ($class, $self) = @_;  | 
| 
81
 | 
119
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
612
 | 
   $self ||= {};  | 
| 
82
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
345
 | 
   bless $self, $class;  | 
| 
83
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
443
 | 
   $self->init();  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # We may be given a database handle from the cache with an open  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # transaction (e.g. from running a few selects), so on controller  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # construction (effectively per-page-view), we rollback any open  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # transaction on the database handle we've been given.  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
92
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
466
 | 
     $self->util->dbh->rollback();  | 
| 
93
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
685
 | 
     1;  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
95
 | 
119
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
260
 | 
   } or do {  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # ignore any error  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
99
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     carp qq[Failed per-request rollback on fresh database handle: $EVAL_ERROR];  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
102
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
426
 | 
   return $self;  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub init {  | 
| 
106
 | 
119
 | 
 
 | 
 
 | 
  
119
  
 | 
  
1
  
 | 
239
 | 
   return 1;  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub util {  | 
| 
110
 | 
254
 | 
 
 | 
 
 | 
  
254
  
 | 
  
1
  
 | 
571
 | 
   my ($self, $util) = @_;  | 
| 
111
 | 
254
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
692
 | 
   if(defined $util) {  | 
| 
112
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{util} = $util;  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
114
 | 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1108
 | 
   return $self->{util};  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub packagespace {  | 
| 
118
 | 
149
 | 
 
 | 
 
 | 
  
149
  
 | 
  
1
  
 | 
492
 | 
   my ($self, $type, $entity, $util) = @_;  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
149
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
562
 | 
   if($type ne 'view' &&  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      $type ne 'model') {  | 
| 
122
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
149
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
414
 | 
   $util         ||= $self->util();  | 
| 
126
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
295
 | 
   my $entity_name = $entity;  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
149
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
607
 | 
   if($util->config->SectionExists('packagemap')) {  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # if there are uri-to-package maps, process here  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
132
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4081
 | 
     my $map = $util->config->val('packagemap', $entity);  | 
| 
133
 | 
149
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
4916
 | 
     if($map) {  | 
| 
134
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       $entity = $map;  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
138
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
512
 | 
   my $namespace = $self->namespace($util);  | 
| 
139
 | 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
642
 | 
   return "${namespace}::${type}::$entity";  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub process_request { ## no critic (Subroutines::ProhibitExcessComplexity)  | 
| 
143
 | 
119
 | 
 
 | 
 
 | 
  
119
  
 | 
  
1
  
 | 
2087
 | 
   my ($self, $headers) = @_;  | 
| 
144
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
308
 | 
   my $util          = $self->util;  | 
| 
145
 | 
119
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
504
 | 
   my $method        = $ENV{REQUEST_METHOD} || 'GET';  | 
| 
146
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
492
 | 
   my $action        = $CRUD->{uc $method};  | 
| 
147
 | 
119
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
435
 | 
   my $pi            = $ENV{PATH_INFO}      || q[];  | 
| 
148
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
580
 | 
   my $accept        = $ENV{HTTP_ACCEPT}    || q[];  | 
| 
149
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
502
 | 
   my $qs            = $ENV{QUERY_STRING}   || q[];  | 
| 
150
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
475
 | 
   my $hxrw          = $ENV{HTTP_X_REQUESTED_WITH} || q[];  | 
| 
151
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
377
 | 
   my $xhr           = ($hxrw =~ /XMLHttpRequest/smix);  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $accept_extensions = join q[|],  | 
| 
154
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4252
 | 
                           grep { defined }  | 
| 
155
 | 
1785
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5714
 | 
                           map  { m{[.](\S+)$}smx; $1 || undef; } ## no critic (ProhibitCaptureWithoutTest, ProhibitComplexMappings)  | 
| 
 
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7050
 | 
    | 
| 
156
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4179
 | 
                           map  { join q[,], keys %{$_} }  | 
| 
 
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7228
 | 
    | 
| 
157
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
255
 | 
                           @{$self->accept_extensions()};  | 
| 
 
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
365
 | 
    | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
119
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1706
 | 
   if($xhr && $pi !~ m{(?:$accept_extensions)(?:/[^/]*?)?$}smx) {  | 
| 
160
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     if($pi =~ /[;]/smx) {  | 
| 
161
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       $pi .= q[_ajax];  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
163
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
       $pi .= q[.ajax];  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
167
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
761
 | 
   my ($entity)      = $pi =~ m{^/([^/;.]+)}smx;  | 
| 
168
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
458
 | 
   $entity         ||= q[];  | 
| 
169
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4051
 | 
   my ($dummy, $aspect_extra, $id) = $pi =~ m{^/$entity(/(.*))?/([[:lower:][:digit:]:,\-_%@.+\s]+)}smix;  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
786
 | 
   my ($aspect)      = $pi =~ m{;(\S+)}smx;  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
173
 | 
119
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
679
 | 
   if($action eq 'read' && !$id && !$aspect) {  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     $aspect = 'list';  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
119
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
657
 | 
   if($action eq 'create' && $id) {  | 
| 
178
 | 
28
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
166
 | 
     if(!$aspect || $aspect =~ /^update/smx) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
       $action = 'update';  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif($aspect =~ /^delete/smx) {  | 
| 
182
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       $action = 'delete';  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
186
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
505
 | 
   $aspect ||= q[];  | 
| 
187
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
555
 | 
   $aspect_extra ||= q[];  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # process request extensions  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
192
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
546
 | 
   my $uriaspect = $self->_process_request_extensions(\$pi, $aspect, $action) || q[];  | 
| 
193
 | 
119
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
409
 | 
   if($uriaspect ne $aspect) {  | 
| 
194
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
130
 | 
     $aspect = $uriaspect;  | 
| 
195
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3162
 | 
     ($id)   = $pi =~ m{^/$entity/?$aspect_extra/([[:lower:][:digit:]:,\-_%@.+\s]+)}smix;  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # process HTTP 'Accept' header  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
201
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
564
 | 
   $aspect   = $self->_process_request_headers(\$accept, $aspect, $action);  | 
| 
202
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
444
 | 
   $entity ||= $util->config->val('application', 'default_view');  | 
| 
203
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
572
 | 
   $aspect ||= q[];  | 
| 
204
 | 
119
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
992
 | 
   $id       = CGI->unescape($id||'0');  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # no view determined and no configured default_view  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # pull the first one off the list  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
210
 | 
119
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3220
 | 
   if(!$entity) {  | 
| 
211
 | 
2
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
10
 | 
     my $views = $util->config->val('application', 'views') || q[];  | 
| 
212
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     $entity   = (split /[\s,]+/smx, $views)[0];  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # no view determined, no default_view and none in the list  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
218
 | 
119
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
341
 | 
   if(!$entity) {  | 
| 
219
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
159
 | 
     croak q[No available views];  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
417
 | 
   my $viewclass = $self->packagespace('view', $entity, $util);  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
118
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
385
 | 
   if($aspect_extra) {  | 
| 
225
 | 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
     $aspect_extra =~ s{/}{_}smxg;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
228
 | 
118
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
815
 | 
   if($id eq '0') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # no primary key:  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing;method  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing;method_xml  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing.xml;method  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
235
 | 
34
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
119
 | 
     my $tmp = $aspect || $action;  | 
| 
236
 | 
34
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
108
 | 
     if($aspect_extra) {  | 
| 
237
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $tmp =~ s/_/_${aspect_extra}_/smx;  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
239
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if($viewclass->can($tmp)) {  | 
| 
240
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$aspect = $tmp;  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif($id !~ /^\d+$/smx) {  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # mangled primary key - attempt to match method in view object  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing/method          => list_thing_method (if exists), or read(pk=method)  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing/part1/part2     => list_thing_part1_part2 if exists, or read_thing_part1(pk=part2)  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing/method.xml      => list_thing_method_xml (if exists), or read_thing_xml (pk=method)  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing/part1/part2.xml => list_thing_part1_part2_xml (if exists), or read_thing_part1_xml (pk=part2)  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
253
 | 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
     my $tmp = $aspect;  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
35
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
111
 | 
     if($tmp =~ /_/smx) {  | 
| 
256
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
169
 | 
       $tmp =~ s/_/_${id}_/smx;  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
259
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
       $tmp = "${action}_$id";  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
172
 | 
     $tmp =~ s/^read/list/smx;  | 
| 
264
 | 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
     $tmp =~ s/^update/create/smx;  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
266
 | 
35
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
111
 | 
     if($aspect_extra) {  | 
| 
267
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
       $tmp =~ s/_/_${aspect_extra}_/smx;  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
270
 | 
35
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
532
 | 
     if($viewclass->can($tmp)) {  | 
| 
271
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
       $id     = 0;  | 
| 
272
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
       $aspect = $tmp;  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #########  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # id has been modified, so reset action  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #  | 
| 
277
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
       if($aspect =~ /^create/smx) {  | 
| 
278
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	$action = 'create';  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
282
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
58
 | 
       if($aspect_extra) {  | 
| 
283
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
 	if($aspect =~ /_/smx) {  | 
| 
284
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
 	  $aspect =~ s/_/_${aspect_extra}_/smx;  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
286
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
 	  $aspect .= "_$aspect_extra";  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif($aspect_extra) {  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # /thing/method/50       => read_thing_method(pk=50)  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
295
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
114
 | 
     if($aspect =~ /_/smx) {  | 
| 
296
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
       $aspect =~ s/_/_${aspect_extra}_/smx;  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
298
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
       $aspect .= "${action}_$aspect_extra";  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # fix up aspect  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
305
 | 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1515
 | 
   my ($firstpart) = $aspect =~ /^${action}_([^_]+)_?/smx;  | 
| 
306
 | 
118
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
384
 | 
   if($firstpart) {  | 
| 
307
 | 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
189
 | 
     my $restpart = $REST->{$firstpart};  | 
| 
308
 | 
57
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
173
 | 
     if($restpart) {  | 
| 
309
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
       ($restpart) = $restpart =~ /^([^|]+)/smx;  | 
| 
310
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
       if($restpart) {  | 
| 
311
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
 	my ($crudpart) = $CRUD->{$restpart};  | 
| 
312
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
 	if($crudpart) {  | 
| 
313
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
 	  $aspect =~ s/^${crudpart}_//smx;  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
118
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
653
 | 
   if($aspect !~ /^(?:create|read|update|delete|add|list|edit|options)/smx) {  | 
| 
320
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     my $action_extended = $action;  | 
| 
321
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
86
 | 
     if(!$id) {  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $action_extended = {  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			  read => 'list',  | 
| 
324
 | 
8
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
75
 | 
 			 }->{$action} || $action_extended;  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
23
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
107
 | 
     $aspect = $action_extended . ($aspect?"_$aspect":q[]);  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  if($method eq 'OPTIONS') {  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    $action = 'options';  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    $aspect = 'options';  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  }  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # sanity checks  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
338
 | 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
578
 | 
   my ($type) = $aspect =~ /^([^_]+)/smx; # read|list|add|edit|create|update|delete  | 
| 
339
 | 
118
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1269
 | 
   if($method !~ /^$REST->{$type}$/smx) {  | 
| 
340
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     $headers->header('Status', HTTP_BAD_REQUEST);  | 
| 
341
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
412
 | 
     croak qq[Bad request. $aspect ($type) is not a $CRUD->{$method} method];  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
344
 | 
115
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
591
 | 
   if(!$id &&  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      $aspect =~ /^(?:delete|update|edit|read)/smx) {  | 
| 
346
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     $headers->header('Status', HTTP_BAD_REQUEST);  | 
| 
347
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
622
 | 
     croak qq[Bad request. Cannot $aspect without an id];  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
111
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
541
 | 
   if($id &&  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      $aspect =~ /^(?:create|add|list)/smx) {  | 
| 
352
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $headers->header('Status', HTTP_BAD_REQUEST);  | 
| 
353
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
354
 | 
     croak qq[Bad request. Cannot $aspect with an id];  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
356
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
370
 | 
   $aspect =~ s/__/_/smxg;  | 
| 
357
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
963
 | 
   return ($action, $entity, $aspect, $id);  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _process_request_extensions {  | 
| 
361
 | 
119
 | 
 
 | 
 
 | 
  
119
  
 | 
 
 | 
445
 | 
   my ($self, $pi, $aspect, $action) = @_;  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
363
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
241
 | 
   my $extensions = join q[], reverse ${$pi} =~ m{([.][^;.]+)}smxg;  | 
| 
 
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
679
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
365
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
297
 | 
   for my $pair (@{$self->accept_extensions}) {  | 
| 
 
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
318
 | 
    | 
| 
366
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3733
 | 
     my ($ext, $meth) = %{$pair};  | 
| 
 
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6216
 | 
    | 
| 
367
 | 
1785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6618
 | 
     $ext =~ s/[.]/\\./smxg;  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
1785
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19455
 | 
     if($extensions =~ s{$ext$}{}smx) {  | 
| 
370
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
       ${$pi}    =~ s{$ext}{}smx;  | 
| 
 
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
598
 | 
    | 
| 
371
 | 
53
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
399
 | 
       $aspect ||= $action;  | 
| 
372
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
366
 | 
       $aspect   =~ s/$meth$//smx;  | 
| 
373
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
240
 | 
       $aspect  .= $meth;  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
377
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1438
 | 
   return $aspect;  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _process_request_headers {  | 
| 
381
 | 
119
 | 
 
 | 
 
 | 
  
119
  
 | 
 
 | 
392
 | 
   my ($self, $accept, $aspect, $action) = @_;  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
383
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
223
 | 
   for my $pair (@{$self->accept_headers()}) {  | 
| 
 
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
459
 | 
    | 
| 
384
 | 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
521
 | 
     my ($header, $meth) = %{$pair};  | 
| 
 
 | 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
817
 | 
    | 
| 
385
 | 
238
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
501
 | 
     if(${$accept} =~ /$header$/smx) {  | 
| 
 
 | 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3446
 | 
    | 
| 
386
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
4
 | 
       $aspect ||= $action;  | 
| 
387
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       $aspect  =~ s/$meth$//smx;  | 
| 
388
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       $aspect .= $meth;  | 
| 
389
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       last;  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
393
 | 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
632
 | 
   return $aspect;  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub decorator {  | 
| 
397
 | 
46
 | 
 
 | 
 
 | 
  
46
  
 | 
  
1
  
 | 
149
 | 
   my ($self, $util, $headers) = @_;  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
399
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
178
 | 
   if(!$self->{decorator}) {  | 
| 
400
 | 
15
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
91
 | 
     my $appname   = $util->config->val('application', 'name') || 'Application';  | 
| 
401
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
778
 | 
     my $namespace = $self->namespace;  | 
| 
402
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
     my $decorpkg  = "${namespace}::decorator";  | 
| 
403
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
     my $config    = $util->config;  | 
| 
404
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     my $decor;  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
406
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
     my $ref = {  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                headers => $headers,  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               };  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     eval {  | 
| 
410
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
431
 | 
       $decor = $decorpkg->new($ref);  | 
| 
411
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       1;  | 
| 
412
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
49
 | 
     } or do {  | 
| 
413
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
154
 | 
       $decor = ClearPress::decorator->new($ref);  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
416
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
     for my $field ($decor->fields) {  | 
| 
417
 | 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
936
 | 
       $decor->$field($config->val('application', $field));  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
420
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
109
 | 
     if(!$decor->title) {  | 
| 
421
 | 
15
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
81
 | 
       $decor->title($config->val('application', 'name') || 'ClearPress Application');  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # only cache decorator when $headers is passed  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
427
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
827
 | 
     if($headers) {  | 
| 
428
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
70
 | 
       $self->{decorator} = $decor;  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
432
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
372
 | 
   return $self->{decorator};  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub session {  | 
| 
436
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
  
1
  
 | 
54
 | 
   my ($self, $util) = @_;  | 
| 
437
 | 
15
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
92
 | 
   return $self->decorator($util || $self->util())->session() || {};  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub handler {  | 
| 
441
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
  
1
  
 | 
4518
 | 
   my ($self, $util) = @_;  | 
| 
442
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
82
 | 
   if(!ref $self) {  | 
| 
443
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
     $self = $self->new({util => $util});  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
446
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
158
 | 
   my $headers   = HTTP::Headers->new();  | 
| 
447
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
238
 | 
   my $cgi       = $util->cgi();  | 
| 
448
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89
 | 
   my $decorator = $self->decorator($util, $headers);  | 
| 
449
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
   my $namespace = $self->namespace($util);  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
451
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
115
 | 
   $headers->header('Status', HTTP_OK);  | 
| 
452
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1625
 | 
   $headers->header('X-Generator', 'ClearPress');  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # no obvious right place for this  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
457
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1104
 | 
   my $lang = $decorator->lang;  | 
| 
458
 | 
15
 | 
  
 50
  
 | 
  
 50
  
 | 
 
 | 
 
 | 
98
 | 
   if($lang && scalar @{$lang}) {  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
81
 | 
    | 
| 
459
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     $headers->header('Content-Language', join q[,], @{$lang});  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
    | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
462
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
943
 | 
   my ($action, $entity, $aspect, $id, $process_request_error);  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
464
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
     ($action, $entity, $aspect, $id) = $self->process_request($headers);  | 
| 
465
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
     1;  | 
| 
466
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   } or do {  | 
| 
467
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     carp qq[CAUGHT $EVAL_ERROR];  | 
| 
468
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $process_request_error = $EVAL_ERROR;  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
471
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
   my $params = {  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 util    => $util,  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 entity  => $entity,  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 aspect  => $aspect,  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 action  => $action,  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 id      => $id,  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 headers => $headers,  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                };  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # initial header block  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
482
 | 
15
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
249
 | 
   $headers->header('Content-Type', ClearPress::view->new($params)->content_type || 'text/html'); # don't forget to add charset  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
484
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1318
 | 
   for my $cookie ($decorator->cookie) {  | 
| 
485
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{headers}->push_header('Set-Cookie', $_);  | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
488
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
   if($process_request_error) {  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # deferred error handling  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
492
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $self->handle_error($process_request_error, $headers);  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
495
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
   $util->username($decorator->username());  | 
| 
496
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
300
 | 
   $util->session($self->session($util));  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
498
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
203
 | 
   my $viewobject;  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
500
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
84
 | 
     $viewobject = $self->dispatch($params);  | 
| 
501
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
     1;  | 
| 
502
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
   } or do {  | 
| 
503
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $self->handle_error($EVAL_ERROR, $headers);  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
506
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108
 | 
   my $decor = $viewobject->decor(); # boolean  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # let the view have the decorator in case it wants to modify headers  | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
511
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
116
 | 
   $viewobject->decorator($decorator);  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
513
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
286
 | 
   my $charset      = $viewobject->charset();  | 
| 
514
 | 
15
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
301
 | 
   $charset         = ($charset && !exists $ENV{REDIRECT_STATUS}) ? qq[;charset=$charset] : q[];  | 
| 
515
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
   my $content_type = sprintf q[%s%s], $viewobject->content_type(), $charset;  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # update the content-type/charset with whatever the view determined was right for the response  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
520
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
283
 | 
   $headers->header('Content-Type', $content_type);  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
943
 | 
   if($decor) {  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    if($content_type =~ /text/smx && $charset =~ /utf-?8/smix) {  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #      binmode STDOUT, q[:encoding(UTF-8)]; # is this useful? If so, should it be less conditional?  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    }  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # decorated header  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
530
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     $viewobject->output_buffer($decorator->header());  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
533
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   my $errstr;  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # view->render() may be streamed  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
538
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
97
 | 
     if($viewobject->streamed) {  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #########  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # ->render is responsible for all (decorated/undecorated) output  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #  | 
| 
542
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       $viewobject->render();  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #########  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # output returned content  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       #  | 
| 
548
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
90
 | 
       $viewobject->output_buffer($viewobject->render());  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
551
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     1;  | 
| 
552
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   } or do {  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #########  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 1. reset pending output_buffer (different view object)  | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 2. set up error response w/headers  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 3. emit headers  | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 4. hand off to error response handler  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
559
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
173
 | 
     carp qq[controller::handler: view->render failed: $EVAL_ERROR];  | 
| 
560
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
     $viewobject->output_reset(); # reset headers on the original view  | 
| 
561
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     $self->errstr($EVAL_ERROR);  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
563
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $code = $headers->header('Status');  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
565
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
91
 | 
     if(!$code || $code == HTTP_OK) {  | 
| 
566
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
       $headers->header('Status', HTTP_INTERNAL_SERVER_ERROR);  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    my $content_type = $headers->header('Content-Type');  | 
| 
570
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
     $content_type =~ s{;.*$}{}smx;  | 
| 
571
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     $headers->header('Content-Type', $content_type); # ErrorDocuments seem to have a bit of trouble with content-encoding errors so strip the charset  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
573
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
     return $self->handle_error(undef, $headers); # hand off  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # prepend all response headers (and header block termination)  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
579
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
   $viewobject->output_prepend($headers->as_string, "\n");  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # re-test decor in case it's changed by render()  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
584
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
   if($viewobject->decor()) {  | 
| 
585
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     $viewobject->output_buffer($decorator->footer());  | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # flush everything left to client socket (via stdout)  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
591
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
116
 | 
   $viewobject->output_end();  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # save the session after the request has processed  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
596
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
   $decorator->save_session();  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # clean up any shared state so it's not carried over (e.g. incomplete transactions)  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
601
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
   $util->cleanup();  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
880
 | 
   return 1;  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub handle_error {  | 
| 
607
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
6
 | 
   my ($self, $errstr, $headers) = @_;  | 
| 
608
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   my $util      = $self->util;  | 
| 
609
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   my $decorator = $self->decorator();  | 
| 
610
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   my $namespace = $self->namespace();  | 
| 
611
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   my ($action, $entity, $aspect, $id) = $self->process_request($headers);  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # if running in mod_perl, main request serves a bad status header and errordocument is handled by a subrequest  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # if running in CGI, main request serves a bad status header and follows with errordocument content  | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # force reconstruction of CGI object from subrequest QUERY_STRING  | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
619
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   delete $util->{cgi};  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # but pass-through the errstr  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
624
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
8
 | 
   $util->cgi->param('errstr', CGI::escape($errstr || $self->errstr));  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #########  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # non-mod-perl errordocument handled by application internals  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
629
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
   my $error_ns = sprintf q[%s::view::error], $namespace;  | 
| 
630
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   my $params   = {  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   util      => $util,  | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   action    => $action,  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   aspect    => $aspect,  | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   headers   => $headers, # same header block as original response? hmm.  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   decorator => $decorator,  | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  };  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
638
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   my $viewobject;  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
640
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     $viewobject = $error_ns->new($params);  | 
| 
641
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     1;  | 
| 
642
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   } or do {  | 
| 
643
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $viewobject = ClearPress::view::error->new($params);  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
646
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
   my $decor  = $viewobject->decor();  | 
| 
647
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   my $header = q[];  | 
| 
648
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   my $footer = q[];  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
650
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
   $viewobject->output_reset();  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
652
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
   my $body = $viewobject->render;  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
654
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   if($viewobject->decor) {  | 
| 
655
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $header = $decorator->header;  | 
| 
656
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $footer = $decorator->footer;  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
659
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   my $str = $header . $body . $footer;  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   $viewobject->output_prepend($headers->as_string, "\n");  | 
| 
662
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   $viewobject->output_buffer($str);  | 
| 
663
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   $viewobject->output_end();  | 
| 
664
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   $decorator->save_session();  | 
| 
665
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
   $util->cleanup();  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
667
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
   return;  | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub namespace {  | 
| 
671
 | 
180
 | 
 
 | 
 
 | 
  
180
  
 | 
  
1
  
 | 
434
 | 
   my ($self, $util) = @_;  | 
| 
672
 | 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
376
 | 
   my $ns   = q[];  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
674
 | 
180
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1219
 | 
   if((ref $self && !$self->{namespace}) || !ref $self) {  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
675
 | 
118
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
444
 | 
     $util ||= $self->util();  | 
| 
676
 | 
118
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
350
 | 
     $ns = $util->config->val('application', 'namespace') ||  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           $util->config->val('application', 'name') ||  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  'ClearPress';  | 
| 
679
 | 
118
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4268
 | 
     if(ref $self) {  | 
| 
680
 | 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
415
 | 
       $self->{namespace} = $ns;  | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
683
 | 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
162
 | 
     $ns = $self->{namespace};  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
686
 | 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
571
 | 
   return $ns;  | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub is_valid_view {  | 
| 
690
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
  
1
  
 | 
48
 | 
   my ($self, $ref, $viewname) = @_;  | 
| 
691
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
   my $util     = $ref->{util};  | 
| 
692
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
   my @entities = split /[,\s]+/smx, $util->config->val('application','views');  | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
694
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
716
 | 
   for my $ent (@entities) {  | 
| 
695
 | 
57
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
177
 | 
     if($ent eq $viewname) {  | 
| 
696
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
       return 1;  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
700
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return;  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub errstr {  | 
| 
704
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
9
 | 
   my ($self, $str) = @_;  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
706
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
   if($str) {  | 
| 
707
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{errstr} = $str;  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
710
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
   return $self->{errstr};  | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub dispatch {  | 
| 
714
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
  
1
  
 | 
50
 | 
   my ($self, $ref) = @_;  | 
| 
715
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   my $util      = $ref->{util};  | 
| 
716
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   my $entity    = $ref->{entity};  | 
| 
717
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   my $aspect    = $ref->{aspect};  | 
| 
718
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   my $action    = $ref->{action};  | 
| 
719
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
   my $id        = $ref->{id};  | 
| 
720
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
   my $headers   = $ref->{headers};  | 
| 
721
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
   my $viewobject;  | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
723
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
   my $state = $self->is_valid_view($ref, $entity);  | 
| 
724
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
60
 | 
   if(!$state) {  | 
| 
725
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $headers->header('Status', HTTP_NOT_FOUND);  | 
| 
726
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak qq[No such view ($entity). Is it in your config.ini?];  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
729
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
   my $entity_name = $entity;  | 
| 
730
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
   my $viewclass   = $self->packagespace('view',  $entity, $util);  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
732
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
   my $modelobject;  | 
| 
733
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
69
 | 
   if($entity ne 'error') {  | 
| 
734
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
     my $modelclass = $self->packagespace('model', $entity, $util);  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     eval {  | 
| 
736
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
219
 | 
       my $modelpk  = $modelclass->primary_key();  | 
| 
737
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
238
 | 
       $modelobject = $modelclass->new({  | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                        util => $util,  | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                        $modelpk?($modelpk => $id):(),  | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                       });  | 
| 
741
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
       1;  | 
| 
742
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     } or do {  | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # bail out  | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
745
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $code = $headers->header('Status');  | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
747
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
       if(!$code || $code == HTTP_OK) {  | 
| 
748
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $headers->header('Status', HTTP_INTERNAL_SERVER_ERROR);  | 
| 
749
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         croak qq[Failed to instantiate $entity model: $EVAL_ERROR];  | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
752
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak $EVAL_ERROR;  | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
756
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   eval {  | 
| 
757
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
     $viewobject = $viewclass->new({  | 
| 
758
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    util        => $util,  | 
| 
759
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    model       => $modelobject,  | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    action      => $action,  | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    aspect      => $aspect,  | 
| 
762
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    entity_name => $entity_name,  | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    decorator   => $self->decorator,  | 
| 
764
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                    headers     => $headers,  | 
| 
765
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                   });  | 
| 
766
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
77
 | 
     1;  | 
| 
767
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
   } or do {  | 
| 
768
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $code = $headers->header('Status');  | 
| 
769
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
770
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if(!$code || $code == HTTP_OK) {  | 
| 
771
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $headers->header('Status', HTTP_INTERNAL_SERVER_ERROR);  | 
| 
772
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       croak qq[Failed to instantiate $entity view: $EVAL_ERROR];  | 
| 
773
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
774
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
775
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     croak $EVAL_ERROR;  | 
| 
776
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
777
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
778
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
   return $viewobject;  | 
| 
779
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
780
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
781
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
782
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |