File Coverage

blib/lib/MojoMojo/Controller/Jsrpc.pm
Criterion Covered Total %
statement 60 133 45.1
branch 6 38 15.7
condition 3 12 25.0
subroutine 17 25 68.0
pod 10 10 100.0
total 96 218 44.0


line stmt bran cond sub pod time code
1             package MojoMojo::Controller::Jsrpc;
2              
3 35     35   18406 use strict;
  35         99  
  35         1105  
4 35     35   180 use parent 'Catalyst::Controller';
  35         73  
  35         596  
5 35     35   2275 use HTML::Entities;
  35         78  
  35         6388  
6              
7             =head1 NAME
8              
9             MojoMojo::Controller::Jsrpc - Various JSRPC functions.
10              
11             =head1 SYNOPSIS
12              
13             This is the Mojo powering our AJAX features.
14              
15             =head1 DESCRIPTION
16              
17             This controller dispatches various data to ajax methods in mojomojo
18             These methods will be called indirectly through javascript functions.
19              
20             =head1 ACTIONS
21              
22             =head2 render ( /.jsrpc/render )
23              
24             Edit uses this to get live preview. It gets some content in
25             params->{content} and runs it through the formatter chain.
26              
27             =cut
28              
29             sub render : Local {
30 68     68   73253 my ( $self, $c ) = @_;
31 68         478 my $output = $c->loc("Please type something");
32 68         26011 my $input = $c->req->params->{content};
33 68 100 66     6406 if ( $input && $input =~ /(\S+)/ ) {
34 66         339 $output = $c->model("DBIC::Content")->format_content( $c, $input );
35             }
36              
37 68 50       316 unless ($output) {
38 0         0 $output = $c->loc('Your input is invalid, please reformat it and try again.');
39 0         0 $c->res->status(500);
40             }
41              
42 68         1616 $c->res->output($output);
43 35     35   235 }
  35         4034  
  35         208  
44              
45             =head2 child_menu ( /.jsrpc/child_menu?page_id=$page_id )
46              
47             Returns a list of children for the page given by the page_id parameter,
48             formatted for inclusion in a vertical tree navigation menu.
49              
50             =cut
51              
52             sub child_menu : Local {
53 1     1 1 985 my ( $self, $c, $page_id ) = @_;
54              
55             # DBIC complains if find argument is not numeric
56 1 50       5 if ( $c->req->params->{page_id} =~ /^\d+$/ ) {
57 0         0 $c->stash->{parent_page} = $c->model("DBIC::Page")->find( $c->req->params->{page_id} );
58             }
59              
60 1         78 $c->stash->{template} = 'child_menu.tt';
61 35     35   431315 }
  35         103  
  35         161  
62              
63             =head2 diff ( /.jsrpc/diff )
64              
65             Loads diff on demand. Takes an absolute revision number as arg,
66             and diffs it against the previous version.
67              
68             =cut
69              
70             sub diff : Local {
71 0     0 1 0 my ( $self, $c, $page, $revision, $against, $sparse ) = @_;
72 0 0       0 unless ($revision) {
73 0 0       0 my $page = $c->model("DBIC::Page")->find($page) or do {
74 0         0 $c->res->output($c->loc("Can't diff a nonexistent page"));
75 0         0 return 0;
76             };
77 0         0 $revision = $page->content->id;
78             }
79 0         0 $revision = $c->model("DBIC::Content")->search(
80             {
81             page => $page,
82             version => $revision
83             }
84             )->next;
85 0 0       0 if (
    0          
86             my $previous = $against
87             ? $c->model("DBIC::Content")->search(
88             {
89             page => $page,
90             version => $against
91             }
92             )->next
93             : $revision->previous
94             )
95             {
96 0         0 $c->res->output( $revision->formatted_diff( $c, $previous, $sparse ) );
97             }
98             else {
99 0         0 $c->res->output($c->loc("This is the first revision! Nothing to diff against."));
100             }
101 35     35   39889 }
  35         91  
  35         168  
