| 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 | |
|---|
| 7 | package MT::TemplateMap; |
|---|
| 8 | |
|---|
| 9 | use strict; |
|---|
| 10 | use 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 | |
|---|
| 38 | sub class_label { |
|---|
| 39 | return MT->translate("Archive Mapping"); |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | sub class_label_plural { |
|---|
| 43 | return MT->translate("Archive Mappings"); |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | sub 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 | |
|---|
| 62 | sub 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__->exist({ |
|---|
| 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 | |
|---|
| 133 | sub 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 | |
|---|
| 158 | sub _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 | |
|---|
| 171 | 1; |
|---|
| 172 | __END__ |
|---|
| 173 | |
|---|
| 174 | =head1 NAME |
|---|
| 175 | |
|---|
| 176 | MT::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 | |
|---|
| 192 | An I<MT::TemplateMap> object represents a single association between an |
|---|
| 193 | Archive Template and an archive type for a particular blog. For example, if |
|---|
| 194 | you set up a template called C<Date-Based> and assign to the C<Monthly> |
|---|
| 195 | archive type in your blog, such an association will be represented by one |
|---|
| 196 | I<MT::TemplateMap> object. |
|---|
| 197 | |
|---|
| 198 | =head1 USAGE |
|---|
| 199 | |
|---|
| 200 | As a subclass of I<MT::Object>, I<MT::TemplateMap> inherits all of the |
|---|
| 201 | data-management and -storage methods from that class; thus you should look |
|---|
| 202 | at the I<MT::Object> documentation for details about creating a new object, |
|---|
| 203 | loading an existing object, saving an object, etc. |
|---|
| 204 | |
|---|
| 205 | =head1 DATA ACCESS METHODS |
|---|
| 206 | |
|---|
| 207 | The I<MT::TemplateMap> object holds the following pieces of data. These |
|---|
| 208 | fields can be accessed and set using the standard data access methods |
|---|
| 209 | described in the I<MT::Object> documentation. |
|---|
| 210 | |
|---|
| 211 | =over 4 |
|---|
| 212 | |
|---|
| 213 | =item * id |
|---|
| 214 | |
|---|
| 215 | The numeric ID of the template map record. |
|---|
| 216 | |
|---|
| 217 | =item * blog_id |
|---|
| 218 | |
|---|
| 219 | The numeric ID of the blog with which this template map record is associated. |
|---|
| 220 | |
|---|
| 221 | =item * template_id |
|---|
| 222 | |
|---|
| 223 | The numeric ID of the template. |
|---|
| 224 | |
|---|
| 225 | =item * archive_type |
|---|
| 226 | |
|---|
| 227 | The archive type; should be one of the following values: C<Individual>, |
|---|
| 228 | C<Daily>, C<Weekly>, C<Monthly>, or C<Category>. |
|---|
| 229 | |
|---|
| 230 | =item * file_template |
|---|
| 231 | |
|---|
| 232 | The Archive File Template for this particular mapping; this defines the output |
|---|
| 233 | files for the pages generated from the template for this archive type, |
|---|
| 234 | using standard MT template tags. |
|---|
| 235 | |
|---|
| 236 | =item * is_preferred |
|---|
| 237 | |
|---|
| 238 | A boolean flag specifying whether this particular template is preferred over |
|---|
| 239 | any others defined for this archive type. This is used when generating links |
|---|
| 240 | to archives of this archive type--the link will always link to the preferred |
|---|
| 241 | archive type. |
|---|
| 242 | |
|---|
| 243 | =back |
|---|
| 244 | |
|---|
| 245 | =head1 METHODS |
|---|
| 246 | |
|---|
| 247 | =over 4 |
|---|
| 248 | |
|---|
| 249 | =item * save() |
|---|
| 250 | |
|---|
| 251 | Saves the object. It also rearranges blog's archive type. If the saved |
|---|
| 252 | template map is new and there is no other template maps with the same |
|---|
| 253 | archive type has been, the archive type is also added to the blog. |
|---|
| 254 | |
|---|
| 255 | =item * remove() |
|---|
| 256 | |
|---|
| 257 | Removes template maps specified in terms and args (if called as class method) |
|---|
| 258 | or the template map (if called as instance method). It also rearrange blog's |
|---|
| 259 | archive types which are used to determine what types of archive will be |
|---|
| 260 | published during rebuild. If template map is removed and there remains no |
|---|
| 261 | template map with the archive type, the archive type is removed from blog's |
|---|
| 262 | archive types to be rebuilt. |
|---|
| 263 | |
|---|
| 264 | =item * prefer(boolean) |
|---|
| 265 | |
|---|
| 266 | Set the template map preferred or not, depending on the argument. If the map |
|---|
| 267 | has been preferred and is being unpreferred, and if there are any other |
|---|
| 268 | I<MT::TemplateMap> objects defined for this particular archive type and blog, |
|---|
| 269 | the first of the other objects will be set as the preferred object. |
|---|
| 270 | Its I<is_preferred> flag will be set to true. If the map is the only |
|---|
| 271 | I<MT::TemplateMap> object for the blog and the archive type, the method does |
|---|
| 272 | nothing - the map continues to be preferred. |
|---|
| 273 | |
|---|
| 274 | =back |
|---|
| 275 | |
|---|
| 276 | =head1 DATA LOOKUP |
|---|
| 277 | |
|---|
| 278 | In addition to numeric ID lookup, you can look up or sort records by any |
|---|
| 279 | combination of the following fields. See the I<load> documentation in |
|---|
| 280 | I<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 | |
|---|
| 300 | When you remove a I<MT::TemplateMap> object using I<MT::TemplateMap::remove>, |
|---|
| 301 | if the I<$map> object you are removing has the I<is_preferred> flag set to |
|---|
| 302 | true, and if there are any other I<MT::TemplateMap> objects defined for this |
|---|
| 303 | particular archive type and blog, the first of the other objects will be |
|---|
| 304 | set as the preferred object. Its I<is_preferred> flag will be set to true. |
|---|
| 305 | |
|---|
| 306 | =back |
|---|
| 307 | |
|---|
| 308 | =head1 AUTHOR & COPYRIGHT |
|---|
| 309 | |
|---|
| 310 | Please see L<MT/AUTHOR & COPYRIGHT>. |
|---|
| 311 | |
|---|
| 312 | =cut |
|---|