root/trunk/lib/MT/TemplateMap.pm @ 2966

Revision 2966, 9.4 kB (checked in by auno, 15 months ago)

Merge from mt4.21

  • Property svn:keywords set to Author Date Id Revision
Line 
1# Movable Type (r) Open Source (C) 2001-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
7package MT::TemplateMap;
8
9use strict;
10use base qw( MT::Object );
11
12__PACKAGE__->install_properties({
13    column_defs => {
14        'id' => 'integer not null auto_increment',
15        'blog_id' => 'integer not null',
16        'template_id' => 'integer not null',
17        'archive_type' => 'string(25) not null',
18        'file_template' => 'string(255)',
19        'is_preferred' => 'boolean',
20        'build_type' => 'smallint',
21        'build_interval' => 'integer',
22    },
23    indexes => {
24        blog_id => 1,
25        template_id => 1,
26        archive_type => 1,
27        is_preferred => 1,
28    },
29    defaults => {
30        'build_type' => 1,
31    },
32    child_classes => ['MT::FileInfo'],
33    datasource => 'templatemap',
34    primary_key => 'id',
35    cacheable => 0,
36});
37
38sub class_label {
39    return MT->translate("Archive Mapping");
40}
41
42sub class_label_plural {
43    return MT->translate("Archive Mappings");
44}
45
46sub save {
47    my $map = shift;
48    my $res = $map->SUPER::save();
49    return $res unless $res;
50
51    my $at   = $map->archive_type;
52    my $blog = MT->model('blog')->load($map->blog_id)
53        or return;
54    my $blog_at   = $blog->archive_type;
55    my @ats = map { $_ } 
56        grep { $map->archive_type ne $_ }
57            split /,/, $blog_at
58                if $blog_at ne 'None';
59    push @ats, $map->archive_type;
60    my $new_at = join ',', @ats;
61    if ($new_at ne $blog_at) {
62        $blog->archive_type($new_at);
63        $blog->save;
64    }
65    return 1;
66}
67
68sub remove {
69    my $map = shift;
70    $map->remove_children({ key => 'templatemap_id' });
71    my $result = $map->SUPER::remove(@_);
72
73    if (ref $map) {
74        my $remaining = MT::TemplateMap->load(
75          {
76            blog_id => $map->blog_id,
77            archive_type => $map->archive_type,
78            id => [ $map->id ],
79          },
80          {
81            limit => 1,
82            not => { id => 1 }
83          }
84        );
85        if ($remaining) {
86            $remaining->is_preferred(1);
87            $remaining->save;
88        }
89        else {
90            my $blog = MT->model('blog')->load($map->blog_id)
91                or return;
92            my $at   = $blog->archive_type;
93            if ( $at && $at ne 'None' ) {
94                my @newat = map { $_ } grep { $map->archive_type ne $_ } split /,/, $at;
95                $blog->archive_type(join ',', @newat);
96                $blog->save;
97            }
98        }
99    }
100    else {
101        my $blog_id;
102        if ( $_[0] && $_[0]->{template_id} ) {
103            my $tmpl = MT::Template->load( $_[0]->{template_id} );
104            if ( $tmpl ) {
105                return $result unless $tmpl->blog_id; # global template does not have maps
106                $blog_id = $tmpl->blog_id;
107            }
108        }
109
110        my $maps_iter = MT::TemplateMap->count_group_by(
111            { ( defined $blog_id ? ( blog_id => $blog_id ) : () ) },
112            { group => [ 'blog_id', 'archive_type' ] }
113        );
114        my %ats;
115        while ( my ( $count, $blog_id, $at ) = $maps_iter->() ) {
116            my $ats = $ats{$blog_id};
117            push @$ats, $at if $count > 0;
118            $ats{$blog_id} = $ats;
119        }
120        my $iter;
121        if ( $blog_id ) {
122            my $blog = MT::Blog->load( $blog_id );
123            $iter = sub { my $ret = $blog; $blog = undef; $ret; }
124        } else {
125            $iter = MT::Blog->load_iter();
126        }
127        while ( my $blog = $iter->() ) {
128            $blog->archive_type( $ats{ $blog->id } ? join ',', @{ $ats{ $blog->id } } : '' );
129            $blog->save;
130            for my $at ( @{ $ats{ $blog->id } } ) {
131                unless ( __PACKAGE__->exist({
132                    blog_id => $blog->id, archive_type => $at, is_preferred => 1 
133                }) ) {
134                    my $remaining = __PACKAGE__->load(
135                      {
136                        blog_id => $blog->id,
137                        archive_type => $at,
138                      },
139                      {
140                        limit => 1,
141                      }
142                    );
143                    if ($remaining) {
144                        $remaining->is_preferred(1);
145                        $remaining->save;
146                    }
147                }
148            }
149        }
150    }
151    $result;
152}
153
154sub prefer {
155    my $map = shift;
156    my ($prefer) = @_;
157    $prefer = (defined($prefer) && $prefer) ? 1 : 0;
158
159    if ($prefer) {
160        return 1 if $map->is_preferred;
161        my $preferred = MT::TemplateMap->load({
162                blog_id => $map->blog_id,
163                archive_type => $map->archive_type,
164                is_preferred => 1,
165            }) or return;
166        $preferred->is_preferred(0);
167        $preferred->save or return $map->error($preferred->errstr);
168        $map->is_preferred(1);
169        $map->save or return $map->error($map->errstr);
170    } else {
171        return 1 unless $map->is_preferred;
172        if ($map->_prefer_next_map) {
173            $map->is_preferred(0);
174            $map->save or return $map->error($map->errstr);
175        }
176    }
177}
178
179sub _prefer_next_map {
180    my $map = shift;
181    my @all = MT::TemplateMap->load({ blog_id => $map->blog_id,
182                                      archive_type => $map->archive_type });
183    @all = grep { $_->id != $map->id } @all;
184    if (@all) {
185        $all[0]->is_preferred(1);
186        $all[0]->save;
187        return 1;
188    }
189    return 0;
190}
191
1921;
193__END__
194
195=head1 NAME
196
197MT::TemplateMap - Movable Type archive-template association record
198
199=head1 SYNOPSIS
200
201    use MT::TemplateMap;
202    my $map = MT::TemplateMap->new;
203    $map->blog_id($tmpl->blog_id);
204    $map->template_id($tmpl->id);
205    $map->archive_type('Monthly');
206    $map->file_template('<$MTArchiveDate format="%Y/%m/index.html"$>');
207    $map->is_preferred(1);
208    $map->save
209        or die $map->errstr;
210
211=head1 DESCRIPTION
212
213An I<MT::TemplateMap> object represents a single association between an
214Archive Template and an archive type for a particular blog. For example, if
215you set up a template called C<Date-Based> and assign to the C<Monthly>
216archive type in your blog, such an association will be represented by one
217I<MT::TemplateMap> object.
218
219=head1 USAGE
220
221As a subclass of I<MT::Object>, I<MT::TemplateMap> inherits all of the
222data-management and -storage methods from that class; thus you should look
223at the I<MT::Object> documentation for details about creating a new object,
224loading an existing object, saving an object, etc.
225
226=head1 DATA ACCESS METHODS
227
228The I<MT::TemplateMap> object holds the following pieces of data. These
229fields can be accessed and set using the standard data access methods
230described in the I<MT::Object> documentation.
231
232=over 4
233
234=item * id
235
236The numeric ID of the template map record.
237
238=item * blog_id
239
240The numeric ID of the blog with which this template map record is associated.
241
242=item * template_id
243
244The numeric ID of the template.
245
246=item * archive_type
247
248The archive type; should be one of the following values: C<Individual>,
249C<Daily>, C<Weekly>, C<Monthly>, or C<Category>.
250
251=item * file_template
252
253The Archive File Template for this particular mapping; this defines the output
254files for the pages generated from the template for this archive type,
255using standard MT template tags.
256
257=item * is_preferred
258
259A boolean flag specifying whether this particular template is preferred over
260any others defined for this archive type. This is used when generating links
261to archives of this archive type--the link will always link to the preferred
262archive type.
263
264=back
265
266=head1 METHODS
267
268=over 4
269
270=item * save()
271
272Saves the object.  It also rearranges blog's archive type.  If the saved
273template map is new and there is no other template maps with the same
274archive type has been, the archive type is also added to the blog.
275
276=item * remove()
277
278Removes template maps specified in terms and args (if called as class method)
279or the template map (if called as instance method).  It also rearrange blog's
280archive types which are used to determine what types of archive will be
281published during rebuild.  If template map is removed and there remains no
282template map with the archive type, the archive type is removed from blog's
283archive types to be rebuilt.
284
285=item * prefer(boolean)
286
287Set the template map preferred or not, depending on the argument.  If the map
288has been preferred and is being unpreferred, and if there are any other
289I<MT::TemplateMap> objects defined for this particular archive type and blog,
290the first of the other objects will be set as the preferred object.
291Its I<is_preferred> flag will be set to true.  If the map is the only
292I<MT::TemplateMap> object for the blog and the archive type, the method does
293nothing - the map continues to be preferred.
294
295=back
296
297=head1 DATA LOOKUP
298
299In addition to numeric ID lookup, you can look up or sort records by any
300combination of the following fields. See the I<load> documentation in
301I<MT::Object> for more information.
302
303=over 4
304
305=item * blog_id
306
307=item * template_id
308
309=item * archive_type
310
311=item * is_preferred
312
313=back
314
315=head1 NOTES
316
317=over 4
318
319=item * $obj->remove()
320
321When you remove a I<MT::TemplateMap> object using I<MT::TemplateMap::remove>,
322if the I<$map> object you are removing has the I<is_preferred> flag set to
323true, and if there are any other I<MT::TemplateMap> objects defined for this
324particular archive type and blog, the first of the other objects will be
325set as the preferred object. Its I<is_preferred> flag will be set to true.
326
327=back
328
329=head1 AUTHOR & COPYRIGHT
330
331Please see L<MT/AUTHOR & COPYRIGHT>.
332
333=cut
Note: See TracBrowser for help on using the browser.