| | 291 | |
|---|
| | 292 | __END__ |
|---|
| | 293 | |
|---|
| | 294 | =head1 NAME |
|---|
| | 295 | |
|---|
| | 296 | MT::Revisable - An interface for any MT::Object that wishes to be versioned. |
|---|
| | 297 | |
|---|
| | 298 | =head1 SUBCLASS INHERITANCE |
|---|
| | 299 | |
|---|
| | 300 | To be versioned, an MT::Object subclass must first inherit MT::Revisable: |
|---|
| | 301 | |
|---|
| | 302 | package MT::Foo; |
|---|
| | 303 | use base qw( MT::Object MT::Revisable ); |
|---|
| | 304 | |
|---|
| | 305 | When a revision is saved, the entire object is taken and serialized. |
|---|
| | 306 | However, in order to curb bloat, the saving of a revision is only triggered |
|---|
| | 307 | when a versioned column has changed. To mark a column as versioned, simply add |
|---|
| | 308 | the keyword C<revisioned> to the column definition: |
|---|
| | 309 | |
|---|
| | 310 | __PACKAGE__->install_properties({ |
|---|
| | 311 | column_defs => { |
|---|
| | 312 | melody_nelson => 'string(255) not null revisioned |
|---|
| | 313 | } |
|---|
| | 314 | }); |
|---|
| | 315 | |
|---|
| | 316 | If at least one versioned column is changed |
|---|
| | 317 | |
|---|
| | 318 | =head1 METHODS |
|---|
| | 319 | |
|---|
| | 320 | =head2 $class->revision_pkg |
|---|
| | 321 | |
|---|
| | 322 | Returned by C<MT->model($class->datasource . ':revision')> - the namespace of |
|---|
| | 323 | the class that stores revisions for the class. |
|---|
| | 324 | |
|---|
| | 325 | =head2 $class->revision_props |
|---|
| | 326 | |
|---|
| | 327 | Returns a hashref of the install properties for the C<revision_pkg> |
|---|
| | 328 | |
|---|
| | 329 | =head2 $class->init_revisioning |
|---|
| | 330 | |
|---|
| | 331 | Called by the base C<MT::Object> class to initialize the revisioning framework |
|---|
| | 332 | for the particular class. This may involve creating the C<revision_pkg>. |
|---|
| | 333 | |
|---|
| | 334 | =head2 $class->revisioned_columns |
|---|
| | 335 | |
|---|
| | 336 | Returns an arrayref of column names that are marked as being revisioned. |
|---|
| | 337 | |
|---|
| | 338 | =head2 $class->is_revisioned_column($col) |
|---|
| | 339 | |
|---|
| | 340 | Checks whether the passed column name has been marked as being revisioned |
|---|
| | 341 | |
|---|
| | 342 | =head2 $obj->gather_changed_cols($orig) |
|---|
| | 343 | |
|---|
| | 344 | Compares the revisioned columns of C<$orig> with C<$obj> and stores an arrayref |
|---|
| | 345 | of changed columns in C<$obj->{changed_revisioned_columns}> |
|---|
| | 346 | |
|---|
| | 347 | =head2 $obj->pack_revision() |
|---|
| | 348 | |
|---|
| | 349 | Creates the hashref that will be stored as a particular revision of the object. |
|---|
| | 350 | By default, this hashref contains the values of the object's normal and meta |
|---|
| | 351 | columns. The C<<package>::pack_revision> callback can be used to add further |
|---|
| | 352 | values to be stored with the revision. |
|---|
| | 353 | |
|---|
| | 354 | =head2 $obj->unpack_revision($packed_obj) |
|---|
| | 355 | |
|---|
| | 356 | The opposite of C<pack_revision>, takes the C<$packed_obj> hashref and unpacks |
|---|
| | 357 | it, setting the values of C<$obj> as needed. The C<<package>::unpack_revision> |
|---|
| | 358 | callback can be used for any other keys added to C<$packged_obj> that are not |
|---|
| | 359 | part of the normal or meta columns. |
|---|
| | 360 | |
|---|
| | 361 | =head2 $obj->save_revision() |
|---|
| | 362 | |
|---|
| | 363 | Called automatically when an object is saved from the MT web interface or |
|---|
| | 364 | posted via a 3rd party client (on a low priority api/cms_post_save callback). |
|---|
| | 365 | Saves a revision only if at least one revisioned column has changed. |
|---|
| | 366 | |
|---|
| | 367 | # =head2 $obj->object_from_revision($revision) |
|---|
| | 368 | |
|---|
| | 369 | =head2 $obj->load_revision(\%terms, \%args) |
|---|
| | 370 | |
|---|
| | 371 | Loads revisions for the C<$obj>. Arguments work similarly to C<MT::Object->load>. |
|---|
| | 372 | Thus, one can simply do C<$obj->load_revision($rev_numer)> or pass terms and |
|---|
| | 373 | args. Terms can be any of the following: |
|---|
| | 374 | |
|---|
| | 375 | =over |
|---|
| | 376 | |
|---|
| | 377 | =item * id |
|---|
| | 378 | |
|---|
| | 379 | =item * label |
|---|
| | 380 | |
|---|
| | 381 | =item * description |
|---|
| | 382 | |
|---|
| | 383 | =item * rev_number |
|---|
| | 384 | |
|---|
| | 385 | =item * changed |
|---|
| | 386 | |
|---|
| | 387 | =back |
|---|
| | 388 | |
|---|
| | 389 | C<load_revision> should return an/array of arrayref(s) of: |
|---|
| | 390 | |
|---|
| | 391 | =over |
|---|
| | 392 | |
|---|
| | 393 | =item 0. The object stored at the revision |
|---|
| | 394 | |
|---|
| | 395 | =item 1. An array ref of the changed columns that triggered the revision |
|---|
| | 396 | |
|---|
| | 397 | =item 2. The revision number |
|---|
| | 398 | |
|---|
| | 399 | =back |
|---|
| | 400 | |
|---|
| | 401 | =head2 $obj->apply_revision(\%terms, \%args) |
|---|
| | 402 | |
|---|
| | 403 | Rolls back to the state of the object at C<$obj->load_revision(\%terms, \%args)> |
|---|
| | 404 | and saves this action as a revision. |
|---|
| | 405 | |
|---|
| | 406 | =head2 $obj->diff_object($obj_b) |
|---|
| | 407 | |
|---|
| | 408 | Returns a hashref of column names with the values being an arrayref representation |
|---|
| | 409 | of the diff: |
|---|
| | 410 | |
|---|
| | 411 | [<flag>, <left>, <right>] |
|---|
| | 412 | |
|---|
| | 413 | with the flag being C<'u', '+', '-', 'c'>. See the C<HTML::Diff> POD for more |
|---|
| | 414 | information. |
|---|
| | 415 | |
|---|
| | 416 | =head2 $obj->diff_revision(\%terms, \%diff_args) |
|---|
| | 417 | |
|---|
| | 418 | Loads the first object at C<$obj->load_revision(\%terms, \%args)> and returns |
|---|
| | 419 | a hashref of column names with the values being an arrayref representation |
|---|
| | 420 | of the diff: |
|---|
| | 421 | |
|---|
| | 422 | [<flag>, <left>, <right>] |
|---|
| | 423 | |
|---|
| | 424 | with the flag being C<'u', '+', '-', 'c'>. See the C<HTML::Diff> POD for more |
|---|
| | 425 | information. |
|---|
| | 426 | |
|---|
| | 427 | =head1 CALLBACKS |
|---|
| | 428 | |
|---|
| | 429 | =head2 <package>::pack_revision |
|---|
| | 430 | |
|---|
| | 431 | sub pack_revision { |
|---|
| | 432 | my ($cb, $obj, $values) = @_; |
|---|
| | 433 | |
|---|
| | 434 | } |
|---|
| | 435 | |
|---|
| | 436 | This callback is run after C<$values> is initially populated by C<$obj->pack-revision()> |
|---|
| | 437 | and is a hashref of the normal and meta column values and allows you to modify |
|---|
| | 438 | C<$values> before it is saved with the revision. Thus, you can use this callback |
|---|
| | 439 | to augment what is stored with every revision. |
|---|
| | 440 | |
|---|
| | 441 | =head2 <package>::unpack_revision |
|---|
| | 442 | |
|---|
| | 443 | sub unpack_revision { |
|---|
| | 444 | my ($cb, $obj, $packed_obj) = @_; |
|---|
| | 445 | |
|---|
| | 446 | } |
|---|
| | 447 | |
|---|
| | 448 | This callback is the complement of C<pack_revision> and allows you to restore |
|---|
| | 449 | values that are within C<$packed_obj>. |
|---|
| | 450 | |
|---|
| | 451 | =head2 <package>::save_revision_filter |
|---|
| | 452 | |
|---|
| | 453 | sub save_revision_filter { |
|---|
| | 454 | my ($cb, $obj) = @_; |
|---|
| | 455 | } |
|---|
| | 456 | |
|---|
| | 457 | Similar to the C<cms_save_filter> callbacks, this filter will allow you to |
|---|
| | 458 | prevent the saving of a particular revision. |
|---|
| | 459 | |
|---|
| | 460 | =head2 <package>::pre_save_revision |
|---|
| | 461 | |
|---|
| | 462 | sub pre_save_revision { |
|---|
| | 463 | my ($cb, $obj) = @_; |
|---|
| | 464 | |
|---|
| | 465 | } |
|---|
| | 466 | |
|---|
| | 467 | This callback is called just before the revision is saved. |
|---|
| | 468 | |
|---|
| | 469 | =head2 <package>::post_save_revision |
|---|
| | 470 | |
|---|
| | 471 | sub post_save_revision { |
|---|
| | 472 | my ($cb, $obj, $rev_number) = @_; |
|---|
| | 473 | |
|---|
| | 474 | } |
|---|
| | 475 | |
|---|
| | 476 | This callback is called immediately after a revision is saved. |
|---|
| | 477 | |
|---|
| | 478 | =head1 DRIVERS |
|---|
| | 479 | |
|---|
| | 480 | The majority of the methods MT::Revisable provides are implemented by driver |
|---|
| | 481 | modules. These driver modules specify how versions of an object are saved and |
|---|
| | 482 | retrieved from a data store. By default, MT::Revisable uses the |
|---|
| | 483 | MT::Revisable::Local driver which saves versions within the Movable Type database. |
|---|
| | 484 | To change this, you would first need to create a driver that implements the |
|---|
| | 485 | following methods: |
|---|
| | 486 | |
|---|
| | 487 | =item * revision_pkg |
|---|
| | 488 | |
|---|
| | 489 | =item * revision_props |
|---|
| | 490 | |
|---|
| | 491 | =item * init_revisioning |
|---|
| | 492 | |
|---|
| | 493 | =item * save_revision |
|---|
| | 494 | |
|---|
| | 495 | =item * load_revision |
|---|
| | 496 | |
|---|
| | 497 | If some of the above methods are not applicable to your driver, simply return undef. |
|---|