root/branches/release-34/lib/MT/TemplateMap.pm @ 1823

Revision 1823, 8.8 kB (checked in by takayama, 20 months ago)

Fixed BugId:67959
* Added check for result of object loading

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