102              
103             =head2 submittag ( /.jsrpc/submittag )
104              
105             Add a tag through form submit
106              
107             =cut
108              
109             sub submittag : Local {
110 0     0 1 0 my ( $self, $c, $page ) = @_;
111 0         0 $c->forward( '/jsrpc/tag', [ $c->req->params->{tag} ] );
112 35     35   31964 }
  35         89  
  35         164  
113              
114             =head2 tag ( /.jsrpc/tag )
115              
116             Add a tag to a page. Returns a list of yours and popular tags.
117              
118             =cut
119              
120             sub tag : Local Args(1) {
121 6     6 1 6266 my ( $self, $c, $tagname ) = @_;
122 6         44 ($tagname) = $tagname =~ m/([\w\s]+)/;
123 6         29 my $page = $c->stash->{page};
124 6         366 foreach my $tag ( split m/\s/, $tagname ) {
125 6 50 33     55 if (
126             $tag
127             && !$c->model("DBIC::Tag")->search(
128             {
129             page => $page->id,
130             person => $c->req->{user_id},
131             tag => $tagname,
132             }
133             )->next()
134             )
135             {
136             $page->add_to_tags(
137             {
138             tag => $tag,
139             person => $c->stash->{user}->id
140             }
141 6 50       19279 ) if $page;
142             }
143             }
144 6         67775 $c->req->args( [$tagname] );
145 6         641 $c->forward('/page/inline_tags');
146 35     35   35822 }
  35         89  
  35         163  
147              
148             =head2 untag ( /.jsrpc/untag )
149              
150             Remove a tag from a page. Returns a list of yours and popular tags.
151              
152             =cut
153              
154             sub untag : Local Args(1) {
155 0     0 1 0 my ( $self, $c, $tagname ) = @_;
156 0         0 my $page = $c->stash->{page};
157 0 0       0 die "Page " . $page . " not found" unless ref $page;
158 0         0 my $tag = $c->model("DBIC::Tag")->search(
159             {
160             page => $page->id,
161             person => $c->user->obj->id,
162             tag => $tagname
163             }
164             )->next();
165 0 0       0 $tag->delete() if $tag;
166 0         0 $c->req->args( [$tagname] );
167 0         0 $c->forward('/page/inline_tags');
168 35     35   34630 }
  35         94  
  35         148  
169              
170             =head2 imginfo ( .jsrpc/imginfo )
171              
172             Inline info on hover for gallery photos.
173              
174             =cut
175              
176             sub imginfo : Local {
177 0     0 1 0 my ( $self, $c, $photo ) = @_;
178 0         0 $c->stash->{photo} = $c->model("DBIC::Photo")->find($photo);
179 0         0 $c->stash->{template} = 'gallery/imginfo.tt';
180 35     35   31886 }
  35         86  
  35         158  
181              
182             =head2 usersearch ( .jsrpc/usersearch )
183              
184             Backend that handles jQuery autocomplete requests for users.
185              
186             =cut
187              
188             sub usersearch : Local {
189 0     0 1 0 my ($self, $c) = @_;
190 0         0 my $query = $c->req->param('q');
191              
192 0         0 $c->stash->{template} = "user/user_search.tt";
193              
194 0 0 0     0 if (defined($query) && length($query)) {
195 0         0 my $rs = $c->model('DBIC::Person')->search({
196             login => { -like => '%'.$query.'%'}
197             });
198 0         0 $c->stash->{users} = [ $rs->all ];
199             }
200 35     35   33312 }
  35         100  
  35         170  
