root/branches/release-39/lib/MT/CMS/TrackBack.pm @ 2454

Revision 2454, 25.3 kB (checked in by fumiakiy, 18 months ago)

Calculate and set offset value correctly when the number of items appearing on a page is changed. BugId:79897

  • Property svn:keywords set to Id Revision
Line 
1package MT::CMS::TrackBack;
2
3use strict;
4use MT::Util qw( format_ts relative_date encode_url encode_html );
5use MT::I18N qw( const break_up_text );
6
7sub edit {
8    my $cb = shift;
9    my ($app, $id, $obj, $param) = @_;
10
11    my $q = $app->param;
12    my $perms = $app->permissions;
13    my $blog = $app->blog;
14    my $blog_id = $q->param('blog_id');
15    my $type = $q->param('_type');
16
17    if ($id) {
18        $param->{nav_trackbacks} = 1;
19        $app->add_breadcrumb(
20            $app->translate('TrackBacks'),
21            $app->uri(
22                'mode' => 'list_pings',
23                args   => { blog_id => $blog_id }
24            )
25        );
26        $app->add_breadcrumb( $app->translate('Edit TrackBack') );
27        $param->{approved}           = $app->param('approved');
28        $param->{unapproved}         = $app->param('unapproved');
29        $param->{has_publish_access} = 1 if $app->user->is_superuser;
30        $param->{has_publish_access} = (
31            ( $perms->can_manage_feedback || $perms->can_edit_all_posts )
32            ? 1
33            : 0
34        ) unless $app->user->is_superuser;
35        require MT::Trackback;
36
37        if ( my $tb = MT::Trackback->load( $obj->tb_id ) ) {
38            if ( $tb->entry_id ) {
39                $param->{entry_ping} = 1;
40                require MT::Entry;
41                if ( my $entry = MT::Entry->load( $tb->entry_id ) ) {
42                    $param->{entry_title} = $entry->title;
43                    $param->{entry_id}    = $entry->id;
44                    unless ( $param->{has_publish_access} ) {
45                        $param->{has_publish_access} =
46                          ( $perms->can_publish_post
47                              && ( $app->user->id == $entry->author_id ) )
48                          ? 1
49                          : 0;
50                    }
51                }
52            }
53            elsif ( $tb->category_id ) {
54                $param->{category_ping} = 1;
55                require MT::Category;
56                if ( my $cat = MT::Category->load( $tb->category_id ) ) {
57                    $param->{category_id}    = $cat->id;
58                    $param->{category_label} = $cat->label;
59                }
60            }
61        }
62
63        $param->{"ping_approved"} = $obj->is_published
64          or $param->{"ping_pending"} = $obj->is_moderated
65          or $param->{"is_junk"}      = $obj->is_junk;
66
67        ## Load next and previous entries for next/previous links
68        if ( my $next = $obj->next ) {
69            $param->{next_ping_id} = $next->id;
70        }
71        if ( my $prev = $obj->previous ) {
72            $param->{previous_ping_id} = $prev->id;
73        }
74        my $parent = $obj->parent;
75        if ( $parent && ( $parent->isa('MT::Entry') ) ) {
76            if ( $parent->status == MT::Entry::RELEASE() ) {
77                $param->{entry_permalink} = $parent->permalink;
78            }
79        }
80
81        if ( $obj->junk_log ) {
82            require MT::CMS::Comment;
83            MT::CMS::Comment::build_junk_table( $app, param => $param, object => $obj );
84        }
85
86        $param->{created_on_time_formatted} =
87          format_ts( MT::App::CMS::LISTING_DATETIME_FORMAT(), $obj->created_on(), $blog, $app->user ? $app->user->preferred_language : undef );
88        $param->{created_on_day_formatted} =
89          format_ts( MT::App::CMS::LISTING_DATE_FORMAT(), $obj->created_on(), $blog, $app->user ? $app->user->preferred_language : undef );
90
91        $param->{search_label} = $app->translate('TrackBacks');
92        $param->{object_type}  = 'ping';
93
94        $app->load_list_actions( $type, $param );
95
96        # since MT::App::build_page clobbers it:
97        $param->{source_blog_name} = $param->{blog_name};
98    }
99    1;
100}
101
102sub list {
103    my $app   = shift;
104    my $q     = $app->param;
105    my $perms = $app->permissions;
106
107    my $can_empty_junk = 1;
108    my $state_editable = 1;
109    my $admin = $app->user->is_superuser
110      || ( $perms && $perms->can_administer_blog );
111    if ($perms) {
112        unless ( $perms->can_view_feedback ) {
113            return $app->error( $app->translate("Permission denied.") );
114        }
115        $can_empty_junk = $admin
116          || ( $perms && $perms->can_manage_feedback )
117          ? 1 : 0;
118        $state_editable = $admin
119          || ( $perms
120            && ( $perms->can_publish_post
121              || $perms->can_edit_all_posts || $perms->can_manage_feedback ) )
122          ? 1 : 0;
123    }    # otherwise we simply filter the list of objects
124
125    my $list_pref = $app->list_pref('ping');
126    my $class     = $app->model("ping") or return;
127    my $blog_id   = $q->param('blog_id');
128    my $blog;
129    if ($blog_id) {
130        $blog = $app->model('blog')->load($blog_id);
131    }
132    my %param = %$list_pref;
133    my %terms;
134    if ($blog_id) {
135        $terms{blog_id} = $blog_id;
136    }
137    elsif ( !$app->user->is_superuser ) {
138        $terms{blog_id} = [
139            map    { $_->blog_id }
140              grep { $_->can_view_feedback }
141              MT::Permission->load( { author_id => $app->user->id } )
142        ];
143        return $app->errtrans("Permission denied.")
144          unless @{ $terms{blog_id} };
145    }
146    my $cols           = $class->column_names;
147    my $limit          = $list_pref->{rows};
148    my $offset         = $app->param('offset') || 0;
149    my $sort_direction = $q->param('sortasc') ? 'ascend' : 'descend';
150
151    ## We load $limit + 1 records so that we can easily tell if we have a
152    ## page of next entries to link to. Obviously we only display $limit
153    ## entries.
154    my %arg;
155    require MT::TBPing;
156    if ( ( $app->param('tab') || '' ) eq 'junk' ) {
157        $app->param( 'filter',     'junk_status' );
158        $app->param( 'filter_val', MT::TBPing::JUNK() );
159        $param{filter_special} = 1;
160        $param{filter_phrase}  = $app->translate('Junk TrackBacks');
161    }
162    else {
163        $terms{'junk_status'} = MT::TBPing::NOT_JUNK();
164    }
165
166    my $filter_key = $q->param('filter_key');
167    if ( !$filter_key && !$app->param('filter') ) {
168        $filter_key = 'default';
169    }
170    my @val        = $q->param('filter_val');
171    my $filter_col = $q->param('filter');
172    if ( $filter_col && ( my $val = $q->param('filter_val') ) ) {
173        if ( $filter_col eq 'status' ) {
174            $terms{visible} = $val eq 'approved' ? 1 : 0;
175        }
176        elsif ($filter_col eq 'category_id'
177            || $filter_col eq 'entry_id' )
178        {
179            $arg{join} = $app->model('trackback')->join_on(
180                undef,
181                {
182                    id          => \'= tbping_tb_id',
183                    $filter_col => $val,
184                    $blog_id ? ( blog_id => $blog_id ) : (),
185                }
186            );
187            if ( $filter_col eq 'entry_id' ) {
188                my $pkg   = $app->model('entry');
189                my $entry = $pkg->load($val);
190                if ($entry) {
191                    $param{filter_phrase} = $app->translate(
192    "TrackBacks where <strong>[_1]</strong> is &quot;[_2]&quot;.",
193                        $entry->class_label,
194                        encode_html( $entry->title )
195                    );
196                }
197            }
198            elsif ( $filter_col eq 'category_id' ) {
199                my $pkg = $app->model('category');
200                my $cat = $pkg->load($val);
201                if ($cat) {
202                    $param{filter_phrase} = $app->translate(
203    "TrackBacks where <strong>[_1]</strong> is &quot;[_2]&quot;.",
204                        $cat->class_label,
205                        encode_html( $cat->label )
206                    );
207                }
208            }
209            $param{filter_special} = 1;
210        }
211        else {
212            if ( $val[1] ) {
213                $terms{$filter_col} = [ $val[0], $val[1] ];
214                $arg{'range_incl'} = { $filter_col => 1 };
215                $param{filter_val2}  = $val[1];
216                $param{filter_range} = 1;
217            }
218            else {
219                $terms{$filter_col} = $val;
220            }
221        }
222        $param{filter_args} = "&filter=" . encode_url($filter_col) . "&filter_val=" . encode_url($val);
223        $param{filter}     ||= $filter_col;
224        $param{filter_val} ||= $val;
225        $param{is_filtered} = 1;
226        $param{is_ip_filter} = $filter_col eq "ip";
227    }
228    elsif ($filter_key) {
229        my $filters = $app->registry("list_filters", "ping") || {};
230        if ( my $filter = $filters->{$filter_key} ) {
231            if ( my $code = $filter->{code}
232                || $app->handler_to_coderef( $filter->{handler} ) )
233            {
234                $param{filter} = 1;
235                $param{filter_key}   = $filter_key;
236                $param{filter_label} = $filter->{label};
237                $code->( \%terms, \%arg );
238            }
239        }
240    }
241
242    my $ping_class = $app->model('ping');
243    my $total      = $ping_class->count( \%terms, \%arg ) || 0;
244    $arg{'sort'}    = 'created_on';
245    $arg{direction} = $sort_direction;
246    $arg{limit}     = $limit + 1;
247    if ( $total <= $limit ) {
248        delete $arg{limit};
249        $offset = 0;
250    }
251    elsif ( $total && $offset > $total - 1 ) {
252        $arg{offset} = $offset = $total - $limit;
253    }
254    elsif ( $offset && ( ( $offset < 0 ) || ( $total - $offset < $limit ) ) ) {
255        $arg{offset} = $offset = $total - $limit;
256    }
257    else {
258        $arg{offset} = $offset if $offset;
259    }
260
261    my $iter = $class->load_iter( \%terms, \%arg );
262    my $data = build_ping_table( $app, iter => $iter, param => \%param );
263    delete $_->{object} for @$data;
264
265    ## We tried to load $limit + 1 entries above; if we actually got
266    ## $limit + 1 back, we know we have another page of entries.
267    my $have_next_entry = @$data > $limit;
268    pop @$data while @$data > $limit;
269    if ($offset) {
270        $param{prev_offset}     = 1;
271        $param{prev_offset_val} = $offset - $limit;
272        $param{prev_offset_val} = 0 if $param{prev_offset_val} < 0;
273    }
274    if ($have_next_entry) {
275        $param{next_offset}     = 1;
276        $param{next_offset_val} = $offset + $limit;
277    }
278
279    $param{ping_count}         = scalar @$data;
280    $param{limit}              = $limit;
281    $param{offset}             = $offset;
282    $param{list_filters}       = $app->list_filters('ping');
283    $param{saved}              = $q->param('saved');
284    $param{junked}             = $q->param('junked');
285    $param{unjunked}           = $q->param('unjunked');
286    $param{approved}           = $q->param('approved');
287    $param{unapproved}         = $q->param('unapproved');
288    $param{emptied}            = $q->param('emptied');
289    $param{state_editable}     = $state_editable;
290    $param{can_empty_junk}     = $can_empty_junk;
291    $param{saved_deleted_ping} = $q->param('saved_deleted')
292      || $q->param('saved_deleted_ping');
293    $param{object_type}         = 'ping';
294    $param{object_label}        = $ping_class->class_label;
295    $param{object_label_plural} = $ping_class->class_label_plural;
296    $param{search_label}        = $param{object_label_plural};
297    $param{list_start}          = $offset + 1;
298    $param{list_end}            = $offset + scalar @$data;
299    $param{list_total}          = $total;
300    $param{next_max}     = $param{list_total} - $limit if $param{list_total};
301    $param{next_max}     = 0 if ( $param{next_max} || 0 ) < $offset + 1;
302    $param{page_actions} = $app->page_actions('list_pings')
303      || $app->page_actions('list_ping');
304    $param{nav_trackbacks}    = 1;
305    $param{has_expanded_mode} = 1;
306    $param{tab}               = $app->param('tab') || 'pings';
307    $param{ "tab_" . ( $app->param('tab') || 'pings' ) } = 1;
308
309    unless ($blog_id) {
310        $param{system_overview_nav} = 1;
311        $param{nav_pings}           = 1;
312    }
313    $param{filter_spam} =
314      ( $app->param('filter_key') && $app->param('filter_key') eq 'spam' );
315    if ( $param{'tab'} ne 'junk' ) {
316        $param{feed_name} = $app->translate("TrackBack Activity Feed");
317        $param{feed_url} =
318          $app->make_feed_link( 'ping',
319            $blog_id ? { blog_id => $blog_id } : undef );
320    }
321    $param{screen_id} = "list-ping";
322    $param{listing_screen} = 1;
323    $app->add_breadcrumb( $app->translate('TrackBacks') );
324    $app->load_tmpl( "list_ping.tmpl", \%param );
325}
326
327sub cfg_trackbacks {
328    my $app     = shift;
329    my $q       = $app->param;
330    my $blog_id = scalar $q->param('blog_id');
331    return $app->return_to_dashboard( redirect => 1 )
332      unless $blog_id;
333    $q->param( '_type', 'blog' );
334    $q->param( 'id',    scalar $q->param('blog_id') );
335    $app->forward( "view",
336        {
337            output       => 'cfg_trackbacks.tmpl',
338            screen_class => 'settings-screen',
339            screen_id    => 'trackback-settings',
340        }
341    );
342}
343
344sub can_view {
345    my $eh = shift;
346    my ( $app, $id, $objp ) = @_;
347    my $obj = $objp->force() or return 0;
348    require MT::Trackback;
349    my $tb    = MT::Trackback->load( $obj->tb_id );
350    my $perms = $app->permissions;
351    if ($tb) {
352        if ( $tb->entry_id ) {
353            require MT::Entry;
354            my $entry = MT::Entry->load( $tb->entry_id );
355            return ( !$entry
356                  || $entry->author_id == $app->user->id
357                  || $perms->can_manage_feedback
358                  || $perms->can_edit_all_posts );
359        }
360        elsif ( $tb->category_id ) {
361            require MT::Category;
362            my $cat = MT::Category->load( $tb->category_id );
363            return $cat && $perms->can_edit_categories;
364        }
365    }
366    else {
367        return 0;    # no TrackBack center--no edit
368    }
369}
370
371sub can_save {
372    my ( $eh, $app, $id ) = @_;
373    return 0 unless $id;    # Can't create new pings here
374    return 1 if $app->user->is_superuser();
375
376    my $perms = $app->permissions;
377    return 1
378      if $perms
379      && ( $perms->can_edit_all_posts
380        || $perms->can_manage_feedback );
381    my $p      = MT::TBPing->load($id)
382        or return 0;
383    my $tbitem = $p->parent;
384    if ( $tbitem->isa('MT::Entry') ) {
385        if ( $perms && $perms->can_publish_post && $perms->can_create_post ) {
386            return $tbitem->author_id == $app->user->id;
387        }
388        elsif ( $perms->can_create_post ) {
389            return ( $tbitem->author_id == $app->user->id )
390              && (
391                ( $p->is_junk && ( 'junk' eq $app->param('status') ) )
392                || ( $p->is_moderated
393                    && ( 'moderate' eq $app->param('status') ) )
394                || ( $p->is_published
395                    && ( 'publish' eq $app->param('status') ) )
396              );
397        }
398        elsif ( $perms && $perms->can_publish_post ) {
399            return 0 unless $tbitem->author_id == $app->user->id;
400            return 0
401              unless ( $p->excerpt eq $app->param('excerpt') )
402              && ( $p->blog_name  eq $app->param('blog_name') )
403              && ( $p->title      eq $app->param('title') )
404              && ( $p->source_url eq $app->param('source_url') );
405        }
406    }
407    else {
408        return $perms && $perms->can_edit_categories;
409    }
410}
411
412sub can_delete {
413    my ( $eh, $app, $obj ) = @_;
414    my $author = $app->user;
415    return 1 if $author->is_superuser();
416    my $perms = $app->permissions;
417    require MT::Trackback;
418    my $tb = MT::Trackback->load( $obj->tb_id )
419        or return 0;
420    if ( my $entry = $tb->entry ) {
421        if ( !$perms || $perms->blog_id != $entry->blog_id ) {
422            $perms ||= $author->permissions( $entry->blog_id );
423        }
424
425        # publish_post allows entry author to delete comment.
426        return 1
427          if $perms->can_edit_all_posts
428          || $perms->can_manage_feedback
429          || $perms->can_edit_entry( $entry, $author, 1 );
430        return 0
431          if $obj->visible;    # otherwise, visible comment can't be deleted.
432        return $perms->can_edit_entry( $entry, $author );
433    }
434    elsif ( $tb->category_id ) {
435        $perms ||= $author->permissions( $tb->blog_id );
436        return ( $perms && $perms->can_edit_categories() );
437    }
438    return 0;
439}
440
441sub pre_save {
442    my $eh = shift;
443    my ( $app, $obj, $original ) = @_;
444    my $perms = $app->permissions;
445    return 1
446      unless $perms->can_publish_post
447      || $perms->can_edit_categories
448      || $perms->can_edit_all_posts
449      || $perms->can_manage_feedback;
450
451    unless ( $perms->can_edit_all_posts || $perms->can_manage_feedback ) {
452        return 1 unless $perms->can_publish_post || $perms->can_edit_categories;
453        require MT::Trackback;
454        my $tb = MT::Trackback->load( $obj->tb_id )
455            or return 0;
456        if ($tb) {
457            if ( $tb->entry_id ) {
458                require MT::Entry;
459                my $entry = MT::Entry->load( $tb->entry_id );
460                return 1
461                  if ( !$entry || $entry->author_id != $app->user->id )
462                  && $perms->can_publish_post;
463            }
464        }
465        elsif ( $tb->category_id ) {
466            require MT::Category;
467            my $cat = MT::Category->load( $tb->category_id );
468            return 1 unless $cat && $perms->can_edit_categories;
469        }
470    }
471
472    my $status = $app->param('status');
473    if ( $status eq 'publish' ) {
474        $obj->approve;
475        if ( $original->junk_status != $obj->junk_status ) {
476            $app->run_callbacks( 'handle_ham', $app, $obj );
477        }
478    }
479    elsif ( $status eq 'moderate' ) {
480        $obj->moderate;
481    }
482    elsif ( $status eq 'junk' ) {
483        $obj->junk;
484        if ( $original->junk_status != $obj->junk_status ) {
485            $app->run_callbacks( 'handle_spam', $app, $obj );
486        }
487    }
488    return 1;
489}
490
491sub post_save {
492    my $eh = shift;
493    my ( $app, $obj, $original ) = @_;
494    require MT::Trackback;
495    require MT::Entry;
496    require MT::Category;
497    if ( my $tb = MT::Trackback->load( $obj->tb_id ) ) {
498        my ( $entry, $cat );
499        if ( $tb->entry_id && ( $entry = MT::Entry->load( $tb->entry_id ) ) ) {
500            if ( $obj->visible
501                || ( ( $obj->visible || 0 ) != ( $original->visible || 0 ) ) )
502            {
503                $app->rebuild_entry( Entry => $entry, BuildIndexes => 1 )
504                    or return $app->publish_error();
505            }
506        }
507        elsif ( $tb->category_id
508            && ( $cat = MT::Category->load( $tb->category_id ) ) )
509        {
510
511            # FIXME: rebuild single category
512        }
513    }
514    1;
515}
516
517sub post_delete {
518    my ( $eh, $app, $obj ) = @_;
519
520    my ( $message, $title );
521    my $obj_parent = $obj->parent();
522    if ( $obj_parent->isa('MT::Category') ) {
523        $title = $obj_parent->label || $app->translate('(Unlabeled category)');
524        $message =
525          $app->translate(
526            "Ping (ID:[_1]) from '[_2]' deleted by '[_3]' from category '[_4]'",
527            $obj->id, $obj->blog_name, $app->user->name, $title );
528    }
529    else {
530        $title = $obj_parent->title || $app->translate('(Untitled entry)');
531        $message =
532          $app->translate(
533            "Ping (ID:[_1]) from '[_2]' deleted by '[_3]' from entry '[_4]'",
534            $obj->id, $obj->blog_name, $app->user->name, $title );
535    }
536
537    $app->log(
538        {
539            message  => $message,
540            level    => MT::Log::INFO(),
541            class    => 'system',
542            category => 'delete'
543        }
544    );
545}
546
547# takes param and one of load_args, iter, or items
548sub build_ping_table {
549    my $app = shift;
550    my (%args) = @_;
551
552    require MT::Entry;
553    require MT::Trackback;
554    require MT::Category;
555
556    my $author    = $app->user;
557    my $list_pref = $app->list_pref('ping');
558    my $iter;
559    if ( $args{load_args} ) {
560        my $class = $app->model('ping');
561        $iter = $class->load_iter( @{ $args{load_args} } );
562    }
563    elsif ( $args{iter} ) {
564        $iter = $args{iter};
565    }
566    elsif ( $args{items} ) {
567        $iter = sub { pop @{ $args{items} } };
568    }
569    return [] unless $iter;
570    my $limit = $args{limit};
571    my $param = $args{param};
572
573    my @data;
574    my ( %blogs, %entries, %cats, %perms );
575    my $excerpt_max_len = const('DISPLAY_LENGTH_EDIT_PING_TITLE_FROM_EXCERPT');
576    my $title_max_len   = const('DISPLAY_LENGTH_EDIT_PING_BREAK_UP');
577    while ( my $obj = $iter->() ) {
578        my $row = $obj->column_values;
579        my $blog = $blogs{ $obj->blog_id } ||= $obj->blog if $obj->blog_id;
580        $row->{excerpt} = '[' . $app->translate("No Excerpt") . ']'
581          unless ( $row->{excerpt} || '' ) ne '';
582        if ( ( $row->{title} || '' ) eq ( $row->{source_url} || '' ) ) {
583            $row->{title} = '[' . $app->translate("No Title") . ']';
584        }
585        if ( !defined( $row->{title} ) ) {
586            $row->{title} =
587              substr_text( $row->{excerpt} || "", 0, $excerpt_max_len ) . '...';
588        }
589        $row->{excerpt} ||= '';
590        $row->{title}     = break_up_text( $row->{title},     $title_max_len );
591        $row->{excerpt}   = break_up_text( $row->{excerpt},   $title_max_len );
592        $row->{blog_name} = break_up_text( $row->{blog_name}, $title_max_len );
593        $row->{object}    = $obj;
594        push @data, $row;
595
596        my $entry;
597        my $cat;
598        if ( my $tb_center = MT::Trackback->load( $obj->tb_id ) ) {
599            if ( $tb_center->entry_id ) {
600                $entry = $entries{ $tb_center->entry_id } ||=
601                  $app->model('entry')->load( $tb_center->entry_id );
602                my $class = $entry->class || 'entry';
603                if ($entry) {
604                    $row->{target_title} = $entry->title;
605                    $row->{target_link}  = $app->uri(
606                        'mode' => 'view',
607                        args   => {
608                            '_type' => $class,
609                            id      => $entry->id,
610                            blog_id => $entry->blog_id,
611                            tab     => 'pings'
612                        }
613                    );
614                }
615                else {
616                    $row->{target_title} =
617                      ( '* ' . $app->translate('Orphaned TrackBack') . ' *' );
618                }
619                $row->{target_type} = $app->translate($class);
620            }
621            elsif ( $tb_center->category_id ) {
622                $cat = $cats{ $tb_center->category_id } ||=
623                  MT::Category->load( $tb_center->category_id );
624                if ($cat) {
625                    $row->{target_title} =
626                      ( '* ' . $app->translate('Orphaned TrackBack') . ' *' );
627                    $row->{target_title} = $cat->label;
628                    $row->{target_link}  = $app->uri(
629                        'mode' => 'view',
630                        args   => {
631                            '_type' => 'category',
632                            id      => $cat->id,
633                            blog_id => $cat->blog_id,
634                            tab     => 'pings'
635                        }
636                    );
637                }
638                $row->{target_type} = $app->translate('category');
639            }
640        }
641        if ( my $ts = $obj->created_on ) {
642            $row->{created_on_time_formatted} =
643              format_ts( MT::App::CMS::LISTING_DATETIME_FORMAT(), $ts, $blog, $app->user ? $app->user->preferred_language : undef );
644            $row->{created_on_formatted} =
645              format_ts( MT::App::CMS::LISTING_DATE_FORMAT(), $ts, $blog, $app->user ? $app->user->preferred_language : undef );
646            $row->{created_on_relative} = relative_date( $ts, time, $blog );
647        }
648        if ($blog) {
649            $row->{weblog_id}   = $blog->id;
650            $row->{weblog_name} = $blog->name;
651        }
652        else {
653            $row->{weblog_name} =
654              '* ' . $app->translate('Orphaned TrackBack') . ' *';
655        }
656        if ( $author->is_superuser() ) {
657            $row->{has_edit_access} = 1;
658            $row->{has_bulk_access} = 1;
659        }
660        else {
661            my $perms = $perms{ $obj->blog_id } ||=
662              $author->permissions( $obj->blog_id );
663            $row->{has_bulk_access} = (
664                (
665                    $perms
666                      && (
667                        (
668                            $entry && ( $perms->can_edit_all_posts
669                                || $perms->can_manage_feedback )
670                        )
671                        || (
672                            $cat
673                            && (   $perms->can_edit_categories
674                                || $perms->can_manage_feedback )
675                        )
676                      )
677                )
678                  || ( $cat && $author->id == $cat->author_id )
679                  || (
680                    $entry
681                    && ( ( $author->id == $entry->author_id )
682                        && $perms->can_publish_post )
683                  )
684            );
685            $row->{has_edit_access} = (
686                (
687                    $perms
688                      && (
689                        (
690                            $entry && ( $perms->can_edit_all_posts
691                                || $perms->can_manage_feedback )
692                        )
693                        || (
694                            $cat
695                            && (   $perms->can_edit_categories
696                                || $perms->can_manage_feedback )
697                        )
698                      )
699                )
700                  || ( $cat && $author->id == $cat->author_id )
701                  || (
702                    $entry
703                    && ( ( $author->id == $entry->author_id )
704                        && $perms->can_create_post )
705                  )
706            );
707        }
708    }
709    return [] unless @data;
710
711    $param->{ping_table}[0] = {%$list_pref};
712    $param->{object_loop} = $param->{ping_table}[0]{object_loop} = \@data;
713    $param->{ping_table}[0]{object_type} = 'ping';
714    $app->load_list_actions( 'ping', $param );
715    \@data;
716}
717
7181;
Note: See TracBrowser for help on using the browser.