root/branches/release-41/plugins/MultiBlog/multiblog.pl @ 2727

Revision 2727, 12.6 kB (checked in by bchoate, 17 months ago)

Updated MultiBlog to issue triggered publishing for scheduled posts. BugId:80355

  • Property svn:keywords set to Id
Line 
1# Movable Type (r) Open Source (C) 2006-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7# Original Copyright (c) 2004-2006 David Raynes
8
9package MT::Plugin::MultiBlog;
10
11use strict;
12use warnings;
13
14use base qw( MT::Plugin );
15
16our $VERSION = '2.0';
17my $plugin  = MT::Plugin::MultiBlog->new({
18    id          =>  'multiblog',
19    name        =>  'MultiBlog',
20    description =>  '<MT_TRANS phrase="MultiBlog allows you to publish content from other blogs and define publishing rules and access controls between them.">',
21    version                => $VERSION,
22    author_name            => 'Six Apart, Ltd.',
23    author_link            => 'http://www.sixapart.com/',
24    system_config_template => 'system_config.tmpl',
25    blog_config_template   => 'blog_config.tmpl',
26    settings               => new MT::PluginSettings([
27        [ 'default_access_allowed',     { Default =>  1, Scope => 'system' }],
28        [ 'rebuild_triggers',           { Default => '', Scope => 'blog' } ],
29        [ 'blog_content_accessible',    { Default => '', Scope => 'blog' } ],
30        [ 'other_triggers',             { Scope   => 'blog' } ],
31        [ 'all_triggers',               { Scope   => 'system' } ],
32        [ 'default_mtmultiblog_action', { Default =>  1, Scope => 'blog' } ],
33        [ 'default_mtmulitblog_blogs',  { Default => '', Scope => 'blog' } ],
34    ]),
35    l10n_class => 'MultiBlog::L10N',
36    registry => {
37        applications => {
38            'cms' => {
39                methods => {
40                    multiblog_add_trigger => '$multiblog::MT::Plugin::MultiBlog::add_trigger',
41                },
42            },
43        },
44        tags => {
45            help_url => sub { MT->translate('http://www.movabletype.org/documentation/appendices/tags/%t.html') },
46            block => {
47                Entries => 'MultiBlog::preprocess_native_tags',
48                Categories => 'MultiBlog::preprocess_native_tags',
49                Comments => 'MultiBlog::preprocess_native_tags',
50                Pages => 'MultiBlog::preprocess_native_tags',
51                Folders => 'MultiBlog::preprocess_native_tags',
52                Blogs => 'MultiBlog::preprocess_native_tags',
53                Assets => 'MultiBlog::preprocess_native_tags',
54                Comments => 'MultiBlog::preprocess_native_tags',
55                Pings => 'MultiBlog::preprocess_native_tags',
56                Authors => 'MultiBlog::preprocess_native_tags',
57                Tags => 'MultiBlog::preprocess_native_tags',
58                MultiBlog => 'MultiBlog::Tags::MultiBlog',
59                OtherBlog => 'MultiBlog::Tags::MultiBlog',
60                MultiBlogLocalBlog => 'MultiBlog::Tags::MultiBlogLocalBlog',
61                'MultiBlogIfLocalBlog?' => 'MultiBlog::Tags::MultiBlogIfLocalBlog',
62            },
63            function => {
64                'Include' => 'MultiBlog::preprocess_native_tags',
65                'BlogCategoryCount' => 'MultiBlog::preprocess_native_tags',
66                'BlogEntryCount' => 'MultiBlog::preprocess_native_tags',
67                'BlogPingCount' => 'MultiBlog::preprocess_native_tags',
68                'TagSearchLink' => 'MultiBlog::preprocess_native_tags',
69            },
70        },
71    },
72});
73MT->add_plugin($plugin);
74
75# Register entry post-save callback for rebuild triggers
76MT->add_callback( 'cms_post_save.entry', 10, $plugin,
77    sub { $plugin->runner( 'post_entry_save', @_ ) } );
78MT->add_callback( 'scheduled_post_published', 10, $plugin,
79    sub { $plugin->runner( 'post_entry_pub', @_ ) } );
80
81# Register Comment/TB post-save callbacks for rebuild triggers
82MT->add_callback( 'MT::Comment::post_save', 10, $plugin,
83    sub { $plugin->runner( 'post_feedback_save', 'comment_pub', @_ ) } );
84MT->add_callback( 'MT::TBPing::post_save', 10, $plugin,
85    sub { $plugin->runner( 'post_feedback_save', 'tb_pub', @_ ) } );
86
87sub instance { $plugin }
88
89sub add_trigger {
90    my $app = shift;
91
92    return $plugin->translate("Permission denied.")
93        unless $app->user->is_superuser() ||
94               ($app->blog && $app->user->permissions($app->blog->id)->can_administer_blog());
95
96    my $blog_id = $app->blog->id;
97
98    my $dialog_tmpl = $plugin->load_tmpl('dialog_create_trigger.tmpl');
99    my $tmpl = $app->listing({
100        template => $dialog_tmpl,
101        type => 'blog',
102        code => sub {
103            my ($obj, $row) = @_;
104            if ($obj) {
105                $row->{label} = $obj->name;
106                $row->{link} = $obj->site_url;
107            }
108        },
109        terms => {
110            id => [ $blog_id ],
111        },
112        args => {
113            not => { id => 1 },
114        },
115        params => {
116            panel_type => 'blog',
117            dialog_title => $plugin->translate('MultiBlog'),
118            panel_title => $plugin->translate('Create Trigger'),
119            panel_label => $plugin->translate("Weblog Name"),
120            search_prompt => $plugin->translate("Search Weblogs") . ':',
121            panel_description => $plugin->translate("Description"),
122            panel_multi => 0,
123            panel_first => 1,
124            panel_last => 1,
125            panel_searchable => 1,
126            multiblog_trigger_loop => trigger_loop(),
127            multiblog_action_loop => action_loop(),
128            list_noncron => 1,
129            trigger_caption => $plugin->translate('When this'),
130        },
131    });
132    if (!$app->param('search')) {
133        if (my $loop = $tmpl->param('object_loop')) {
134            unshift @$loop, {
135                id => '_all',
136                label => $plugin->translate('* All Weblogs'),
137                description => $plugin->translate('Select to apply this trigger to all weblogs'),
138            };
139        }
140    }
141    return $app->build_page($tmpl);
142}
143
144sub trigger_loop {
145    [
146        {
147            trigger_key  => 'entry_save',
148            trigger_name => $plugin->translate('saves an entry'),
149        },
150        {
151            trigger_key  => 'entry_pub',
152            trigger_name => $plugin->translate('publishes an entry'),
153        },
154        {
155            trigger_key  => 'comment_pub',
156            trigger_name => $plugin->translate('publishes a comment'),
157        },
158        {
159            trigger_key  => 'tb_pub',
160            trigger_name => $plugin->translate('publishes a TrackBack'),
161        },
162    ];
163}
164
165sub action_loop {
166    [
167        {
168            action_id   => 'ri',
169            action_name => $plugin->translate('rebuild indexes.'),
170        },
171        {
172            action_id   => 'rip',
173            action_name => $plugin->translate('rebuild indexes and send pings.'),
174        },
175    ];
176}
177
178sub load_config {
179    my $plugin = shift;
180    my ($args, $scope) = @_;
181
182    $plugin->SUPER::load_config(@_);
183
184    if ( $scope =~ /blog:(\d+)/ ) {
185        my $blog_id = $1;
186
187        require MT::Blog;
188
189        $args->{multiblog_trigger_loop} = trigger_loop();
190        my %triggers =
191            map { $_->{trigger_key} => $_->{trigger_name} }
192                @{ $args->{multiblog_trigger_loop}};
193
194        $args->{multiblog_action_loop} = action_loop();
195        my %actions =
196            map { $_->{action_id} => $_->{action_name} }
197                @{ $args->{multiblog_action_loop} };
198
199        my $rebuild_triggers = $args->{rebuild_triggers};
200        my @rebuilds = map {
201            my ( $action, $id, $trigger ) = split ( /:/, $_ );
202            if ($id eq '_all') {
203                {
204                    action_name   => $actions{$action},
205                    action_value  => $action,
206                    blog_name     => $plugin->translate('* All Weblogs'),
207                    blog_id       => $id,
208                    trigger_name  => $triggers{$trigger},
209                    trigger_value => $trigger,
210                };
211            } elsif (my $blog = MT::Blog->load($id, { cached_ok => 1 })) {
212                {
213                    action_name   => $actions{$action},
214                    action_value  => $action,
215                    blog_name     => $blog->name,
216                    blog_id       => $id,
217                    trigger_name  => $triggers{$trigger},
218                    trigger_value => $trigger,
219                };
220            } else {
221                ();
222            }
223        } split ( /\|/, $rebuild_triggers );
224        $args->{rebuilds_loop} = \@rebuilds;
225    }
226    my $app = MT->instance;
227    if ($app->isa('MT::App')) {
228        $args->{blog_id} = $app->blog->id if $app->blog;
229    }
230}
231
232sub save_config {
233    my $plugin = shift;
234    my ($args, $scope) = @_;
235
236    $plugin->SUPER::save_config(@_);
237
238    my ($blog_id);
239    if ( $scope =~ /blog:(\d+)/ ) {
240        $blog_id = $1;
241
242        # Save blog-level content aggregation policy to single
243        # system config hash for easy lookup
244        my ($cfg_old, $cfg_new) = 0;
245        my $override = 
246            $plugin->get_config_value( 'access_overrides', "system" ) || {};
247        $cfg_new = $args->{blog_content_accessible};
248        if ( exists $override->{$blog_id} ) {
249            $cfg_old = $override->{$blog_id};
250        }
251        if ( $cfg_old != $cfg_new ) {
252            $override->{$blog_id} = $cfg_new 
253                or delete $override->{$blog_id};
254            $plugin->set_config_value( 'access_overrides'
255                                     , $override
256                                     , 'system' );
257        }
258
259        # Fiddle with rebuild triggers...
260        my $rebuild_triggers = $args->{rebuild_triggers};
261        my $old_triggers     = $args->{old_rebuild_triggers};
262
263        # Check to see if the triggers changed
264        if ( $old_triggers ne $rebuild_triggers ) {
265            # If so, remove all references to the current blog from the triggers cached in other blogs
266            foreach ( split ( /\|/, $old_triggers ) ) {
267                my ( $action, $id, $trigger ) = split ( /:/, $_ );
268                my $name = $id eq '_all' ? "all_triggers" : "other_triggers";
269                my $scope = $id eq '_all' ? "system" : "blog:$id";
270                my $d = $plugin->get_config_value($name, $scope);
271                next unless exists $d->{$trigger}{$blog_id};
272                delete $d->{$trigger}{$blog_id};
273                $plugin->set_config_value($name, $d, $scope);
274            }
275        }
276        foreach ( split ( /\|/, $rebuild_triggers ) ) {
277            my ($action, $id, $trigger) = split ( /:/, $_ );
278            my $name = $id eq '_all' ? "all_triggers" : "other_triggers";
279            my $scope = $id eq '_all' ? "system" : "blog:$id";
280            my $d = $plugin->get_config_value($name, $scope) || {};
281            $d->{$trigger}{$blog_id}{$action} = 1;
282            $plugin->set_config_value($name, $d, $scope);
283        }
284    }
285}
286
287sub reset_config {
288    my $plugin = shift;
289    my ($args, $scope) = @_;
290
291    if ( $scope =~ /blog:(\d+)/ ) {
292        my $blog_id = $1;
293
294        # Get the blogs this one triggers from and update them
295        # And then save the triggers this blog runs
296        my $other_triggers =
297            $plugin->get_config_value( 'other_triggers', $scope );
298        my $rebuild_triggers =
299            $plugin->get_config_value( 'rebuild_triggers', $scope );
300        my $all_triggers =
301            $plugin->get_config_value( 'all_triggers', 'system' );
302
303        foreach ( split ( /\|/, $rebuild_triggers ) ) {
304            my ( $action, $id, $trigger ) = split ( /:/, $_ );
305            next if $id eq '_all';
306            my $d = $plugin->get_config_value( 'other_triggers', "blog:$id" );
307            delete $d->{$trigger}{$blog_id}
308                if exists $d->{$trigger}{$blog_id};
309            $plugin->set_config_value( 'other_triggers', $d, "blog:$id" );
310        }
311        # remove this blog from the 'all_triggers'
312        if ($all_triggers) {
313            my $changed = 0;
314            foreach my $trigger (keys %$all_triggers) {
315                if (exists $all_triggers->{$trigger}{$blog_id}) {
316                    delete $all_triggers->{$trigger}{$blog_id};
317                    $changed = 1;
318                }
319            }
320            if ($changed) {
321                $plugin->set_config_value('all_triggers', $all_triggers, 'system');
322            }
323        }
324        $plugin->SUPER::reset_config(@_);
325        $plugin->set_config_value( 'other_triggers', $other_triggers,
326            "blog:$blog_id" );
327    }
328    else {
329        # reset should not alter the 'all_triggers' element which is
330        # configured through the blog-level settings
331        my $all_triggers = $plugin->get_config_value('all_triggers');
332        $plugin->SUPER::reset_config(@_);
333        $plugin->set_config_value('all_triggers', $all_triggers, 'system');
334    }
335}
336
337# Run-time loading for MultiBlog core methods
338sub runner {
339    my $plugin = shift;
340    my $method = shift;
341    require MultiBlog;
342    no strict 'refs';
343    return $_->( $plugin, @_ ) if $_ = \&{"MultiBlog::$method"};
344    die "Failed to find MultiBlog::$method";
345}
346
3471;
Note: See TracBrowser for help on using the browser.