201              
202             =head2 set_permissions ( .jsrpc/set_permissions )
203              
204             Sets page permissions.
205              
206             =cut
207              
208             sub set_permissions : Local {
209 0     0 1 0 my ($self, $c) = @_;
210              
211 0         0 $c->forward('validate_perm_edit');
212              
213 0         0 my @path_elements = $c->_expand_path_elements($c->stash->{path});
214 0         0 my $current_path = pop @path_elements;
215              
216             my ( $create, $read, $write, $delete, $attachment, $subpages) =
217 0 0       0 map { $c->req->param($_) ? 'yes' : 'no' }
  0         0  
218             qw/create read write delete attachment subpages/;
219              
220 0         0 my $role = $c->stash->{role};
221              
222 0         0 my $params = {
223             path => $current_path,
224             role => $role->id,
225             apply_to_subpages => $subpages,
226             create_allowed => $create,
227             delete_allowed => $delete,
228             edit_allowed => $write,
229             view_allowed => $read,
230             attachment_allowed => $attachment
231             };
232              
233 0         0 my $model = $c->model('DBIC::PathPermissions');
234              
235             # when subpages should inherit permissions we actually need to update two
236             # entries: one for the subpages and one for the current page
237 0 0       0 if ($subpages eq 'yes') {
238             # update permissions for subpages
239 0         0 $model->update_or_create( $params );
240              
241             # update permissions for the current page
242 0         0 $params->{apply_to_subpages} = 'no';
243 0         0 $model->update_or_create( $params );
244             }
245             # otherwise, we must remove the subpages permissions entry and update the
246             # entry for the current page
247             else {
248             # delete permissions for subpages
249 0         0 $model->search( {
250             path => $current_path,
251             role => $role->id,
252             apply_to_subpages => 'yes'
253             } )->delete;
254              
255             # update permissions for the current page
256 0         0 $model->update_or_create($params);
257             }
258              
259             # clear cache
260 0 0       0 if ( $c->pref('cache_permission_data') ) {
261 0         0 $c->cache->remove( 'page_permission_data' );
262             }
263              
264 0         0 $c->res->body("OK");
265 0         0 $c->res->status(200);
266 35     35   41019 }
  35         83  
  35         160  
267              
268             =head2 clear_permissions ( .jsrpc/clear_permissions )
269              
270             Clears this page permissions for a given role (making permissions inherited).
271              
272             =cut
273              
274             sub clear_permissions : Local {
275 0     0 1 0 my ($self, $c) = @_;
276              
277 0         0 $c->forward('validate_perm_edit');
278              
279 0         0 my @path_elements = $c->_expand_path_elements($c->stash->{path});
280 0         0 my $current_path = pop @path_elements;
281              
282 0         0 my $role = $c->stash->{role};
283              
284 0 0       0 if ($role) {
285              
286             # delete permissions for subpages
287 0         0 $c->model('DBIC::PathPermissions')->search( {
288             path => $current_path,
289             role => $role->id
290             } )->delete;
291              
292             # clear cache
293 0 0       0 if ( $c->pref('cache_permission_data') ) {
294 0         0 $c->cache->remove( 'page_permission_data' );
295             }
296              
297             }
298              
299 0         0 $c->res->body("OK");
300 0         0 $c->res->status(200);
301              
302 35     35   34057 }
  35         81  
  35         155  
303              
304             =head2 validate_perm_edit
305              
306             Validates if the user is able to edit permissions and if a role was supplied.
307              
308             =cut
309              
310             sub validate_perm_edit : Private {
311 0     0 1   my ($self, $c) = @_;
312              
313 0           my $user = $c->user;
314              
315             # only admins can change permissions for now
316 0 0 0       unless ($user && $user->is_admin) {
317 0           $c->res->body("Forbidden");
318 0           $c->res->status(403);
319 0           $c->detach;
320             }
321              
322 0           my $role = $c->model('DBIC::Role')->find(
323             { name => $c->req->param('role_name') }
324             );
325              
326 0 0         unless ($role) {
327 0           $c->res->body('Bad Request');
328 0           $c->res->status(400);
329 0           $c->detach;
330             }
331              
332 0           $c->stash->{role} = $role;
333 35     35   33907 }
  35         84  
  35         158  
334              
335             =head1 AUTHOR
336              
337             Marcus Ramberg <mramberg@cpan.org>, David Naughton <naughton@cpan.org>
338              
339             =head1 LICENSE
340              
341             This library is free software. You can redistribute it and/or modify it under
342             the same terms as Perl itself.
343              
344             =cut
345              
346             1;