root/branches/release-30/lib/MT/CMS/Blog.pm @ 1387

Revision 1387, 74.5 kB (checked in by bchoate, 21 months ago)

Fix for ping_continuation call.

  • Property svn:keywords set to Id Revision
Line 
1package MT::CMS::Blog;
2
3use strict;
4
5sub edit {
6    my $cb = shift;
7    my ($app, $id, $obj, $param) = @_;
8
9    my $q = $app->param;
10    my $cfg = $app->config;
11    my $blog = $app->blog;
12    my $blog_id = $id;
13
14    if ($id) {
15        require MT::IPBanList;
16        my $output = $param->{output} || '';
17        $param->{need_full_rebuild}  = 1 if $q->param('need_full_rebuild');
18        $param->{need_index_rebuild} = 1 if $q->param('need_index_rebuild');
19        $param->{show_ip_info} = $cfg->ShowIPInformation;
20        $param->{use_plugins} = $cfg->UsePlugins;
21
22        my $entries_on_index = ( $obj->entries_on_index || 0 );
23        if ($entries_on_index) {
24            $param->{'list_on_index'} = $entries_on_index;
25            $param->{'posts'}         = 1;
26        }
27        else {
28            $param->{'list_on_index'} = ( $obj->days_on_index || 0 );
29            $param->{'days'} = 1;
30        }
31        my $lang = $obj->language || 'en';
32        $lang = 'en' if lc($lang) eq 'en-us' || lc($lang) eq 'en_us';
33        $lang = 'ja' if lc($lang) eq 'jp';
34        $param->{ 'language_' . $lang } = 1;
35
36        $param->{system_allow_comments} = $cfg->AllowComments;
37        $param->{system_allow_pings}    = $cfg->AllowPings;
38        $param->{tk_available}          = eval { require MIME::Base64; 1; }
39          && eval { require LWP::UserAgent; 1 };
40        $param->{'auto_approve_commenters'} =
41          !$obj->manual_approve_commenters;
42        $param->{identity_system}     = $app->config('IdentitySystem');
43        $param->{handshake_return}    = $app->base . $app->mt_uri;
44        $param->{"moderate_comments"} = $obj->moderate_unreg_comments;
45        $param->{ "moderate_comments_"
46              . ( $obj->moderate_unreg_comments || 0 ) } = 1;
47        $param->{ "moderate_pings_" . ( $obj->moderate_pings || 0 ) } = 1;
48
49        my $cmtauth_reg = $app->registry('commenter_authenticators');
50        foreach my $auth ( keys %$cmtauth_reg ) {
51            $cmtauth_reg->{$auth}->{disabled} = 1
52              if exists( $cmtauth_reg->{$auth}->{condition} )
53              && !( $cmtauth_reg->{$auth}->{condition}->() );
54        }
55        if ( my $auths = $blog->commenter_authenticators ) {
56            foreach ( split ',', $auths ) {
57                if ( 'MovableType' eq $_ ) {
58                    $param->{enabled_MovableType} = 1;
59                }
60                else {
61                    $cmtauth_reg->{$_}->{enabled} = 1;
62                }
63            }
64        }
65        my @cmtauth_loop;
66        foreach ( keys %$cmtauth_reg ) {
67            $cmtauth_reg->{$_}->{key} = $_;
68            if (
69                UNIVERSAL::isa(
70                    $cmtauth_reg->{$_}->{plugin}, 'MT::Plugin'
71                )
72              )
73            {
74                push @cmtauth_loop, $cmtauth_reg->{$_};
75            }
76        }
77        unshift @cmtauth_loop, $cmtauth_reg->{'TypeKey'}
78          if exists( $cmtauth_reg->{'TypeKey'} )
79          && $blog->remote_auth_token;
80        unshift @cmtauth_loop, $cmtauth_reg->{'Vox'}
81          if exists $cmtauth_reg->{'Vox'};
82        unshift @cmtauth_loop, $cmtauth_reg->{'LiveJournal'}
83          if exists $cmtauth_reg->{'LiveJournal'};
84        unshift @cmtauth_loop, $cmtauth_reg->{'OpenID'}
85          if exists $cmtauth_reg->{'OpenID'};
86
87        $param->{cmtauth_loop} = \@cmtauth_loop;
88
89        if ( $output eq 'cfg_prefs.tmpl' ) {
90            $app->add_breadcrumb( $app->translate('General Settings') );
91
92            my $lang = $obj->language || 'en';
93            $lang = 'en' if lc($lang) eq 'en-us' || lc($lang) eq 'en_us';
94            $lang = 'ja' if lc($lang) eq 'jp';
95            $param->{ 'language_' . $lang } = 1;
96
97            if ( $obj->cc_license ) {
98                $param->{cc_license_name} =
99                  MT::Util::cc_name( $obj->cc_license );
100                $param->{cc_license_image_url} =
101                  MT::Util::cc_image( $obj->cc_license );
102                $param->{cc_license_url} =
103                  MT::Util::cc_url( $obj->cc_license );
104            }
105        }
106        elsif ( $output eq 'cfg_entry.tmpl' ) {
107            ## load entry preferences for new/edit entry page of the blog
108            my $pref_param = $app->load_entry_prefs;
109            %$param = ( %$param, %$pref_param );
110            $param->{ 'sort_order_posts_'
111                  . ( $obj->sort_order_posts || 0 ) } = 1;
112            $param->{ 'status_default_' . $obj->status_default } = 1
113              if $obj->status_default;
114            $param->{ 'allow_comments_default_'
115                  . ( $obj->allow_comments_default || 0 ) } = 1;
116            $param->{system_allow_pings} =
117              $cfg->AllowPings && $blog->allow_pings;
118            $param->{system_allow_comments} = $cfg->AllowComments
119              && ( $blog->allow_reg_comments
120                || $blog->allow_unreg_comments );
121            my $replace_fields = $blog->smart_replace_fields || '';
122            my @replace_fields = split( /,/, $replace_fields );
123            foreach my $fld (@replace_fields) {
124                $param->{ 'nwc_' . $fld } = 1;
125            }
126            $param->{ 'nwc_smart_replace_' . ( $blog->smart_replace || 0 ) } = 1;
127            $param->{ 'nwc_replace_none' } = ( $blog->smart_replace || 0 ) == 2;
128        }
129        elsif ( $output eq 'cfg_web_services.tmpl' ) {
130            $param->{system_disabled_notify_pings} =
131              $cfg->DisableNotificationPings;
132            $param->{system_allow_outbound_pings} =
133              $cfg->OutboundTrackbackLimit eq 'any';
134            my %selected_pings = map { $_ => 1 }
135              split ',', ($obj->update_pings || '');
136            my $pings = $app->registry('ping_servers');
137            my @pings;
138            push @pings,
139              {
140                key   => $_,
141                label => $pings->{$_}->{label},
142                exists( $selected_pings{$_} ) ? ( selected => 1 ) : (),
143              } foreach keys %$pings;
144            $param->{pings_loop} = \@pings;
145        }
146        elsif ( $output eq 'cfg_comments.tmpl' ) {
147            $param->{email_new_comments_1} =
148              ( $obj->email_new_comments || 0 ) == 1;
149            $param->{email_new_comments_2} =
150              ( $obj->email_new_comments || 0 ) == 2;
151            $param->{nofollow_urls}     = $obj->nofollow_urls;
152            $param->{follow_auth_links} = $obj->follow_auth_links;
153            $param->{ 'sort_order_comments_'
154                  . ( $obj->sort_order_comments || 0 ) } = 1;
155            $param->{global_sanitize_spec} = $cfg->GlobalSanitizeSpec;
156            $param->{ 'sanitize_spec_' . ( $obj->sanitize_spec ? 1 : 0 ) } =
157              1;
158            $param->{sanitize_spec_manual} = $obj->sanitize_spec
159              if $obj->sanitize_spec;
160            $param->{allow_comments} = $blog->allow_reg_comments
161              || $blog->allow_unreg_comments;
162            $param->{use_comment_confirmation} =
163              defined $blog->use_comment_confirmation
164              ? $blog->use_comment_confirmation
165              : 0;
166            $param->{system_allow_comments} = $cfg->AllowComments
167              && ( $blog->allow_reg_comments
168                || $blog->allow_unreg_comments );
169            my @cps = MT->captcha_providers;
170
171            foreach my $cp (@cps) {
172                if ( ( $blog->captcha_provider || '' ) eq $cp->{key} ) {
173                    $cp->{selected} = 1;
174                }
175            }
176            $param->{captcha_loop} = \@cps;
177        }
178        elsif ( $output eq 'cfg_trackbacks.tmpl' ) {
179            $param->{email_new_pings_1} = ( $obj->email_new_pings || 0 ) == 1;
180            $param->{email_new_pings_2} = ( $obj->email_new_pings || 0 ) == 2;
181            $param->{nofollow_urls}     = $obj->nofollow_urls;
182            $param->{system_allow_selected_pings} =
183              $cfg->OutboundTrackbackLimit eq 'selected';
184            $param->{system_allow_outbound_pings} =
185              $cfg->OutboundTrackbackLimit eq 'any';
186            $param->{system_allow_local_pings} =
187                 ( $cfg->OutboundTrackbackLimit eq 'local' )
188              || ( $cfg->OutboundTrackbackLimit eq 'any' );
189        }
190        elsif ( $output eq 'cfg_registration.tmpl' ) {
191            $param->{commenter_authenticators} =
192              $obj->commenter_authenticators;
193            my $registration = $cfg->CommenterRegistration;
194            if ( $registration->{Allow} ) {
195                $param->{registration} =
196                  $blog->allow_commenter_regist ? 1 : 0;
197            }
198            else {
199                $param->{system_disallow_registration} = 1;
200            }
201            $param->{allow_reg_comments} = $blog->allow_reg_comments;
202            $param->{allow_unreg_comments} = $blog->allow_unreg_comments;
203            $param->{require_typekey_emails} = $obj->require_typekey_emails;
204        }
205        elsif ( $output eq 'cfg_spam.tmpl' ) {
206            my $threshold = $obj->junk_score_threshold || 0;
207            $threshold = '+' . $threshold if $threshold > 0;
208            $param->{junk_score_threshold} = $threshold;
209            $param->{junk_folder_expiry}   = $obj->junk_folder_expiry || 60;
210            $param->{auto_delete_junk}     = $obj->junk_folder_expiry;
211        }
212        elsif ( $output eq 'cfg_archives.tmpl' ) {
213            $app->add_breadcrumb( $app->translate('Publishing Settings') );
214            if (   $obj->column('archive_path')
215                || $obj->column('archive_url') )
216            {
217                $param->{enable_archive_paths} = 1;
218                $param->{archive_path}         = $obj->column('archive_path');
219                $param->{archive_url}          = $obj->column('archive_url');
220            }
221            else {
222                $param->{archive_path} = '';
223                $param->{archive_url}  = '';
224            }
225            $param->{ 'archive_type_preferred_'
226                  . $blog->archive_type_preferred } = 1
227              if $blog->archive_type_preferred;
228            my $at = $blog->archive_type;
229            if ( $at && $at ne 'None' ) {
230                my @at = split /,/, $at;
231                for my $at (@at) {
232                    $param->{ 'archive_type_' . $at } = 1;
233                }
234            }
235            if ( $blog->publish_queue ) {
236                $param->{publish_queue} = 1;
237            }
238        }
239        elsif ( $output eq 'cfg_plugin.tmpl' ) {
240            $app->add_breadcrumb( $app->translate('Plugin Settings') );
241            $param->{blog_view} = 1;
242            require MT::CMS::Plugin;
243            MT::CMS::Plugin::build_plugin_table( $app,
244                param => $param,
245                scope => 'blog:' . $blog_id
246            );
247            $param->{can_config} = 1;
248        }
249        else {
250            $app->add_breadcrumb( $app->translate('Settings') );
251        }
252        ( my $offset = $obj->server_offset ) =~ s![-\.]!_!g;
253        $offset =~ s!_0+$!!; # fix syntax highlight ->!
254        $param->{ 'server_offset_' . $offset } = 1;
255        if ( $output eq 'cfg_comments.tmpl' ) {
256            ## Load text filters.
257            $param->{text_filters_comments} =
258              $app->load_text_filters( $obj->convert_paras_comments,
259                'comment' );
260        }
261        elsif ( $output eq 'cfg_entry.tmpl' ) {
262            ## Load text filters.
263            $param->{text_filters} =
264              $app->load_text_filters( $obj->convert_paras, 'entry' );
265        }
266        $param->{nav_config} = 1;
267        $param->{error} = $app->errstr if $app->errstr;
268    } else {
269        $app->add_breadcrumb( $app->translate('New Blog') );
270        ( my $tz = $cfg->DefaultTimezone ) =~ s![-\.]!_!g;
271        $tz =~ s!_00$!!; # fix syntax highlight ->!
272        $param->{ 'server_offset_' . $tz } = 1;
273        $param->{'can_edit_config'}        = $app->user->can_create_blog;
274        $param->{'can_set_publish_paths'}  = $app->user->can_create_blog;
275
276        my $sets = $app->registry("template_sets");
277        $sets->{$_}{key} = $_ for keys %$sets;
278        $sets->{'mt_blog'}{selected} = 1;
279        $sets = $app->filter_conditional_list([ values %$sets ]);
280        no warnings;
281        @$sets = sort { $a->{order} <=> $b->{order} } @$sets;
282        $param->{'template_set_loop'} = $sets;
283        $param->{'template_set_index'} = $#$sets;
284    }
285
286    if (   !$param->{site_path}
287        && !( $param->{site_path} = $app->config('DefaultSiteRoot') ) )
288    {
289        my $cwd = $app->document_root;
290        $cwd = File::Spec->catdir($cwd, 'BLOG-NAME'); # for including the end of directory separator
291        $cwd =~ s!BLOG-NAME\z!!;                      # canonpath() remove it
292        $cwd =~ s!([\\/])cgi(?:-bin)?([\\/].*)?$!$1!;
293        $cwd =~ s!([\\/])mt[\\/]?$!$1!i;
294        $param->{suggested_site_path} = $cwd;
295    }
296    if ( !$param->{id} ) {
297        if ( $param->{site_path} ) {
298            $param->{site_path} =
299              File::Spec->catdir( $param->{site_path}, 'BLOG-NAME' );
300        }
301        else {
302            $param->{suggested_site_path} =
303              File::Spec->catdir( $param->{suggested_site_path},
304                'BLOG-NAME' );
305        }
306    }
307
308    # If not yet defined, set the site_url to the config default, if one exists.
309    $param->{site_url} ||= $app->config('DefaultSiteURL');
310    if ( !$param->{site_url} ) {
311        $param->{suggested_site_url} = $app->base . '/';
312        $param->{suggested_site_url} =~ s!/cgi(?:-bin)?(/.*)?$!/!;
313        $param->{suggested_site_url} =~ s!/mt/?$!/!i;
314    }
315    if ( !$param->{id} ) {
316        if ( $param->{site_url} ) {
317            $param->{site_url} .= '/'
318              unless $param->{site_url} =~ /\/$/;
319            $param->{site_url} .= 'BLOG-NAME/';
320        }
321        else {
322            $param->{suggested_site_url} .= '/'
323              unless $param->{suggested_site_url} =~ /\/$/;
324            $param->{suggested_site_url} .= 'BLOG-NAME/';
325        }
326    }
327    1;
328}
329
330sub list {
331    my $app = shift;
332
333    $app->return_to_dashboard( redirect => 1 ) if $app->param('blog_id');
334
335    my $author    = $app->user;
336    my $list_pref = $app->list_pref('blog');
337
338    my $limit  = $list_pref->{rows};
339    my $offset = $app->param('offset') || 0;
340    my $args   = { offset => $offset, sort => 'name' };
341    $args->{limit} = $limit + 1;
342    unless ( $author->is_superuser ) {
343        $args->{join} = MT::Permission->join_on(
344            'blog_id',
345            { author_id => $author->id },
346            { unique    => 1 }
347        );
348    }
349    my $blog_class       = $app->model('blog');
350    my %param            = %$list_pref;
351    my @blogs            = $blog_class->load( undef, $args );
352    my $can_edit_authors = $author->is_superuser;
353    my $blog_loop        = make_blog_list( $app, \@blogs );
354
355    if ($blog_loop) {
356        ## We tried to load $limit + 1 entries above; if we actually got
357        ## $limit + 1 back, we know we have another page of entries.
358        my $have_next = @$blog_loop > $limit;
359        pop @$blog_loop while @$blog_loop > $limit;
360        if ($offset) {
361            $param{prev_offset}     = 1;
362            $param{prev_offset_val} = $offset - $limit;
363            $param{prev_offset_val} = 0 if $param{prev_offset_val} < 0;
364        }
365        if ($have_next) {
366            $param{next_offset}     = 1;
367            $param{next_offset_val} = $offset + $limit;
368        }
369    }
370    $param{offset}      = $offset;
371    $param{object_type} = 'blog';
372    $param{list_start}  = $offset + 1;
373    delete $args->{limit};
374    delete $args->{offset};
375    $param{list_total} = $blog_class->count( undef, $args );
376    $param{list_end}        = $offset + ( $blog_loop ? scalar @$blog_loop : 0 );
377    $param{next_max}        = $param{list_total} - $limit;
378    $param{next_max}        = 0 if ( $param{next_max} || 0 ) < $offset + 1;
379    $param{can_create_blog} = $author->can_create_blog;
380    $param{saved_deleted}   = $app->param('saved_deleted');
381    $param{refreshed}       = $app->param('refreshed');
382    $param{nav_blogs}       = 1;
383    $param{list_noncron}    = 1;
384    $param{search_label}    = $app->translate('Blogs');
385
386    if ($blog_loop) {
387        $param{object_loop} = $param{blog_table}[0]{object_loop} = $blog_loop;
388        $app->load_list_actions( 'blog', \%param );
389    }
390
391    $param{page_actions} = $app->page_actions('list_blog');
392    $param{feed_name}    = $app->translate("Blog Activity Feed");
393    $param{feed_url}     = $app->make_feed_link('blog');
394    $app->add_breadcrumb( $app->translate("Blogs") );
395    $param{nav_weblogs} = 1;
396    $param{object_label} = $blog_class->class_label;
397    $param{object_label_plural} = $blog_class->class_label_plural;
398    $param{screen_class} = "list-blog";
399    $param{screen_id} = "list-blog";
400    $param{listing_screen} = 1;
401    return $app->load_tmpl( 'list_blog.tmpl', \%param );
402}
403
404sub cfg_archives {
405    my $app = shift;
406    my %param;
407    %param = %{ $_[0] } if $_[0];
408    my $q = $app->param;
409
410    my $blog_id = $q->param('blog_id');
411
412    return $app->return_to_dashboard( redirect => 1 ) unless $blog_id;
413
414    my $blog = $app->model('blog')->load($blog_id);
415    my @data;
416    for my $at ( split /\s*,\s*/, $blog->archive_type ) {
417        my $archiver = $app->publisher->archiver($at);
418        next unless $archiver;
419        next if 'entry' ne $archiver->entry_class;
420        my $archive_label = $archiver->archive_label;
421        $archive_label = $at unless $archive_label;
422        $archive_label = $archive_label->() if ( ref $archive_label ) eq 'CODE';
423        push @data,
424          {
425            archive_type_translated => $archive_label,
426            archive_type            => $at,
427            archive_type_is_preferred =>
428              ( $blog->archive_type_preferred eq $at ? 1 : 0 ),
429          };
430    }
431    @data = sort { MT::App::CMS::archive_type_sorter( $a, $b ) } @data;
432    $param{entry_archive_types} = \@data;
433    $param{saved_deleted}       = 1 if $q->param('saved_deleted');
434    $param{saved_added}         = 1 if $q->param('saved_added');
435    $param{archives_changed}    = 1 if $q->param('archives_changed');
436    $param{no_writedir}         = $q->param('no_writedir');
437    $param{no_cachedir}         = $q->param('no_cachedir');
438    $param{no_writecache}       = $q->param('no_writecache');
439    $param{dynamic_none}        = $blog->custom_dynamic_templates eq 'none';
440    $param{dynamic_archives}    = $blog->custom_dynamic_templates eq 'archives';
441    $param{dynamic_custom}      = $blog->custom_dynamic_templates eq 'custom';
442    $param{dynamic_all}         = $blog->custom_dynamic_templates eq 'all';
443
444    if ( $app->config->ObjectDriver =~ qr/(db[id]::)?sqlite/i ) {
445        $param{hide_build_option} = 1
446          unless $app->config->UseSQLite2;
447    }
448    my $mtview_path = File::Spec->catfile( $blog->site_path(), "mtview.php" );
449
450    if ( -f $mtview_path ) {
451        open my ($fh), $mtview_path;
452        while ( my $line = <$fh> ) {
453            $param{dynamic_caching} = 1
454              if $line =~ m/^\s*\$mt->caching\s*=\s*true;/i;
455            $param{dynamic_conditional} = 1
456              if $line =~ /^\s*\$mt->conditional\s*=\s*true;/i;
457        }
458        close $fh;
459    }
460    $param{output} = 'cfg_archives.tmpl';
461    $q->param( '_type', 'blog' );
462    $q->param( 'id',    $blog_id );
463    $param{screen_class} = "settings-screen archive-settings";
464    $param{object_type}  = 'author';
465    $param{search_label} = $app->translate('Users');
466    $app->forward( "view", \%param );
467}
468
469sub cfg_prefs {
470    my $app     = shift;
471    my $q       = $app->param;
472    my $blog_id = scalar $q->param('blog_id');
473    return $app->return_to_dashboard( redirect => 1 )
474      unless $blog_id;
475    $q->param( '_type', 'blog' );
476    $q->param( 'id',    $blog_id );
477    my $blog_prefs = $app->user_blog_prefs;
478    my $perms      = $app->permissions;
479    return $app->error( $app->translate('Permission denied.') )
480      unless $app->user->is_superuser()
481      || (
482        $perms
483        && (   $perms->can_edit_config
484            || $perms->can_administer_blog
485            || $perms->can_set_publish_paths )
486      );
487    my $output = 'cfg_prefs.tmpl';
488    $app->forward("view",
489        {
490            output       => $output,
491            screen_class => 'settings-screen general-screen'
492        }
493    );
494}
495
496sub cfg_web_services {
497    my $app     = shift;
498    my $q       = $app->param;
499    my $blog_id = scalar $q->param('blog_id');
500    return $app->return_to_dashboard( redirect => 1 )
501      unless $blog_id;
502    $q->param( '_type', 'blog' );
503    $q->param( 'id',    scalar $q->param('blog_id') );
504    $app->forward( "view",
505        {
506            output       => 'cfg_web_services.tmpl',
507            screen_class => 'settings-screen web-services-settings'
508        }
509    );
510}
511
512sub rebuild_phase {
513    my $app  = shift;
514    my $type = $app->param('_type') || 'entry';
515    my @ids  = $app->param('id');
516    $app->{goback} = "window.location='" . $app->return_uri . "'";
517    $app->{value} ||= $app->translate('Go Back');
518    if ( $type eq 'entry' ) {
519        my %ids = map { $_ => 1 } @ids;
520        return $app->rebuild_these( \%ids );
521    }
522    elsif ( $type eq 'template' ) {
523        require MT::Template;
524        foreach (@ids) {
525            my $template = MT::Template->load($_);
526            $app->rebuild_indexes(
527                Template => $template,
528                Force    => 1
529            ) or return;
530        }
531    }
532    $app->call_return;
533}
534
535sub rebuild_pages {
536    my $app   = shift;
537    my $perms = $app->permissions
538      or return $app->error( $app->translate("No permissions") );
539    require MT::Entry;
540    require MT::Blog;
541    my $q             = $app->param;
542    my $blog_id       = $q->param('blog_id');
543    my $blog          = MT::Blog->load($blog_id);
544    my $order         = $q->param('type');
545    my @order         = split /,/, $order;
546    my $next          = $q->param('next');
547    my $done          = 0;
548    my $type          = $order[$next];
549    my $archiver      = $app->publisher->archiver($type);
550    my $archive_label = $archiver ? $archiver->archive_label : '';
551    $archive_label = $app->translate($type) unless $archive_label;
552    $archive_label = $archive_label->() if ( ref $archive_label ) eq 'CODE';
553    $next++;
554    $done++ if $next >= @order;
555    my $offset = 0;
556    my ($total) = $q->param('total');
557
558    ## Tells MT::_rebuild_entry_archive_type to cache loaded templates so
559    ## that each template is only loaded once.
560    $app->{cache_templates} = 1;
561
562    my ($tmpl_saved);
563
564    # Make sure errors go to a sensible place when in fs mode
565    # TODO: create contin. earlier, pass it thru
566    if ( $app->param('fs') ) {
567        my ( $type, $obj_id ) = $app->param('type') =~ m/(entry|index)-(\d+)/;
568        if ( $type && $obj_id ) {
569            my $edit_type = $type;
570            $edit_type = 'template' if $type eq 'index';
571            if ($type eq 'entry') {
572                require MT::Entry;
573                my $entry = MT::Entry->load($obj_id);
574                $edit_type = $entry->class;
575            }
576            $app->{goback} =
577              "window.location='"
578              . $app->object_edit_uri( $edit_type, $obj_id ) . "'";
579            $app->{value} ||= $app->translate('Go Back');
580        }
581    }
582
583    # FIXME: Wrap the entire rebuild operation with begin/end callbacks
584    if ( $type eq 'all' ) {
585        return $app->error( $app->translate("Permission denied.") )
586          unless $perms->can_rebuild;
587
588        # FIXME: Rebuild the entire blog????
589        $app->rebuild( BlogID => $blog_id )
590          or return $app->publish_error();
591    }
592    elsif ( $type eq 'index' ) {
593        return $app->error( $app->translate("Permission denied.") )
594          unless $perms->can_rebuild;
595        $app->rebuild_indexes( BlogID => $blog_id )
596            or return $app->publish_error();
597    }
598    elsif ( $type =~ /^index-(\d+)$/ ) {
599        return $app->error( $app->translate("Permission denied.") )
600          unless $perms->can_rebuild;
601        my $tmpl_id = $1;
602        require MT::Template;
603        $tmpl_saved = MT::Template->load($tmpl_id);
604        $app->rebuild_indexes(
605            BlogID   => $blog_id,
606            Template => $tmpl_saved,
607            Force    => 1
608        ) or return $app->publish_error();
609        $order = $app->translate( "index template '[_1]'", $tmpl_saved->name );
610    }
611    elsif ( $type =~ /^entry-(\d+)$/ ) {
612        my $entry_id = $1;
613        require MT::Entry;
614        my $entry = MT::Entry->load($entry_id);
615        return $app->error( $app->translate("Permission denied.") )
616          unless $perms->can_edit_entry( $entry, $app->user );
617        $app->rebuild_entry(
618            Entry             => $entry,
619            BuildDependencies => 1,
620            OldPrevious       => $q->param('old_previous'),
621            OldNext           => $q->param('old_next')
622        ) or return $app->publish_error();
623        $order = "entry '" . $entry->title . "'";
624    }
625    elsif ( $archiver->category_based ) {
626        return $app->error( $app->translate("Permission denied.") )
627          unless $perms->can_rebuild;
628        $offset = $q->param('offset') || 0;
629        my $start = time;
630        my $count = 0;
631        my $cb    = sub {
632            return 0 if time - $start > 20;    # 10 seconds
633            $count++;
634            return 1;
635        };
636        if ( $offset < $total ) {
637            $app->rebuild(
638                BlogID         => $blog_id,
639                ArchiveType    => $type,
640                NoIndexes      => 1,
641                Offset         => $offset,
642                FilterCallback => $cb,
643            ) or return $app->publish_error();
644            $offset += $count;
645        }
646        if ( $offset < $total ) {
647            $done-- if $done;
648            $next--;
649        }
650        else {
651            $offset = 0;
652        }
653    }
654    elsif ($type) {
655        my $special = 0;
656        my @options = $app->{rebuild_options} ||= {};
657        $app->run_callbacks( 'rebuild_options', $app, \@options );
658        for my $optn (@options) {
659            if ( ( $optn->{key} || '' ) eq $type ) {
660                $optn->{code}->();
661                $special = 1;
662            }
663        }
664        if ( !$special ) {
665            return $app->error( $app->translate("Permission denied.") )
666              unless $perms->can_rebuild;
667            $offset = $q->param('offset') || 0;
668            if ( $offset < $total ) {
669                my $start = time;
670                my $count = 0;
671                my $cb    = sub {
672                    return 0 if time - $start > 20;    # 10 seconds
673                    $count++;
674                    return 1;
675                };
676                $app->rebuild(
677                    BlogID         => $blog_id,
678                    ArchiveType    => $type,
679                    NoIndexes      => 1,
680                    Offset         => $offset,
681                    FilterCallback => $cb,
682                ) or return $app->publish_error();
683                $offset += $count;
684            }
685            if ( $offset < $total ) {
686                $done-- if $done;
687                $next--;
688            }
689            else {
690                $offset = 0;
691            }
692        }
693    }
694
695    # Rebuild done--now form the continuation.
696    unless ($done) {
697        my $dynamic   = 0;
698        my $type_name = $order[$next];
699
700        ## If we're moving on to the next rebuild step, recalculate the
701        ## limit.
702        my $static_count;
703        if ( $type_name !~ m/^index/ ) {
704            $static_count = $blog->count_static_templates($type_name) || 0;
705        }
706        else {
707            $static_count = 1;
708        }
709        if ( !$static_count ) {
710            $dynamic = 1;
711        }
712        elsif ( defined($offset) && $offset == 0 ) {
713            $dynamic = 0;
714        }
715        if ( $offset == 0 ) {
716
717            # determine total
718            if ( my $archiver = $app->publisher->archiver($type_name) ) {
719                if ( $archiver->entry_based || $archiver->date_based ) {
720                    my $entry_class = $archiver->entry_class || 'entry';
721                    require MT::Entry;
722                    my $terms = {
723                        class   => $entry_class,
724                        status  => MT::Entry::RELEASE(),
725                        blog_id => $blog_id,
726                    };
727                    $total = MT::Entry->count($terms);
728                }
729                elsif ( $archiver->category_based ) {
730                    require MT::Category;
731                    my $terms = { blog_id => $blog_id, };
732                    $total = MT::Category->count($terms);
733                }
734                elsif ( $archiver->author_based ) {
735                    require MT::Author;
736                    require MT::Entry;
737                    my $terms = {
738                        blog_id => $blog_id,
739                        status  => MT::Entry::RELEASE(),
740                        class   => 'entry',
741                    };
742                    $total = MT::Author->count(
743                        undef,
744                        {
745                            join   => MT::Entry->join_on( 'author_id', $terms, { unique => 1 } ),
746                            unique => 1,
747                        }
748                    );
749                }
750            }
751        }
752
753        my $type = $order[$next];
754        if ($type) {
755            $archiver      = $app->publisher->archiver($type);
756            $archive_label = $archiver ? $archiver->archive_label : '';
757            $archive_label = $app->translate($type) unless $archive_label;
758            $archive_label = $archive_label->()
759              if ( ref $archive_label ) eq 'CODE';
760        }
761
762        my $complete =
763          $total
764          ? ( $total == $offset ? 100 : int( ( $offset / $total ) * 100 ) )
765          : 0;
766
767        my %param = (
768            build_type      => $order,
769            build_next      => $next,
770            build_type_name => $archive_label,
771            archives        => $archiver ? 1 : 0,
772            total           => $total,
773            offset          => $offset,
774            complete        => $complete,
775            incomplete      => 100 - $complete,
776            entry_id        => scalar $q->param('entry_id'),
777            dynamic         => $dynamic,
778            is_new          => scalar $q->param('is_new'),
779            old_status      => scalar $q->param('old_status')
780        );
781        $app->load_tmpl( 'rebuilding.tmpl', \%param );
782    }
783    else {
784        if ( $q->param('entry_id') ) {
785            require MT::Entry;
786            my $entry = MT::Entry->load( scalar $q->param('entry_id') );
787            require MT::Blog;
788            my $blog = MT::Blog->load( $entry->blog_id );
789            require MT::CMS::Entry;
790            MT::CMS::Entry::ping_continuation( $app,
791                $entry, $blog,
792                OldStatus => scalar $q->param('old_status'),
793                IsNew     => scalar $q->param('is_new'),
794            );
795        }
796        else {
797            my $all          = $order =~ /,/;
798            my $type         = $order;
799            my $is_one_index = $order =~ /index template/;
800            my $is_entry     = $order =~ /entry/;
801            my $built_type;
802            if ( $is_entry || $is_one_index ) {
803                ( $built_type = $type ) =~
804                  s/^(entry|index template)/$app->translate($1)/e;
805            }
806            else {
807                $built_type = $app->translate($type);
808            }
809            my %param = (
810                all          => $all,
811                type         => $archive_label,
812                is_one_index => $is_one_index,
813                is_entry     => $is_entry,
814                archives     => $type ne 'index',
815            );
816            if ($is_one_index) {
817                $param{tmpl_url} = $blog->site_url;
818                $param{tmpl_url} .= '/' if $param{tmpl_url} !~ m!/$!;
819                $param{tmpl_url} .= $tmpl_saved->outfile;
820            }
821            if ( $q->param('fs') ) {    # full screen--go to a useful app page
822                my $type = $q->param('type');
823                $type =~ /index-(\d+)/;
824                my $tmpl_id = $1;
825                $app->run_callbacks( 'rebuild', $blog );
826                return $app->redirect(
827                    $app->uri(
828                        'mode' => 'view',
829                        args   => {
830                            '_type'       => 'template',
831                            id            => $tmpl_id,
832                            blog_id       => $blog->id,
833                            saved_rebuild => 1
834                        }
835                    )
836                );
837            }
838            else {    # popup--just go to cnfrmn. page
839                $app->run_callbacks( 'rebuild', $blog );
840                return $app->load_tmpl( 'popup/rebuilt.tmpl', \%param );
841            }
842        }
843    }
844}
845
846sub rebuild_new_phase {
847    my ($app) = @_;
848    my %reb_set = map { $_ => 1 } $app->param('id');
849    $app->rebuild_these( \%reb_set, how => MT::App::CMS::NEW_PHASE() );
850}
851
852sub start_rebuild_pages {
853    my $app           = shift;
854    my $q             = $app->param;
855    my $type          = $q->param('type');
856    my $next          = $q->param('next') || 0;
857    my @order         = split /,/, $type;
858    my $total         = $q->param('total') || 0;
859    my $type_name     = $order[$next];
860    my $archiver      = $app->publisher->archiver($type_name);
861    my $archive_label = $archiver ? $archiver->archive_label : '';
862    $archive_label = $app->translate($type_name) unless $archive_label;
863    $archive_label = $archive_label->() if ( ref $archive_label ) eq 'CODE';
864    my $blog_id = $q->param('blog_id');
865
866    if ($archiver) {
867        if ( $archiver->entry_based || $archiver->date_based ) {
868            my $entry_class = $archiver->entry_class || 'entry';
869            require MT::Entry;
870            my $terms = {
871                class   => $entry_class,
872                status  => MT::Entry::RELEASE(),
873                blog_id => $blog_id,
874            };
875            $total = MT::Entry->count($terms);
876        }
877        elsif ( $archiver->category_based ) {
878            require MT::Category;
879            my $terms = {
880                blog_id => $blog_id,
881                class   => $archiver->category_class,
882            };
883            $total = MT::Category->count($terms);
884        }
885        elsif ( $archiver->author_based ) {
886            require MT::Author;
887            require MT::Entry;
888            my $terms = {
889                blog_id => $blog_id,
890                status  => MT::Entry::RELEASE(),
891                class => 'entry',
892            };
893            $total = MT::Author->count(
894                undef,
895                {
896                    join   => MT::Entry->join_on( 'author_id', $terms, { unique => 1 } ),
897                    unique => 1,
898                }
899            );
900        }
901    }
902
903    my %param = (
904        build_type      => $type,
905        build_next      => $next,
906        total           => $total,
907        complete        => 0,
908        incomplete      => 100,
909        build_type_name => $archive_label
910    );
911
912    if ( $type_name =~ /^index-(\d+)$/ ) {
913        my $tmpl_id = $1;
914        require MT::Template;
915        my $tmpl = MT::Template->load($tmpl_id);
916        $param{build_type_name} =
917          $app->translate( "index template '[_1]'", $tmpl->name );
918        $param{is_one_index} = 1;
919    }
920    elsif ( $type_name =~ /^entry-(\d+)$/ ) {
921        my $entry_id = $1;
922        require MT::Entry;
923        my $entry = MT::Entry->load($entry_id);
924        $param{build_type_name} =
925          $app->translate( "[_1] '[_2]'", $entry->class_label, $entry->title );
926        $param{is_entry} = 1;
927        $param{entry_id} = $entry_id;
928        for my $col (qw( is_new old_status old_next old_previous )) {
929            $param{$col} = $q->param($col);
930        }
931    }
932    $param{is_full_screen} = ( $param{is_entry} )
933      || $q->param('single_template');
934    $param{page_titles} = [ { bc_name => 'Rebuilding' } ];
935    $app->load_tmpl( 'rebuilding.tmpl', \%param );
936}
937
938sub rebuild_confirm {
939    my $app     = shift;
940    my $blog_id = $app->param('blog_id');
941    require MT::Blog;
942    my $blog = MT::Blog->load($blog_id);
943    my $at = $blog->archive_type || '';
944    my ( @blog_at, @at, @data );
945    my $archiver;
946    my $archive_label;
947
948    if ( $at && $at ne 'None' ) {
949        @blog_at = split /,/, $at;
950        foreach my $t (@blog_at) {
951            $archiver = $app->publisher->archiver($t);
952            next unless $archiver;    # ignore unknown archive types
953            push @at, $t;
954            $archive_label = $archiver->archive_label;
955            $archive_label = $at unless $archive_label;
956            $archive_label = $archive_label->()
957              if ( ref $archive_label ) eq 'CODE';
958            push(
959                @data,
960                {
961                    archive_type       => $t,
962                    archive_type_label => $archive_label
963                }
964            );
965        }
966    }
967    my $order     = join ',', @at, 'index';
968    my $entry_pkg = $app->model('entry');
969    my %param     = (
970        archive_type_loop => \@data,
971        build_order       => $order,
972        build_next        => 0,
973    );
974    $param{index_selected} = ( $app->param('prompt') || "" ) eq 'index';
975
976    if ( my $tmpl_id = $app->param('tmpl_id') ) {
977        require MT::Template;
978        my $tmpl = MT::Template->load($tmpl_id);
979        $param{index_tmpl_id}   = $tmpl->id;
980        $param{index_tmpl_name} = $tmpl->name;
981    }
982    my $options = $app->registry("rebuild_options") || {};
983    my @options;
984    if ($options) {
985        foreach my $opt ( keys %$options ) {
986            $options->{$opt}{key} ||= $opt;
987            push @options, $options->{$opt};
988        }
989    }
990    $app->run_callbacks( 'rebuild_options', $app, \@options );
991    my $rebuild_options = $app->filter_conditional_list( \@options );
992    $param{rebuild_option_loop} = $rebuild_options;
993    $param{refocus}             = 1;
994    $app->add_breadcrumb( $app->translate('Publish Site') );
995    $app->load_tmpl( 'popup/rebuild_confirm.tmpl', \%param );
996}
997
998sub save_favorite_blogs {
999    my $app = shift;
1000    $app->validate_magic() or return;
1001    my $fav = $app->param('id');
1002    return unless int($fav) > 0;
1003    $app->add_to_favorite_blogs($fav);
1004    $app->send_http_header("text/javascript+json");
1005    return 'true';
1006}
1007
1008sub cc_return {
1009    my $app   = shift;
1010    my $code  = $app->param('license_code');
1011    my $url   = $app->param('license_url');
1012    my $image = $app->param('license_button');
1013    my %param = ( license_name => MT::Util::cc_name($code) );
1014    if ($url) {
1015        $param{license_code} = "$code $url $image";
1016    }
1017    else {
1018        $param{license_code} = $code;
1019    }
1020    $app->load_tmpl( 'cc_return.tmpl', \%param );
1021}
1022
1023sub handshake {
1024    my $app               = shift;
1025    my $blog_id           = $app->param('blog_id');
1026    my $remote_auth_token = $app->param('remote_auth_token');
1027
1028    my %param = ();
1029    $param{remote_auth_token} = $remote_auth_token;
1030    $app->load_tmpl( 'handshake_return.tmpl', \%param );
1031}
1032
1033sub update_welcome_message {
1034    my $app = shift;
1035    $app->validate_magic or return;
1036
1037    my $perms = $app->permissions;
1038    return $app->errtrans("Permission denied.")
1039      unless $perms && $perms->can_edit_config;
1040
1041    my $blog_id    = $app->param('blog_id');
1042    my $message    = $app->param('welcome-message-text');
1043    my $blog_class = $app->model('blog');
1044    my $blog       = $blog_class->load($blog_id)
1045      or return $app->error( $app->translate("Invalid blog") );
1046    $blog->welcome_msg($message);
1047    $blog->save;
1048    $app->redirect(
1049        $app->uri( mode => 'menu', args => { blog_id => $blog_id } ) );
1050}
1051
1052sub dialog_select_weblog {
1053    my $app = shift;
1054
1055    #return $app->errtrans("Permission denied.")
1056    #    unless $app->user->is_superuser;
1057
1058    my $favorites = $app->param('select_favorites');
1059    my %favorite;
1060    my $confirm_js;
1061    my $terms = {};
1062    my $args  = {};
1063    if ($favorites) {
1064        my $auth = $app->user or return;
1065        if ( my @favs = @{ $auth->favorite_blogs || [] } ) {
1066            $terms->{id} = \@favs;
1067            $args->{not}{id} = 1;
1068        }
1069        $confirm_js = 'saveFavorite';
1070    }
1071
1072    my $hasher = sub {
1073        my ( $obj, $row ) = @_;
1074        $row->{label} = $row->{name};
1075        $row->{'link'} = $row->{site_url};
1076    };
1077
1078    $app->listing(
1079        {
1080            type     => 'blog',
1081            code     => $hasher,
1082            template => 'dialog/select_weblog.tmpl',
1083            terms    => $terms,
1084            args     => $args,
1085            params   => {
1086                dialog_title  => $app->translate("Select Blog"),
1087                items_prompt  => $app->translate("Selected Blog"),
1088                search_prompt => $app->translate(
1089                    "Type a blog name to filter the choices below."),
1090                panel_label       => $app->translate("Blog Name"),
1091                panel_description => $app->translate("Description"),
1092                panel_type        => 'blog',
1093                panel_multi       => defined $app->param('multi')
1094                ? $app->param('multi')
1095                : 0,
1096                panel_searchable => 1,
1097                panel_first      => 1,
1098                panel_last       => 1,
1099                list_noncron     => 1,
1100                return_url       => $app->uri . '?'
1101                  . ( $app->param('return_args') || '' ),
1102                confirm_js => $confirm_js,
1103                idfield    => ( $app->param('idfield') || '' ),
1104                namefield  => ( $app->param('namefield') || '' ),
1105            },
1106        }
1107    );
1108}
1109
1110sub _populate_archive_loop {
1111    my $app = shift;
1112    my ( $blog, $obj ) = @_;
1113
1114    my $index = $app->config('IndexBasename');
1115    my $ext = $blog->file_extension || '';
1116    $ext = '.' . $ext if $ext ne '';
1117
1118    require MT::TemplateMap;
1119    my @tmpl_maps = MT::TemplateMap->load( { template_id => $obj->id } );
1120    my @maps;
1121    my %types;
1122    foreach my $map_obj (@tmpl_maps) {
1123        my $map = {};
1124        $map->{map_id}           = $map_obj->id;
1125        $map->{map_is_preferred} = $map_obj->is_preferred;
1126        my $at = $map->{archive_type} = $map_obj->archive_type;
1127        $types{$at}++;
1128        $map->{ 'archive_type_preferred_' . $blog->archive_type_preferred } = 1
1129          if $blog->archive_type_preferred;
1130        $map->{file_template} = $map_obj->file_template
1131          if $map_obj->file_template;
1132
1133        my $archiver = $app->publisher->archiver($at);
1134        next unless $archiver;
1135        $map->{archive_label} = $archiver->archive_label;
1136        my $tmpls     = $archiver->default_archive_templates;
1137        my $tmpl_loop = [];
1138        foreach (@$tmpls) {
1139            my $name = $_->{label};
1140            $name =~ s/\.html$/$ext/;
1141            $name =~ s/index$ext$/$index$ext/;
1142            push @$tmpl_loop,
1143              {
1144                name    => $name,
1145                value   => $_->{template},
1146                default => ( $_->{default} || 0 )
1147              };
1148        }
1149
1150        my $custom = 1;
1151
1152        foreach (@$tmpl_loop) {
1153            if (   ( !$map->{file_template} && $_->{default} )
1154                || ( $map->{file_template} eq $_->{value} ) )
1155            {
1156                $_->{selected}        = 1;
1157                $custom               = 0;
1158                $map->{file_template} = $_->{value}
1159                  if !$map->{file_template};
1160            }
1161        }
1162        if ($custom) {
1163            unshift @$tmpl_loop,
1164              {
1165                name     => $map->{file_template},
1166                value    => $map->{file_template},
1167                selected => 1,
1168              };
1169        }
1170
1171        $map->{archive_tmpl_loop} = $tmpl_loop;
1172        if (
1173            1 < MT::TemplateMap->count(
1174                { archive_type => $at, blog_id => $obj->blog_id }
1175            )
1176          )
1177        {
1178            $map->{has_multiple_archives} = 1;
1179        }
1180
1181        push @maps, $map;
1182    }
1183    @maps = sort { MT::App::CMS::archive_type_sorter( $a, $b ) } @maps;
1184    return \@maps;
1185}
1186
1187sub can_view {
1188    my ( $eh, $app, $id ) = @_;
1189    my $perms = $app->permissions;
1190    if ( $id
1191        && ( $perms->can_set_publish_paths && !$perms->can_administer_blog ) )
1192    {
1193        return 1 if 'view' eq $app->mode;
1194    }
1195    if (
1196        (
1197            $id && !(
1198                   $perms->can_edit_config
1199                || $perms->can_set_publish_paths
1200                || $perms->can_manage_feedback
1201            )
1202        )
1203        || ( !$id && !$app->user->can_create_blog )
1204      )
1205    {
1206        return 0;
1207    }
1208    1;
1209}
1210
1211sub can_save {
1212    my ( $eh, $app, $id ) = @_;
1213    my $perms = $app->permissions;
1214    return ( $id
1215          && ( $perms->can_edit_config || $perms->can_set_publish_paths ) )
1216      || ( !$id && $app->user->can_create_blog );
1217}
1218
1219sub can_delete {
1220    my ( $eh, $app, $obj ) = @_;
1221    my $author = $app->user;
1222    return 1 if $author->is_superuser();
1223    require MT::Permission;
1224    my $perms = $author->permissions( $obj->id );
1225    return $perms && $perms->can_administer_blog;
1226}
1227
1228sub pre_save {
1229    my $eh = shift;
1230    my ( $app, $obj ) = @_;
1231    if ( !$app->param('overlay')
1232        && $app->param('cfg_screen') )
1233    {
1234
1235        # Checkbox options have to be blanked if they aren't passed.
1236        my $screen = $app->param('cfg_screen');
1237        my @fields;
1238        if ( $screen eq 'cfg_web_services' ) {
1239        }
1240        elsif ( $screen eq 'cfg_archives' ) {
1241            @fields = qw(file_extension);
1242        }
1243        elsif ( $screen eq 'cfg_templatemaps' ) {
1244        }
1245        elsif ( $screen eq 'cfg_comments' ) {
1246            @fields = qw( allow_comment_html autolink_urls
1247              use_comment_confirmation );
1248        }
1249        elsif ( $screen eq 'cfg_registration' ) {
1250            @fields = qw( allow_commenter_regist
1251              require_comment_emails allow_unreg_comments
1252              require_typekey_emails );
1253        }
1254        elsif ( $screen eq 'cfg_entry' ) {
1255            @fields = qw( allow_comments_default
1256              allow_pings_default );
1257        }
1258        elsif ( $screen eq 'cfg_trackbacks' ) {
1259            @fields = qw( allow_pings moderate_pings
1260              autodiscover_links internal_autodiscovery );
1261        }
1262        elsif ( $screen eq 'cfg_plugins' ) {
1263        }
1264        for my $cb (@fields) {
1265            unless ( defined $app->param($cb) ) {
1266
1267      # two possibilities: user unchecked the option, or user was not allowed to
1268      # set the value (and therefore there was no field to submit).
1269                my $perms = $app->permissions;
1270                if (
1271                    $app->user->is_superuser
1272                    || (
1273                        $perms
1274                        && (   $perms->can_administer_blog
1275                            || $perms->can_edit_config )
1276                    )
1277                  )
1278                {
1279                    $obj->$cb(0);
1280                }
1281                else {
1282                    delete $obj->{column_values}->{$cb};
1283                    delete $obj->{changed_cols}->{$cb};
1284                }
1285            }
1286        }
1287        if ( $screen eq 'cfg_comments' ) {
1288
1289            # value for comments:  1 == Accept from anyone
1290            #                      2 == Accept authenticated only
1291            #                      0 == No comments
1292            if ( $app->param('allow_comments') ) {
1293                $obj->allow_reg_comments(1);
1294            }
1295            else {
1296                $obj->allow_unreg_comments(0);
1297                $obj->allow_reg_comments(0);
1298            }
1299            $obj->moderate_unreg_comments( $app->param('moderate_comments') );
1300            $obj->nofollow_urls( $app->param('nofollow_urls')         ? 1 : 0 );
1301            $obj->follow_auth_links( $app->param('follow_auth_links') ? 1 : 0 );
1302            my $cp_old = $obj->captcha_provider;
1303            $obj->captcha_provider( $app->param('captcha_provider') );
1304            my $rebuild = $cp_old ne $obj->captcha_provider ? 1 : 0;
1305            $app->add_return_arg( need_full_rebuild => 1 ) if $rebuild;
1306        }
1307        if ( $screen eq 'cfg_web_services' ) {
1308            my $tok = '';
1309            ( $tok = $obj->remote_auth_token ) =~ s/\s//g;
1310            $obj->remote_auth_token($tok);
1311
1312            my $ping_servers = $app->registry('ping_servers');
1313            my @pings_list;
1314            push @pings_list, $_ foreach grep {
1315                defined( $app->param( 'ping_' . $_ ) )
1316                  && $app->param( 'ping_' . $_ )
1317              }
1318              keys %$ping_servers;
1319            $obj->update_pings( join( ',', @pings_list ) );
1320        }
1321        if ( $screen eq 'cfg_entry' ) {
1322            my %param = $_[0] ? %{ $_[0] } : ();
1323            my $pref_param = $app->load_entry_prefs;
1324            %param = ( %param, %$pref_param );
1325        }
1326        if ( $screen eq 'cfg_trackbacks' ) {
1327            if ( my $pings = $app->param('allow_pings') ) {
1328                if ($pings) {
1329                    $obj->moderate_pings( $app->param('moderate_pings') );
1330                    $obj->nofollow_urls( $app->param('nofollow_urls') ? 1 : 0 );
1331                }
1332                else {
1333                    $obj->moderate_pings(1);
1334                    $obj->email_new_pings(1);
1335                }
1336            }
1337        }
1338        if ( $screen eq 'cfg_registration' ) {
1339            $obj->allow_commenter_regist(
1340                $app->param('allow_commenter_regist') );
1341            $obj->allow_unreg_comments( $app->param('allow_unreg_comments') );
1342            if ( $app->param('allow_unreg_comments') ) {
1343                $obj->require_comment_emails(
1344                    $app->param('require_comment_emails') );
1345            }
1346            else {
1347                $obj->require_comment_emails(0);
1348            }
1349            my @authenticators;
1350
1351            my $c = $app->registry('commenter_authenticators');
1352            foreach ( keys %$c ) {
1353                if ( $app->param( 'enabled_' . $_ ) ) {
1354                    push @authenticators, $_;
1355                }
1356            }
1357            push @authenticators, 'MovableType'
1358              if $app->param('enabled_MovableType');
1359            my $c_old = $obj->commenter_authenticators;
1360            $obj->commenter_authenticators( join( ',', @authenticators ) );
1361            my $rebuild = $obj->commenter_authenticators ne $c_old ? 1 : 0;
1362            if ( $app->param('enabled_TypeKey') ) {
1363                $rebuild = $obj->require_typekey_emails ? 0 : 1;
1364                $obj->require_typekey_emails(
1365                    $app->param('require_typekey_emails') );
1366            }
1367            else {
1368                $obj->require_typekey_emails(0);
1369            }
1370            my $tok = '';
1371            ( $tok = $obj->remote_auth_token ) =~ s/\s//g;
1372            $obj->remote_auth_token($tok);
1373
1374            $app->add_return_arg( need_full_rebuild => 1 ) if $rebuild;
1375        }
1376        if ( $screen eq 'cfg_spam' ) {
1377            my $threshold = $app->param('junk_score_threshold');
1378            $threshold =~ s/\+//;
1379            $threshold ||= 0;
1380            $obj->junk_score_threshold($threshold);
1381            if ( my $expiry = $app->param('junk_folder_expiry') ) {
1382                $obj->junk_folder_expiry($expiry);
1383            }
1384            my $perms = $app->permissions;
1385            unless ( defined $app->param('auto_delete_junk') ) {
1386                if (
1387                    $app->user->is_superuser
1388                    || (
1389                        $perms
1390                        && (   $perms->can_administer_blog
1391                            || $perms->can_edit_config )
1392                    )
1393                  )
1394                {
1395                    $obj->junk_folder_expiry(0);
1396                }
1397                else {
1398                    delete $obj->{column_values}->{junk_folder_expiry};
1399                    delete $obj->{changed_cols}->{junk_folder_expiry};
1400                }
1401            }
1402        }
1403        if ( $screen eq 'cfg_entry' ) {
1404            my %param = $_[0] ? %{ $_[0] } : ();
1405            my $pref_param = $app->load_entry_prefs;
1406            %param = ( %param, %$pref_param );
1407            $param{ 'sort_order_posts_' . ( $obj->sort_order_posts || 0 ) } = 1;
1408            $param{words_in_excerpt} = 40
1409              unless defined $param{words_in_excerpt}
1410              && $param{words_in_excerpt} ne '';
1411            if ( $app->param('days_or_posts') eq 'days' ) {
1412                $obj->days_on_index( $app->param('list_on_index') );
1413                $obj->entries_on_index(0);
1414            }
1415            else {
1416                $obj->entries_on_index( $app->param('list_on_index') );
1417                $obj->days_on_index(0);
1418            }
1419            $obj->basename_limit(15)
1420              if $obj->basename_limit < 15;    # 15 is the *minimum*
1421            $obj->basename_limit(250)
1422              if $obj->basename_limit > 250;    # 15 is the *maximum*
1423        }
1424        if ( $screen eq 'cfg_archives' ) {
1425            if ( my $dcty = $app->param('dynamicity') ) {
1426                $obj->custom_dynamic_templates($dcty);
1427            }
1428            if ( !$app->param('enable_archive_paths') ) {
1429                $obj->archive_url('');
1430                $obj->archive_path('');
1431            }
1432        }
1433    }
1434    else {
1435
1436        #$obj->is_dynamic(0) unless defined $app->{query}->param('is_dynamic');
1437    }
1438
1439    if ( ( $obj->sanitize_spec || '' ) eq '1' ) {
1440        $obj->sanitize_spec( scalar $app->param('sanitize_spec_manual') );
1441    }
1442
1443    1;
1444}
1445
1446sub post_save {
1447    my $eh = shift;
1448    my ( $app, $obj, $original ) = @_;
1449
1450    my $perms = $app->permissions;
1451    return 1
1452      unless $app->user->is_superuser
1453      || $app->user->can_create_blog
1454      || ( $perms && $perms->can_edit_config );
1455
1456    my $screen = $app->param('cfg_screen') || '';
1457    if ( $screen eq 'cfg_archives' ) {
1458        if ( my $dcty = $app->param('dynamicity') ) {
1459            my $dcty_changed = $dcty ne $original->custom_dynamic_templates ? 1 : 0;
1460
1461            if ($dcty_changed) {
1462                if ( $dcty eq 'none' ) {
1463                    require MT::Template;
1464                    my @tmpls = MT::Template->load({
1465                        blog_id       => $obj->id,
1466                        build_dynamic => 1,
1467                    });
1468                    for my $tmpl (@tmpls) {
1469                        $tmpl->build_dynamic(0);
1470                        $tmpl->save;
1471                    }
1472                }
1473                $app->update_dynamicity(
1474                    $obj,
1475                    $app->param('dynamic_cache')       ? 1 : 0,
1476                    $app->param('dynamic_conditional') ? 1 : 0
1477                );
1478            }
1479
1480            # If either of the publishing paths changed, rebuild the fileinfos.
1481            my $path_changed = 0;
1482            for my $path_field (qw( site_path archive_path site_url archive_url )) {
1483                $path_changed = 1 && last if $app->param($path_field)
1484                    && $app->param($path_field) ne $original->$path_field();
1485            }
1486            if ($dcty ne 'none' && ($dcty_changed || $path_changed)) {
1487                $app->rebuild( BlogID => $obj->id, NoStatic => 1 )
1488                    or return $app->publish_error();
1489            }
1490        }
1491
1492        cfg_archives_save($app, $obj) or return;
1493    }
1494    if ( $screen eq 'cfg_prefs' ) {
1495        my $blog_id = $obj->id;
1496
1497        # FIXME: Needs to exclude MT::Permission records for groups
1498        $app->model('permission')
1499          ->load( { blog_id => $blog_id, author_id => 0 } );
1500        if ( !$perms ) {
1501            $perms = $app->model('permission')->new;
1502            $perms->blog_id($blog_id);
1503            $perms->author_id(0);
1504        }
1505    }
1506    if ( $screen eq 'cfg_entry' ) {
1507        my $blog_id = $obj->id;
1508
1509        # FIXME: Needs to exclude MT::Permission records for groups
1510        my $perms =
1511          $app->model('permission')
1512          ->load( { blog_id => $blog_id, author_id => 0 } );
1513        if ( !$perms ) {
1514            $perms = $app->model('permission')->new;
1515            $perms->blog_id($blog_id);
1516            $perms->author_id(0);
1517        }
1518        my $prefs = $app->_entry_prefs_from_params;
1519        if ($prefs) {
1520            $perms->entry_prefs($prefs);
1521            $perms->save
1522              or return $app->errtrans( "Saving permissions failed: [_1]",
1523                $perms->errstr );
1524        }
1525    }
1526
1527    if ( !$original->id ) {    # If the object is new, the "orignal" was blank
1528        ## If this is a new blog, we need to set up a permissions
1529        ## record for the existing user.
1530        $obj->create_default_templates( $obj->template_set );
1531
1532        # Add this blog to the user's "favorite blogs", pushing any 10th
1533        # blog off the list
1534        my $auth = $app->user;
1535
1536        # FIXME: Should we still be doing this?
1537        my $perms = $app->model('permission')->new;
1538        $perms->author_id( $auth->id );
1539        $perms->blog_id( $obj->id );
1540        $perms->set_full_permissions;
1541        $perms->save;
1542
1543        require MT::Log;
1544        $app->log(
1545            {
1546                message => $app->translate(
1547                    "Blog '[_1]' (ID:[_2]) created by '[_3]'",
1548                    $obj->name, $obj->id, $auth->name
1549                ),
1550                level    => MT::Log::INFO(),
1551                class    => 'blog',
1552                category => 'new',
1553            }
1554        );
1555
1556        $app->run_callbacks( 'blog_template_set_change', { blog => $obj } );
1557    }
1558    else {
1559
1560        # if you've changed the comment configuration
1561        if (
1562            (
1563                grep { $original->column($_) ne $obj->column($_) }
1564                qw(allow_unreg_comments allow_reg_comments remote_auth_token)
1565            )
1566          )
1567        {
1568            if ( RegistrationAffectsArchives( $obj->id, 'Individual' ) ) {
1569                $app->add_return_arg( need_full_rebuild => 1 );
1570            }
1571            else {
1572                $app->add_return_arg( need_index_rebuild => 1 );
1573            }
1574        }
1575
1576        # if other settings were changed that would affect published pages:
1577        if ( grep { $original->column($_) ne $obj->column($_) }
1578            qw(allow_pings allow_comment_html) )
1579        {
1580            $app->add_return_arg( need_full_rebuild => 1 );
1581        }
1582
1583        if ( ($original->template_set || '') ne ($obj->template_set || '') ) {
1584            $app->run_callbacks( 'blog_template_set_change', { blog => $obj } );
1585            $app->add_return_arg( need_full_rebuild => 1 );
1586        }
1587    }
1588    1;
1589}
1590
1591sub save_filter {
1592    my $eh    = shift;
1593    my ($app) = @_;
1594    my $name  = $app->param('name');
1595    if ( defined $name ) {
1596        $name =~ s/(^\s+|\s+$)//g;
1597        $app->param( 'name', $name );
1598    }
1599    my $perms = $app->permissions;
1600    my $screen = $app->param('cfg_screen') || '';
1601    return $eh->error( MT->translate("You did not specify a blog name.") )
1602      if ( !( $screen && $perms->can_edit_config )
1603        && ( defined $app->param('name') && ( $app->param('name') eq '' ) ) );
1604    return $eh->error( MT->translate("Site URL must be an absolute URL.") )
1605      if ( $screen eq 'cfg_archives' )
1606      && $perms->can_set_publish_paths
1607      && $app->param('site_url') !~ m.^https?://.;
1608    return $eh->error( MT->translate("Archive URL must be an absolute URL.") )
1609      if ( $screen eq 'cfg_archives' )
1610      && $perms->can_set_publish_paths
1611      && $app->param('archive_url') !~ m.^https?://.
1612      && $app->param('enable_archive_paths');
1613    return $eh->error( MT->translate("You did not specify an Archive Root.") )
1614      if ( $screen eq 'cfg_archives' )
1615      && $app->param('archive_path') =~ m/^\s*$/
1616      && $app->param('enable_archive_paths');
1617    return 1;
1618}
1619
1620sub post_delete {
1621    my ( $eh, $app, $obj ) = @_;
1622
1623    $app->log(
1624        {
1625            message => $app->translate(
1626                "Blog '[_1]' (ID:[_2]) deleted by '[_3]'",
1627                $obj->name, $obj->id, $app->user->name
1628            ),
1629            level    => MT::Log::INFO(),
1630            class    => 'blog',
1631            category => 'delete'
1632        }
1633    );
1634    $app->_delete_pseudo_association(undef, $obj->id);
1635}
1636
1637sub make_blog_list {
1638    my $app = shift;
1639    my ($blogs) = @_;
1640
1641    my $tbp_class     = $app->model('ping');
1642    my $entry_class   = $app->model('entry');
1643    my $comment_class = $app->model('comment');
1644    my $author        = $app->user;
1645    my $data;
1646    my $i;
1647    my @blog_ids;
1648    push @blog_ids, $_->id for @$blogs;
1649    my ( $entry_count, $ping_count, $comment_count );
1650    my $can_edit_authors = 1 if $author->is_superuser;
1651
1652    for my $blog (@$blogs) {
1653        my $blog_id = $blog->id;
1654        my $perms   = $author->permissions($blog_id);
1655        my $row     = {
1656            id          => $blog->id,
1657            name        => $blog->name,
1658            description => $blog->description,
1659            site_url    => $blog->site_url
1660        };
1661
1662        # we should use count by group here...
1663        $row->{num_entries} =
1664          ( $entry_count ? $entry_count->{$blog_id} : $entry_count->{$blog_id} =
1665              MT::Entry->count( { blog_id => $blog_id } ) )
1666          || 0;
1667        $row->{num_comments} = (
1668              $comment_count
1669            ? $comment_count->{$blog_id}
1670            : $comment_count->{$blog_id} = MT::Comment->count(
1671                { blog_id => $blog_id, junk_status => [ 0, 1 ] }
1672            )
1673          )
1674          || 0;
1675        $row->{num_pings} = (
1676            $ping_count ? $ping_count->{$blog_id} : $ping_count->{$blog_id} =
1677              MT::TBPing->count(
1678                { blog_id => $blog_id, junk_status => [ 0, 1 ] }
1679              )
1680        ) || 0;
1681        $row->{num_authors} = 0;
1682
1683        # FIXME: this isn't efficient
1684        my $iter = MT::Permission->load_iter(
1685            {
1686                blog_id => [ 0, $blog_id ],
1687
1688                #    role_mask => [ 2, undef ]
1689                #}, {
1690                #    range_incl => { 'role_mask' => 1 }
1691            }
1692        );
1693        my %a;
1694        while ( my $p = $iter->() ) {
1695            next if exists $a{ $p->author_id };
1696            $a{ $p->author_id } = 1;
1697            $row->{num_authors}++ if $p->can_create_post;
1698        }
1699        $row->{can_create_post}  = $perms->can_create_post;
1700        $row->{can_edit_entries} = $perms->can_create_post
1701          || $perms->can_edit_all_posts
1702          || $perms->can_publish_post;
1703        $row->{can_edit_templates} = $perms->can_edit_templates;
1704        $row->{can_edit_config}    = $perms->can_edit_config
1705          || $perms->can_administer_blog;
1706        $row->{can_set_publish_paths} = $perms->can_set_publish_paths
1707          || $perms->can_administer_blog;
1708        $row->{can_manage_feedback} = $perms->can_manage_feedback;
1709        $row->{can_edit_assets}     = $perms->can_edit_assets;
1710        $row->{can_administer_blog} = $perms->can_administer_blog;
1711        push @$data, $row;
1712    }
1713    $data;
1714}
1715
1716sub build_blog_table {
1717    my $app = shift;
1718    my (%args) = @_;
1719
1720    my $blog_class    = $app->model('blog');
1721    my $tbp_class     = $app->model('ping');
1722    my $entry_class   = $app->model('entry');
1723    my $comment_class = $app->model('comment');
1724
1725    my $iter;
1726    if ( $args{load_args} ) {
1727        my $class = $app->model('blog');
1728        $iter = $class->load_iter( @{ $args{load_args} } );
1729    }
1730    elsif ( $args{iter} ) {
1731        $iter = $args{iter};
1732    }
1733    elsif ( $args{items} ) {
1734        $iter = sub { pop @{ $args{items} } };
1735    }
1736    return [] unless $iter;
1737    my $param = $args{param};
1738
1739    my $author           = $app->user;
1740    my $can_edit_authors = $author->is_superuser;
1741    my @data;
1742    my $i;
1743    my ( $entry_count, $ping_count, $comment_count );
1744    while ( my $blog = $iter->() ) {
1745        my $blog_id = $blog->id;
1746        my $row     = {
1747            id          => $blog->id,
1748            name        => $blog->name,
1749            description => $blog->description,
1750            site_url    => $blog->site_url
1751        };
1752
1753        # we should use count by group here...
1754        $row->{num_entries} =
1755          ( $entry_count ? $entry_count->{$blog_id} : $entry_count->{$blog_id} =
1756              MT::Entry->count( { blog_id => $blog_id } ) )
1757          || 0;
1758        $row->{num_comments} = (
1759              $comment_count
1760            ? $comment_count->{$blog_id}
1761            : $comment_count->{$blog_id} = MT::Comment->count(
1762                { blog_id => $blog_id, junk_status => [ 0, 1 ] }
1763            )
1764          )
1765          || 0;
1766        $row->{num_pings} = (
1767            $ping_count ? $ping_count->{$blog_id} : $ping_count->{$blog_id} =
1768              MT::TBPing->count(
1769                { blog_id => $blog_id, junk_status => [ 0, 1 ] }
1770              )
1771        ) || 0;
1772        $row->{num_authors} = 0;
1773
1774        # FIXME: This isn't efficient
1775        my $iter = MT::Permission->load_iter(
1776            {
1777                blog_id => [ 0, $blog_id ],
1778
1779                #    role_mask => [ 2, undef ]
1780                #}, {
1781                #    range_incl => { 'role_mask' => 1 }
1782            }
1783        );
1784        my %a;
1785        while ( my $p = $iter->() ) {
1786            next if exists $a{ $p->author_id };
1787            $a{ $p->author_id } = 1;
1788            $row->{num_authors}++ if $p->can_create_post;
1789        }
1790        if ( $author->is_superuser ) {
1791            $row->{can_create_post}       = 1;
1792            $row->{can_edit_entries}      = 1;
1793            $row->{can_edit_templates}    = 1;
1794            $row->{can_edit_config}       = 1;
1795            $row->{can_set_publish_paths} = 1;
1796            $row->{can_administer_blog}   = 1;
1797        }
1798        else {
1799            my $perms = $author->permissions($blog_id);
1800            $row->{can_create_post}  = $perms->can_create_post;
1801            $row->{can_edit_entries} = $perms->can_create_post
1802              || $perms->can_edit_all_posts
1803              || $perms->can_publish_post;
1804            $row->{can_edit_templates} = $perms->can_edit_templates;
1805            $row->{can_edit_config}    = $perms->can_edit_config
1806              || $perms->can_administer_blog;
1807            $row->{can_set_publish_paths} = $perms->can_set_publish_paths
1808              || $perms->can_administer_blog;
1809            $row->{can_administer_blog} = $perms->can_administer_blog;
1810        }
1811        $row->{object} = $blog;
1812        push @data, $row;
1813    }
1814
1815    if (@data) {
1816        $param->{blog_table}[0]{object_loop} = \@data;
1817        $app->load_list_actions( 'blog', \%$param );
1818        $param->{object_loop} = $param->{blog_table}[0]{object_loop};
1819    }
1820
1821    \@data;
1822}
1823
1824sub cfg_blog {
1825    my $q = $_[0]->{query};
1826    $q->param( '_type', 'blog' );
1827    $q->param( 'id',    scalar $q->param('blog_id') );
1828    $_[0]->forward( "view", { output => 'cfg_prefs.tmpl' } );
1829}
1830
1831sub cfg_archives_save {
1832    my $app = shift;
1833    my ($blog) = @_;
1834
1835    my $at = $app->param('preferred_archive_type');
1836    $blog->archive_type_preferred($at);
1837    my $pq = $app->param('publish_queue');
1838    $blog->publish_queue( $pq ? 1 : 0 );
1839    $blog->save
1840      or return $app->error(
1841        $app->translate( "Saving blog failed: [_1]", $blog->errstr ) );
1842}
1843
1844sub RegistrationAffectsArchives {
1845    my ( $blog_id, $archive_type ) = @_;
1846    require MT::TemplateMap;
1847    require MT::Template;
1848    my @tms = MT::TemplateMap->load(
1849        {
1850            archive_type => $archive_type,
1851            blog_id      => $blog_id
1852        }
1853    );
1854    grep { $_->text =~ /<MT:?IfRegistration/i }
1855      map { MT::Template->load( $_->template_id ) } @tms;
1856}
1857
1858sub update_dynamicity {
1859    my $app = shift;
1860    my ( $blog, $cache, $conditional ) = @_;
1861    my $dcty = $blog->custom_dynamic_templates;
1862    if ( $dcty eq 'none' ) {
1863        require MT::Template;
1864        my @templates = MT::Template->load( { blog_id => $blog->id } );
1865        for my $tmpl (@templates) {
1866            $tmpl->build_dynamic(0);
1867            $tmpl->save();
1868        }
1869    }
1870    elsif ( $dcty eq 'archives' ) {
1871        require MT::Template;
1872        my @templates = MT::Template->load( { blog_id => $blog->id } );
1873        for my $tmpl (@templates) {
1874            $tmpl->build_dynamic( $tmpl->type ne 'index' || 0 );
1875            $tmpl->save();
1876        }
1877    }
1878    elsif ( $dcty eq 'custom' ) {
1879    }
1880    elsif ( $dcty eq 'all' ) {
1881        require MT::Template;
1882        my @templates = MT::Template->load(
1883            {
1884                blog_id => $blog->id,
1885
1886                # FIXME: enumeration of types
1887                type =>
1888                  [ 'index', 'archive', 'individual', 'page', 'category' ],
1889            }
1890        );
1891        for my $tmpl (@templates) {
1892            $tmpl->build_dynamic(1);
1893            $tmpl->save();
1894        }
1895    }
1896
1897    if ( $dcty ne 'none' ) {
1898        $app->prepare_dynamic_publishing(@_, $blog->site_path, $blog->site_url);
1899        if ( $blog->archive_path ) {
1900            $app->prepare_dynamic_publishing(@_, $blog->archive_path, $blog->archive_url);
1901        }
1902        my $compiled_template_path =
1903          File::Spec->catfile( $blog->site_path(), 'templates_c' );
1904        if ( -d $compiled_template_path ) {
1905            $app->add_return_arg( 'no_writecache' => 1 )
1906              unless ( -w $compiled_template_path );
1907        }
1908        else {
1909            $app->add_return_arg( 'no_cachedir' => 1 )
1910              unless ( -d $compiled_template_path );
1911        }
1912
1913        # FIXME: use FileMgr
1914        if ($cache) {
1915            my $cache_path = File::Spec->catfile( $blog->site_path(), 'cache' );
1916            if ( -d $cache_path ) {
1917                $app->add_return_arg( 'no_write_cache_path' => 1 )
1918                  unless ( -w $cache_path );
1919            }
1920            else {
1921                $app->add_return_arg( 'no_cache_path' => 1 )
1922                  unless ( -d $cache_path );
1923            }
1924        }
1925    }
1926    $app->add_return_arg( dynamic_set => 1 );
1927}
1928
1929sub prepare_dynamic_publishing {
1930    my ( $cb, $blog, $cache, $conditional, $site_path, $site_url ) = @_;
1931
1932    my $htaccess_path = File::Spec->catfile( $site_path, ".htaccess" );
1933    my $mtview_path   = File::Spec->catfile( $site_path, "mtview.php" );
1934
1935    ## Don't re-create when files are there in callback.
1936    return 1
1937      if !defined($cache)
1938      && !defined($conditional)
1939      && ( 'MT::Callback' eq ref($cb) )
1940      && ( -f $htaccess_path )
1941      && ( -f $mtview_path );
1942    return 1 if ( 'none' eq $blog->custom_dynamic_templates );
1943
1944    require File::Spec;
1945
1946    # IIS itself does not handle .htaccess,
1947    # but IISPassword (3rd party) does and dies with this.
1948    if ( $ENV{SERVER_SOFTWARE} !~ /Microsoft-IIS/ ) {
1949        eval {
1950            require URI;
1951            my $mtview_server_url = new URI( $site_url );
1952            $mtview_server_url = $mtview_server_url->path();
1953            $mtview_server_url .=
1954              ( $mtview_server_url =~ m|/$| ? "" : "/" ) . "mtview.php";
1955
1956            my $contents = "";
1957            if ( open( HT, $htaccess_path ) ) {
1958                local $/ = undef;
1959                $contents = <HT>;
1960                close HT;
1961            }
1962            if ( $contents !~ /^\s*Rewrite(Cond|Engine|Rule)\b/m ) {
1963                my $htaccess = <<HTACCESS;
1964
1965## %%%%%%% Movable Type generated this part; don't remove this line! %%%%%%%
1966# Disable fancy indexes, so mtview.php gets a chance...
1967Options -Indexes +SymLinksIfOwnerMatch
1968  <IfModule mod_rewrite.c>
1969  # The mod_rewrite solution is the preferred way to invoke
1970  # dynamic pages, because of its flexibility.
1971
1972  # Add mtview.php to the list of DirectoryIndex options, listing it last,
1973  # so it is invoked only if the common choices aren't present...
1974  <IfModule mod_dir.c>
1975    DirectoryIndex index.php index.html index.htm default.htm default.html default.asp $mtview_server_url
1976  </IfModule>
1977
1978  RewriteEngine on
1979
1980  # don't serve mtview.php if the request is for a real directory
1981  # (allows the DirectoryIndex lookup to function)
1982  RewriteCond %{REQUEST_FILENAME} !-d
1983
1984  # don't serve mtview.php if the request is for a real file
1985  # (allows the actual file to be served)
1986  RewriteCond %{REQUEST_FILENAME} !-f
1987  # anything else is handed to mtview.php for resolution
1988  RewriteRule ^(.*)\$ $mtview_server_url [L,QSA]
1989</IfModule>
1990
1991<IfModule !mod_rewrite.c>
1992  # if mod_rewrite is unavailable, we forward any missing page
1993  # or unresolved directory index requests to mtview
1994  # if mtview.php can resolve the request, it returns a 200
1995  # result code which prevents any 4xx error code from going
1996  # to the server's access logs. However, an error will be
1997  # reported in the error log file. If this is your only choice,
1998  # and you want to suppress these messages, adding a "LogLevel crit"
1999  # directive within your VirtualHost or root configuration for
2000  # Apache will turn them off.
2001  ErrorDocument 404 $mtview_server_url
2002  ErrorDocument 403 $mtview_server_url
2003</IfModule>
2004## ******* Movable Type generated this part; don't remove this line! *******
2005
2006HTACCESS
2007
2008                $blog->file_mgr->mkpath( $site_path );
2009
2010                open( HT, ">>$htaccess_path" )
2011                  || die "Couldn't open $htaccess_path for appending";
2012                print HT $htaccess || die "Couldn't write to $htaccess_path";
2013                close HT;
2014            }
2015        };
2016        if ($@) { print STDERR $@; }
2017    }
2018
2019    eval {
2020        my $mv_contents = '';
2021        if ( -f $mtview_path ) {
2022            open( my $mv, "<$mtview_path" );
2023            while ( my $line = <$mv> ) {
2024                $mv_contents .= $line if ( $line !~ m!^//|<\?(?:php)?|\?>! );
2025            }
2026            close $mv;
2027        }
2028        my $cgi_path = MT->instance->server_path() || "";
2029        $cgi_path =~ s!/*$!!;
2030        my $mtphp_path = File::Spec->canonpath("$cgi_path/php/mt.php");
2031        my $blog_id    = $blog->id;
2032        my $config     = MT->instance->{cfg_file};
2033        my $cache_code = $cache ? "\n    \$mt->caching = true;" : '';
2034        my $conditional_code =
2035          $conditional ? "\n    \$mt->conditional = true;" : '';
2036        my $new_mtview = <<NEW_MTVIEW;
2037
2038    include('$mtphp_path');
2039    \$mt = new MT($blog_id, '$config');$cache_code$conditional_code
2040    \$mt->view();
2041NEW_MTVIEW
2042
2043        if ( $new_mtview ne substr( $mv_contents, 0, length($new_mtview) ) ) {
2044            $mv_contents =~ s!\n!\n//!gs;
2045            my $mtview = <<MTVIEW;
2046<?php
2047$new_mtview
2048$mv_contents
2049?>
2050MTVIEW
2051
2052            $blog->file_mgr->mkpath( $site_path );
2053            open( my $mv, ">$mtview_path" )
2054              || die "Couldn't open $mtview_path for appending";
2055            print $mv $mtview || die "Couldn't write to $mtview_path";
2056            close $mv;
2057        }
2058    };
2059    if ($@) { print STDERR $@; }
2060
2061    my $compiled_template_path =
2062      File::Spec->catfile( $site_path, 'templates_c' );
2063    my $fmgr        = $blog->file_mgr;
2064    my $cfg         = MT->config;
2065    my $saved_umask = $cfg->DirUmask;
2066    $cfg->DirUmask('0000');
2067    $fmgr->mkpath($compiled_template_path);
2068    $cfg->DirUmask($saved_umask);
2069    my $message = q();
2070
2071    if ( -d $compiled_template_path ) {
2072        $message = MT->translate(
2073'Error: Movable Type cannot write to the template cache directory. Please check the permissions for the directory called <code>[_1]</code> underneath your blog directory.',
2074            'templates_c'
2075        ) unless ( -w $compiled_template_path );
2076    }
2077    else {
2078        $message = MT->translate(
2079'Error: Movable Type was not able to create a directory to cache your dynamic templates. You should create a directory called <code>[_1]</code> underneath your blog directory.',
2080            'templates_c'
2081        ) unless ( -d $compiled_template_path );
2082    }
2083
2084    # FIXME: use FileMgr
2085    if ($cache) {
2086        my $cache_path = File::Spec->catfile( $blog->site_path(), 'cache' );
2087        $cfg->DirUmask('0000');
2088        $fmgr->mkpath($cache_path);
2089        $cfg->DirUmask($saved_umask);
2090        if ( -d $cache_path ) {
2091            $message = MT->translate(
2092'Error: Movable Type cannot write to the template cache directory. Please check the permissions for the directory called <code>[_1]</code> underneath your blog directory.',
2093                'cache'
2094            ) unless ( -w $cache_path );
2095        }
2096        else {
2097            $message = MT->translate(
2098'Error: Movable Type was not able to create a directory to cache your dynamic templates. You should create a directory called <code>[_1]</code> underneath your blog directory.',
2099                'cache'
2100            ) unless ( -d $cache_path );
2101        }
2102    }
2103    MT->log(
2104        {
2105            message => $message,
2106            level   => MT::Log::ERROR(),
2107            class   => 'system',
2108        }
2109    );
2110}
2111
21121;
Note: See TracBrowser for help on using the browser.