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