Changeset 1927
- Timestamp:
- 04/16/08 15:36:30 (6 months ago)
- Files:
-
- branches/release-35/build/mt-dists/default.mk (modified) (1 diff)
- branches/release-35/lib/MT.pm.pre (modified) (9 diffs)
- branches/release-35/lib/MT/Asset/Image.pm (modified) (1 diff)
- branches/release-35/lib/MT/Author.pm (modified) (3 diffs)
- branches/release-35/lib/MT/Blog.pm (modified) (2 diffs)
- branches/release-35/lib/MT/Component.pm (modified) (1 diff)
- branches/release-35/lib/MT/Meta (copied) (copied from branches/feature-narrow-tables/lib/MT/Meta)
- branches/release-35/lib/MT/Meta.pm (copied) (copied from branches/feature-narrow-tables/lib/MT/Meta.pm)
- branches/release-35/lib/MT/Meta/Proxy.pm (copied) (copied from branches/feature-narrow-tables/lib/MT/Meta/Proxy.pm)
- branches/release-35/lib/MT/Object.pm (modified) (14 diffs)
- branches/release-35/lib/MT/ObjectDriver/DDL/mysql.pm (modified) (1 diff)
- branches/release-35/lib/MT/Template.pm (modified) (2 diffs)
- branches/release-35/lib/MT/Upgrade.pm (modified) (1 diff)
- branches/release-35/t/09-image.t (modified) (4 diffs)
- branches/release-35/t/20-setup.t (modified) (1 diff)
- branches/release-35/t/22-author.t (modified) (4 diffs)
- branches/release-35/t/64-objectmeta.t (modified) (2 diffs)
- branches/release-35/t/lib/MT/Test.pm (modified) (31 diffs)
- branches/release-35/t/plugins/Awesome (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome)
- branches/release-35/t/plugins/Awesome/config.yaml (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome/config.yaml)
- branches/release-35/t/plugins/Awesome/lib (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome/lib)
- branches/release-35/t/plugins/Awesome/lib/MT (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome/lib/MT)
- branches/release-35/t/plugins/Awesome/lib/MT/Awesome (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome)
- branches/release-35/t/plugins/Awesome/lib/MT/Awesome.pm (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome.pm)
- branches/release-35/t/plugins/Awesome/lib/MT/Awesome/Image.pm (copied) (copied from branches/feature-narrow-tables/t/plugins/Awesome/lib/MT/Awesome/Image.pm)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/release-35/build/mt-dists/default.mk
r1897 r1927 2 2 3 3 PRODUCT_VERSION = 4.15 4 SCHEMA_VERSION = 4.005 44 SCHEMA_VERSION = 4.0055 5 5 API_VERSION = 4.15 6 6 branches/release-35/lib/MT.pm.pre
r1871 r1927 58 58 no strict 'refs'; 59 59 unless ( defined *{ $compat . '::' } ) { 60 eval " require $compat;";60 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $compat;"; 61 61 } 62 62 } … … 267 267 return $object_types{$k} if exists $object_types{$k}; 268 268 269 if ($k =~ m/^(.+):meta$/) { 270 my $ppkg = $pkg->model($1); 271 my $mpkg = $ppkg->meta_pkg; 272 return $mpkg ? $object_types{$k} = $mpkg : undef; 273 } 274 269 275 my $model = $pkg->registry( 'object_types', $k ); 270 276 if ( ref($model) eq 'ARRAY' ) { … … 287 293 unless ( defined *{ $model . '::__properties' } ) { 288 294 use strict 'refs'; 289 eval " require $model;";295 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $model;"; 290 296 if ( $@ && ( $k =~ m/^(.+)\./ ) ) { 291 297 … … 612 618 613 619 $cb->error(); # reset the error string 614 my $result = eval { $cb->invoke(@args) }; 620 my $result = eval { 621 # line __LINE__ __FILE__ 622 $cb->invoke(@args); 623 }; 615 624 if ( my $err = $@ ) { 616 625 $cb->error($err); … … 1262 1271 $Plugins{$plugin_sig}{full_path} = $plugin_full_path; 1263 1272 $timer->pause_partial if $timer; 1264 eval { require $plugin };1273 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire '$plugin';"; 1265 1274 $timer->mark("Loaded plugin " . $sig) if $timer; 1266 1275 if ($@) { … … 1270 1279 # the database has been initialized... 1271 1280 eval { 1281 # line __LINE__ __FILE__ 1272 1282 require MT::Log; 1273 1283 $mt->log( … … 2588 2598 if ($method) { 2589 2599 return sub { 2590 eval " require $hdlr_pkg;"2600 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 2591 2601 or Carp::confess( 2592 2602 "failed loading package $hdlr_pkg for routine $name: $@"); … … 2599 2609 else { 2600 2610 return sub { 2601 eval " require $hdlr_pkg;"2611 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 2602 2612 or Carp::confess( 2603 2613 "failed loading package $hdlr_pkg for routine $name: $@"); … … 2613 2623 } 2614 2624 else { 2615 eval " require $hdlr_pkg;"2625 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $hdlr_pkg;" 2616 2626 or Carp::confess( 2617 2627 "failed loading package $hdlr_pkg for routine $name: $@"); branches/release-35/lib/MT/Asset/Image.pm
r1829 r1927 10 10 use base qw( MT::Asset ); 11 11 12 __PACKAGE__->install_properties( { class_type => 'image', } ); 13 __PACKAGE__->install_meta( { columns => [ 'image_width', 'image_height', ], } ); 12 __PACKAGE__->install_properties( { 13 class_type => 'image', 14 column_defs => { 15 'image_width' => 'integer meta', 16 'image_height' => 'integer meta', 17 }, 18 } ); 14 19 15 20 # List of supported file extensions (to aid the stock 'can_handle' method.) branches/release-35/lib/MT/Author.pm
r1823 r1927 37 37 'userpic_asset_id' => 'integer', 38 38 'basename' => 'string(255)', 39 40 # meta properties 41 'widgets' => 'hash meta', 42 'favorite_blogs' => 'array meta', 39 43 }, 40 44 defaults => { … … 59 63 audit => 1, 60 64 }); 61 __PACKAGE__->install_meta({62 columns => [63 'favorite_blogs',64 'widgets',65 ],66 });67 65 68 66 sub class_label { … … 263 261 die unless $perms->isa('MT::Permission'); 264 262 $perms->can_edit_all_posts || 265 ($perms->can_create_post && $entry->author_id == $author->id);263 ($perms->can_create_post && $entry->author_id == $author->id); 266 264 } 267 265 branches/release-35/lib/MT/Blog.pm
r1868 r1927 77 77 'archive_tmpl_category' => 'string(255)', 78 78 'archive_tmpl_individual' => 'string(255)', 79 80 # meta properties 81 'image_default_wrap_text' => 'integer meta', 82 'image_default_align' => 'string meta', 83 'image_default_thumb' => 'integer meta', 84 'image_default_width' => 'integer meta', 85 'image_default_wunits' => 'integer meta', 86 'image_default_constrain' => 'integer meta', 87 'image_default_popup' => 'integer meta', 88 'commenter_authenticators' => 'string meta', 89 'require_typekey_emails' => 'integer meta', 90 'nofollow_urls' => 'integer meta', 91 'follow_auth_links' => 'integer meta', 92 'update_pings' => 'integer meta', 93 'captcha_provider' => 'string meta', 94 'publish_queue' => 'integer meta', 95 'nwc_smart_replace' => 'integer meta', 96 'nwc_replace_field' => 'string meta', 97 'template_set' => 'string meta', 98 'page_layout' => 'string meta', 99 'include_system' => 'integer meta', 100 'include_cache' => 'integer meta', 79 101 }, 80 102 meta => 1, … … 93 115 datasource => 'blog', 94 116 primary_key => 'id', 95 });96 __PACKAGE__->install_meta({97 columns => [98 'image_default_wrap_text',99 'image_default_align',100 'image_default_thumb',101 'image_default_width',102 'image_default_wunits',103 'image_default_constrain',104 'image_default_popup',105 'commenter_authenticators',106 'require_typekey_emails',107 'nofollow_urls',108 'follow_auth_links',109 'update_pings',110 'captcha_provider',111 'publish_queue',112 'nwc_smart_replace',113 'nwc_replace_field',114 'template_set',115 'page_layout',116 'include_system',117 'include_cache',118 ],119 117 }); 120 118 branches/release-35/lib/MT/Component.pm
r1572 r1927 508 508 509 509 # check for a yaml file reference... 510 if ( !ref($v) && ( $v =~ m/^[-\w]+\.yaml$/ ) ) { 511 my $f = File::Spec->catfile( $c->path, $v ); 512 if ( -f $f ) { 513 require YAML::Tiny; 514 my $y = eval { YAML::Tiny->read($f) } 515 or die "Error reading $f: " . $YAML::Tiny::errstr; 516 517 # skip over non-hash elements 518 shift @$y while @$y && ( ref( $y->[0] ) ne 'HASH' ); 519 if (@$y) { 520 $r->{$p} = $y->[0]; 510 if ( !ref($v) ) { 511 if ( $v =~ m/^[-\w]+\.yaml$/ ) { 512 my $f = File::Spec->catfile( $c->path, $v ); 513 if ( -f $f ) { 514 require YAML::Tiny; 515 my $y = eval { YAML::Tiny->read($f) } 516 or die "Error reading $f: " 517 . $YAML::Tiny::errstr; 518 # skip over non-hash elements 519 shift @$y 520 while @$y && ( ref( $y->[0] ) ne 'HASH' ); 521 $r->{$p} = $y->[0] if @$y; 522 } 523 } elsif ($v =~ m/^\$\w+::/) { 524 my $code = MT->handler_to_coderef($v); 525 if (ref $code eq 'CODE') { 526 $r->{$p} = $code->($c); 521 527 } 522 528 } branches/release-35/lib/MT/Object.pm
r1873 r1927 53 53 } 54 54 55 my %meta; 56 55 57 my $super_props = $class->SUPER::properties(); 58 $props->{meta} = 1 if $super_props && $super_props->{meta}; 59 60 if ($props->{meta}) { 61 # yank out any meta columns before we start working on column_defs 62 $meta{$_} = delete $props->{column_defs}{$_} 63 for grep { $props->{column_defs}{$_} =~ m/\bmeta\b/ } 64 keys %{ $props->{column_defs} }; 65 } 66 56 67 if ($super_props) { 57 68 # subclass; merge hash 58 for (qw(primary_key meta_column class_column datasource driver audit meta)) {69 for (qw(primary_key class_column datasource driver audit)) { 59 70 $props->{$_} = $super_props->{$_} 60 71 if exists $super_props->{$_} && !(exists $props->{$_}); 61 72 } 62 for my $p (qw(column_defs defaults indexes meta_columns)) {73 for my $p (qw(column_defs defaults indexes)) { 63 74 if (exists $super_props->{$p}) { 64 75 foreach my $k (keys %{ $super_props->{$p} }) { … … 81 92 # Legacy MT::Object types only define 'columns'; we still support that 82 93 # but they aren't handled properly with the upgrade system as a result. 83 if (exists $props->{column_defs}) { 84 $props->{columns} = [ keys %{ $props->{column_defs} } ]; 85 } else { 94 if (! exists $props->{column_defs}) { 86 95 map { $props->{column_defs}{$_} = () } @{ $props->{columns} }; 87 96 } 97 $props->{columns} = [ keys %{ $props->{column_defs} } ]; 88 98 89 99 # Support audit flags … … 98 108 } 99 109 100 # Metadata column101 $props->{meta_column} ||= 'meta' if exists $props->{meta};102 if (my $col = $props->{meta_column}) {103 if (!$props->{column_defs}{$col}) {104 $props->{column_defs}{$col} = 'blob';105 push @{ $props->{columns} }, $col;106 }107 no strict 'refs'; ## no critic108 *{$class . '::' . $col} = \&__meta_column;109 $class->add_trigger( pre_save => \&pre_save_serialize_metadata );110 }111 112 110 # Classed object types 113 111 $props->{class_column} ||= 'class' if exists $props->{class_type}; … … 151 149 foreach my $isa_class (@classes) { 152 150 next if UNIVERSAL::isa($class, $isa_class); 153 eval " require $isa_class;" or die;151 eval "# line " . __LINE__ . " " . __FILE__ . "\nrequire $isa_class;" or die; 154 152 no strict 'refs'; ## no critic 155 153 push @{$class . '::ISA'}, $isa_class; … … 160 158 for my $name (keys %$cols) { 161 159 next if exists $props->{column_defs}{$name}; 160 if ($cols->{$name} =~ m/\bmeta\b/) { 161 $meta{$name} = $cols->{$name}; 162 next; 163 } 164 162 165 $class->install_column($name, $cols->{$name}); 163 166 $props->{indexes}{$name} = 1 … … 226 229 no strict 'refs'; ## no critic 227 230 *{$class . '::driver'} = sub { $_[0]->dbi_driver(@_) }; 231 } 232 233 # inherit parent's metadata setup 234 if ($props->{meta}) { # if ($super_props && $super_props->{meta_installed}) { 235 $class->install_meta({ ( %meta ? ( column_defs => \%meta ) : ( columns => [] ) ) }); 236 $class->add_trigger( post_remove => \&remove_meta ); 228 237 } 229 238 … … 347 356 return $package; 348 357 } else { 349 eval " use $package;";358 eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $package;"; 350 359 return $package unless $@; 351 eval " use $pkg; $package->new;";360 eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $pkg; $package->new;"; 352 361 return $package unless $@; 353 362 } … … 373 382 # 'meta' metadata column support 374 383 384 sub new { 385 my $class = shift; 386 my $obj = $class->SUPER::new(@_); 387 if ($obj->properties->{meta_installed}) { 388 $obj->init_meta(); 389 } 390 return $obj; 391 } 392 393 sub init_meta { 394 my $obj = shift; 395 require MT::Meta::Proxy; 396 $obj->{__meta} = MT::Meta::Proxy->new($obj); 397 } 398 375 399 sub install_meta { 376 400 my $class = shift; 377 my ($p rops) = @_;401 my ($params) = @_; 378 402 if ( ( $class ne 'MT::Config' ) && (!$MT::plugins_installed) ) { 379 push @PRE_INIT_META, [$class, $p rops];403 push @PRE_INIT_META, [$class, $params]; 380 404 return; 381 405 } 382 my $cprops = $class->properties; 383 my $fields = $cprops->{meta_columns} ||= {}; 384 my $meta_col = $cprops->{meta_column}; 385 foreach my $name (@{ $props->{columns} }) { 386 $fields->{$name} = (); 387 # Skip adding this method if the class overloads it. 388 # this lets the SUPER::columnname magic do it's thing 389 unless ($class->can($name)) { 390 no strict 'refs'; ## no critic 391 *{"${class}::$name"} = sub { shift->$meta_col($name, @_) }; 392 } 393 } 406 407 require MT::Meta; 408 my $pkg = ref $class || $class; 409 if (!$pkg->SUPER::properties->{meta_installed}) { 410 $pkg->add_trigger( post_save => \&post_save_save_metadata ); 411 $pkg->add_trigger( post_load => \&post_load_initialize_metadata ); 412 } 413 414 my $props = $class->properties; 415 416 if (!$params->{columns} && !$params->{fields} && !$params->{column_defs}) { 417 return $class->error('No meta fields specified to install_meta'); 418 } 419 420 $params->{fields} ||= []; 421 if (my $cols = delete $params->{columns}) { 422 foreach my $col (@$cols) { 423 push @{ $params->{fields} }, { 424 name => $col, 425 type => 'vblob', 426 }; 427 # $props->{fields}{$col} = 'vblob'; 428 } 429 } 430 if (my $cols = delete $params->{column_defs}) { 431 foreach my $col ( keys %$cols ) { 432 my $type = $cols->{$col}; 433 $type =~ s/\s.*//; # take first keyword, ignoring anything after 434 $type .= '_indexed' 435 if $cols->{$col} =~ m/\bindexed\b/; 436 $type = MT::Meta->normalize_type($type); 437 438 push @{ $params->{fields} }, { 439 name => $col, 440 type => $type, 441 }; 442 # $props->{fields}{$col} = $type; 443 } 444 } 445 446 $params->{datasource} ||= $class->datasource . '_meta'; 447 448 if ($props->{meta_installed} && !@{ $params->{fields} }) { 449 return 1; 450 } 451 452 if (my $fields = MT::Meta->install($pkg, $params)) { 453 # we may have inherited meta fields so lets update with 454 # the fields returned by MT::Meta 455 $props->{fields} = $fields; 456 } 457 458 return $props->{meta_installed} = 1; 459 } 460 461 sub meta_args { 462 my $class = shift; 463 my $id_field = $class->datasource . '_id'; 464 return { 465 key => $class->datasource, 466 column_defs => { 467 $id_field => 'integer not null', 468 type => 'string(255) not null', 469 vchar => 'string(255)', 470 vchar_indexed => 'string(255)', 471 vdatetime => 'datetime', 472 vdatetime_indexed => 'datetime', 473 vinteger => 'integer', 474 vinteger_indexed => 'integer', 475 vfloat => 'float', 476 vfloat_indexed => 'float', 477 vblob => 'blob', 478 vclob => 'text', 479 }, 480 columns => [ $id_field, qw( 481 type 482 vchar 483 vchar_indexed 484 vdatetime 485 vdatetime_indexed 486 vinteger 487 vinteger_indexed 488 vfloat 489 vfloat_indexed 490 vblob 491 vclob 492 ) ], 493 indexes => { 494 $id_field => 1, 495 id_type => { columns => [ $id_field, 'type' ] }, 496 id_type_vchar => { columns => [ $id_field, 'type', 'vchar_indexed' ] }, 497 id_type_vdatetime => { columns => [ $id_field, 'type', 498 'vdatetime_indexed' ] }, 499 id_type_vinteger => { columns => [ $id_field, 'type', 500 'vinteger_indexed' ] }, 501 id_type_vfloat => { columns => [ $id_field, 'type', 502 'vfloat_indexed' ] }, 503 }, 504 primary_key => [ $class->datasource . '_id', 'type' ], 505 }; 394 506 } 395 507 396 508 sub has_meta { 397 my $props = $_[0]->properties; 398 return $props->{meta} && (@_ > 1 ? exists $props->{meta_columns}{$_[1]} : 1); 399 } 400 401 sub pre_save_serialize_metadata { 402 my ($obj) = shift; 403 my $meta_col = $obj->properties->{meta_column}; 404 if ($obj->{changed_cols}{$meta_col}) { 405 require MT::Serialize; 406 my $meta = $obj->$meta_col; 407 $obj->$meta_col(MT::Serialize->serialize(\$meta)); 408 } 409 } 410 411 sub __thaw_meta { 412 my ($meta) = @_; 413 $$meta = '' unless defined $$meta; 414 require MT::Serialize; 415 my $out = MT::Serialize->unserialize($$meta); 416 if (ref $out eq 'REF') { 417 return $$out; 418 } else { 419 return {}; 420 } 421 } 422 423 # $obj->meta returns a hashref of metadata information 424 # $obj->meta($scalar) allows assignment of a serialized value 425 # $obj->meta('name', 'value') assigns an individual metadata element 426 # $obj->meta('name') returns an individual metadata value 427 # $obj->save will automatically serialize the metadata back to the database 428 sub __meta_column { 429 my $obj = shift; 430 my $meta_col = $obj->properties->{meta_column} or return; 431 432 if (@_) { 433 my $var = shift; 434 if ((defined $var) && ($var =~ m/^SERG\0\0\0\0/)) { 435 return $obj->column($meta_col, $var); 436 } 437 my $meta = $obj->column($meta_col); 438 if (!defined($meta)) { 439 $obj->{column_values}{$meta_col} = $meta = {}; 440 } elsif (!ref $meta) { 441 $obj->{column_values}{$meta_col} = $meta = __thaw_meta(\$meta); 442 } 509 my $obj = shift; 510 return $obj->is_meta_column(@_) if @_; 511 return $obj->properties->{meta_installed} ? 1 : 0; 512 } 513 514 sub post_load_initialize_metadata { 515 my $obj = shift; 516 if (defined $obj && $obj->properties->{meta_installed}) { 517 $obj->init_meta(); 518 $obj->{__meta}->set_primary_keys($obj); 519 } 520 } 521 522 sub is_meta_column { 523 my $obj = shift; 524 my ($field) = @_; 525 526 my $props = $obj->properties; 527 return unless $props->{meta_installed}; 528 529 my $meta = $obj->meta_pkg; 530 return 1 if $props->{fields}{$field}; 531 532 return; 533 } 534 535 sub meta_pkg { 536 my $class = shift; 537 my $props = $class->properties; 538 return unless $props->{meta}; # this only works for meta-enabled classes 539 540 return $props->{meta_pkg} if $props->{meta_pkg}; 541 542 my $meta = ref $class || $class; 543 $meta .= '::Meta'; 544 return $props->{meta_pkg} = $meta; 545 } 546 547 sub has_column { 548 my $obj = shift; 549 return 1 if $obj->SUPER::has_column(@_); 550 return 1 if $obj->is_meta_column(@_); 551 return; 552 } 553 554 sub post_save_save_metadata { 555 my $obj = shift; 556 if (defined $obj && exists $obj->{__meta}) { 557 $obj->{__meta}->set_primary_keys($obj); 558 $obj->{__meta}->save; 559 } 560 } 561 562 sub meta { 563 my $obj = shift; 564 my ($name, $value) = @_; 565 566 return !$obj->{__meta} ? undef 567 : 2 == scalar @_ ? $obj->{__meta}->set($name, $value) 568 : 1 == scalar @_ ? $obj->{__meta}->get($name) 569 : $obj->{__meta}->get_hash 570 ; 571 } 572 573 sub meta_obj { 574 my $obj = shift; 575 return $obj->{__meta}; 576 } 577 578 sub column_func { 579 my $obj = shift; 580 my ($col) = @_; 581 return if !$col; 582 583 return $obj->SUPER::column_func(@_) 584 if !$obj->is_meta_column($col); 585 586 return sub { 587 my $obj = shift; 443 588 if (@_) { 444 $meta->{$var} = shift if @_; 445 $obj->{changed_cols}{$meta_col}++; 446 } 447 return $meta->{$var}; 448 } else { 449 my $meta = $obj->column($meta_col); 450 if (!ref $meta) { 451 $meta = __thaw_meta(\$meta); 452 $obj->{column_values}{$meta_col} = $meta; 453 } 454 # we should assume changes are going to be made, since 455 # we can't really monitor the hash once it has left us 456 $obj->{changed_cols}{$meta_col}++; 457 return $meta; 458 } 589 $obj->{__meta}->set($col, @_); 590 } 591 else { 592 $obj->{__meta}->get($col); 593 } 594 }; 459 595 } 460 596 … … 466 602 my $ret = sprintf '%04d-%02d-%02d %02d:%02d:%02d', unpack 'A4A2A2A2A2A2', $_[0]; 467 603 return $ret; 468 } 604 } 469 605 470 606 sub db2ts { … … 754 890 } 755 891 892 sub clone_all { 893 my $obj = shift; 894 my $clone = $obj->SUPER::clone_all(); 895 $clone->{__meta} = $obj->{__meta}; # TODO: clone this too 896 return $clone; 897 } 898 756 899 sub clone { 757 900 my $obj = shift; 758 901 my($param) = @_; 759 my $clone = $obj-> SUPER::clone_all;902 my $clone = $obj->clone_all(); 760 903 761 904 ## If the caller has listed a set of columns not to copy to the clone, … … 821 964 } 822 965 966 sub remove_meta { 967 my $obj = shift; 968 return 1 unless ref $obj; 969 my $mpkg = $obj->meta_pkg or return; 970 my $id_field = $obj->datasource . '_id'; 971 return $mpkg->remove({ $id_field => $obj->id }); 972 } 973 823 974 sub remove_children { 824 975 my $obj = shift; … … 834 985 my $obj_id = $obj->id; 835 986 for my $class (@classes) { 836 eval " use $class;";987 eval "# line " . __LINE__ . " " . __FILE__ . "\nuse $class;"; 837 988 $class->remove({ $key => $obj_id }); 838 989 } … … 943 1094 $def{key} = 1 if ($props->{primary_key}) && ($props->{primary_key} eq $col); 944 1095 $def{auto} = 1 if $def =~ m/\bauto[_ ]increment\b/i; 945 $def{default} = $props->{defaults}{$col} if exists $props->{defaults}{$col}; 1096 $def{default} = $props->{defaults}{$col} 1097 if exists $props->{defaults}{$col}; 946 1098 \%def; 947 1099 } … … 1008 1160 $hash; 1009 1161 } 1162 1163 package MT::Object::Meta; 1164 1165 use base qw( Data::ObjectDriver::BaseObject ); 1166 1167 sub driver { $MT::Object::DRIVER ||= MT::ObjectDriverFactory->new } 1168 1169 sub install_properties { 1170 my $class = shift; 1171 my ($props) = @_; 1172 $props->{column_defs}->{$_} ||= 'string' 1173 for @{ $props->{columns} }; 1174 $class->SUPER::install_properties(@_); 1175 } 1176 1177 sub meta_pkg { undef } 1178 1179 *table_name = \&MT::Object::table_name; 1180 *column_defs = \&MT::Object::column_defs; 1181 *column_def = \&MT::Object::column_def; 1182 *index_defs = \&MT::Object::index_defs; 1183 *__parse_defs = \&MT::Object::__parse_defs; 1184 *__parse_def = \&MT::Object::__parse_def; 1185 *count = \&MT::Object::count; 1186 *columns_of_type = \&MT::Object::columns_of_type; 1187 1188 # TODO: copy this too 1189 sub blob_requires_zip {} 1010 1190 1011 1191 1; branches/release-35/lib/MT/ObjectDriver/DDL/mysql.pm
r1174 r1927 22 22 my $field_prefix = $class->datasource; 23 23 my $table_name = $class->table_name; 24 local $dbh->{RaiseError} = 0; 24 25 my $sth = $dbh->prepare('SHOW INDEX FROM ' . $table_name) 25 26 or return undef; branches/release-35/lib/MT/Template.pm
r1877 r1927 35 35 'build_type' => 'smallint', 36 36 'build_interval' => 'integer', 37 38 # meta properties 39 'last_rebuild_time' => 'integer meta', 40 'page_layout' => 'string meta', 41 'include_with_ssi' => 'integer meta', 42 'use_cache' => 'integer meta', 43 'cache_expire_type' => 'integer meta', 44 'cache_expire_interval' => 'integer meta', 45 'cache_expire_event' => 'string meta', 37 46 }, 38 47 indexes => { … … 54 63 datasource => 'template', 55 64 primary_key => 'id', 56 });57 __PACKAGE__->install_meta({58 columns => [59 'last_rebuild_time',60 'page_layout',61 'include_with_ssi',62 'use_cache',63 'cache_expire_type',64 'cache_expire_interval',65 'cache_expire_event',66 ],67 65 }); 68 66 __PACKAGE__->add_trigger('pre_remove' => \&pre_remove_children); branches/release-35/lib/MT/Upgrade.pm
r1897 r1927 1352 1352 } 1353 1353 } 1354 1355 # handle schema updates for meta table 1356 if ($class->meta_pkg) { 1357 $self->check_type($type . ':meta'); 1358 } 1359 1354 1360 1; 1355 1361 } branches/release-35/t/09-image.t
r1100 r1927 25 25 ); 26 26 @drivers = qw( ImageMagick NetPBM ); 27 plan tests => scalar @Img + scalar @Img * scalar @drivers * 17; 27 plan tests => scalar @Img # file exists 28 + (scalar @Img * scalar @drivers * 18) # 18 tests each for every image and driver 29 ; 28 30 } 29 31 … … 38 40 39 41 for my $rec (@Img) { 40 my $img_file = File::Spec->catfile($BASE, 't', 'images', $rec->[0]); 42 my ($img_filename, $img_width, $img_height) = @$rec; 43 my $img_file = File::Spec->catfile($BASE, 't', 'images', $img_filename); 41 44 ok(-B $img_file, "$img_file looks like a binary file"); 42 45 … … 46 49 SKIP : { 47 50 skip("no $driver image", 17) unless $img; 48 isa_ok($img, 'MT::Image::' . $driver );51 isa_ok($img, 'MT::Image::' . $driver, "driver $driver with image $img_file is an MT::Image::$driver"); 49 52 # diag( MT::Image->errstr ) if MT::Image->errstr; 50 53 51 is($img->{width}, $rec->[1], "width is $rec->[1]");52 is($img->{height}, $ rec->[2], "height is $rec->[2]");53 my($w, $h) = $img->get_dimensions ;54 is($w, $ rec->[1], "width is $rec->[1]");55 is($h, $ rec->[2], "height is $rec->[2]");54 is($img->{width}, $img_width, "$driver says $img_filename is $img_width px wide"); 55 is($img->{height}, $img_height, "$driver says $img_filename is $img_height px high"); 56 my($w, $h) = $img->get_dimensions(); 57 is($w, $img_width, "${driver}'s get_dimensions says $img_filename is $img_width px wide"); 58 is($h, $img_height, "${driver}'s get_dimensions says $img_filename is $img_height px high"); 56 59 57 60 ($w, $h) = $img->get_dimensions(Scale => 50); 58 my($x, $y) = (int($img->{width} / 2), int($img->{height} / 2)); 59 is($w, $x, "width is $x"); 60 is($h, $y, "height is $y"); 61 my($x, $y) = (int($img_width / 2), int($img_height / 2)); 62 is($w, $x, "$driver says $img_filename at 50\% scale is $x px wide"); 63 is($h, $y, "$driver says $img_filename at 50\% scale is $y px high"); 64 65 ($w, $h) = $img->get_dimensions(); 66 is($w, $img_width, "${driver}'s get_dimensions says $img_filename is still $img_width px wide after theoretical scaling"); 67 is($h, $img_height, "${driver}'s get_dimensions says $img_filename is still $img_height px high after theoretical scaling"); 61 68 62 69 ($w, $h) = $img->get_dimensions(Width => 50); 63 is($w, 50, 'width is 50');70 is($w, 50, "$driver says $img_filename scaled to 50 px wide is 50 px wide"); 64 71 65 72 ($w, $h) = $img->get_dimensions(Width => 50, Height => 100); 66 is($w, 50, 'width is 50');67 is($h, 100, 'height is 100');73 is($w, 50, "$driver says $img_filename scaled to 50x100 is 50 px wide"); 74 is($h, 100, "$driver says $img_filename scaled to 50x100 is 100 px high"); 68 75 69 76 (my($blob), $w, $h) = $img->scale(Scale => 50); 70 ($x, $y) = (int($img ->{width} / 2), int($img->{height}/ 2));71 is($w, $x, " width is $x");72 is($h, $y, " height is $y");77 ($x, $y) = (int($img_width / 2), int($img_height / 2)); 78 is($w, $x, "result of scaling $img_filename to 50\% with $driver is $x px wide"); 79 is($h, $y, "result of scaling $img_filename to 50\% with $driver is $y px high"); 73 80 74 81 open FH, $img_file or die $!; … … 80 87 isa_ok($img, 'MT::Image::' . $driver); 81 88 # diag( MT::Image->errstr ) if MT::Image->errstr; 82 is($img->{width}, $rec->[1], "width is $rec->[1]");83 is($img->{height}, $ rec->[2], "height is $rec->[2]");89 is($img->{width}, $img_width, "$driver says $img_filename from blob is $img_width px wide"); 90 is($img->{height}, $img_height, "$driver says $img_filename from blob is $img_height px high"); 84 91 ($w, $h) = $img->get_dimensions; 85 is($w, $ rec->[1], "width is $rec->[1]");86 is($h, $ rec->[2], "height is $rec->[2]");92 is($w, $img_width, "${driver}'s get_dimensions says $img_filename from blob is $img_width px wide"); 93 is($h, $img_height, "${driver}'s get_dimensions says $img_filename from blob is $img_height px high"); 87 94 } # END SKIP 88 95 } branches/release-35/t/20-setup.t
r1458 r1927 39 39 ObjectDriver DBI::sqlite 40 40 PluginPath ../plugins 41 PluginPath plugins 41 42 CFG 42 43 close $fh; branches/release-35/t/22-author.t
r1100 r1927 8 8 use lib 'extlib'; 9 9 10 use Test::More tests => 54;10 use Test::More tests => 64; 11 11 12 12 use MT; … … 34 34 my $perm = $author->blog_perm(1); 35 35 ok($perm, "$author->blog_perm(1)") || die; 36 ok($author->can_edit_entry(1), ' can_edit_entry(1)');37 ok($author->can_edit_entry(2), ' can_edit_entry(2)');36 ok($author->can_edit_entry(1), 'Chuck D can edit entry #1'); 37 ok($author->can_edit_entry(2), 'Chuck D can edit entry #2'); 38 38 ok($perm->can_comment, 'can_comment'); 39 39 ok($perm->can_post, 'can_post'); … … 58 58 59 59 { 60 diag('meta field tests'); 61 62 my $author = MT::Author->load({ name => 'Chuck D' }); 63 ok(eval { $author->widgets(); 1 }, 'Author obj has widgets accessor'); 64 ok(!defined $author->widgets, "Author's widgets are undefined by default"); 65 ok(!defined $author->favorite_blogs, "Author's favorite blogs are undefined by default"); 66 67 # same as in MT::CMS::Dashboard, but that's not necessary 68 my $default_widgets = { 69 'blog_stats' => 70 { param => { tab => 'entry' }, order => 1, set => 'main' }, 71 'this_is_you-1' => { order => 1, set => 'sidebar' }, 72 'mt_shortcuts' => { order => 2, set => 'sidebar' }, 73 'mt_news' => { order => 3, set => 'sidebar' }, 74 }; 75 76 my $fav_blogs = [1, 7]; # not actually a blog #7, but meh 77 78 ok($author->widgets($default_widgets), "Author's widgets can be set"); 79 ok($author->favorite_blogs($fav_blogs), "Author's favorite blogs can be set"); 80 ok($author->save(), "Author with modified widgets can be saved"); 81 82 require MT::ObjectDriver::Driver::Cache::RAM; 83 MT::ObjectDriver::Driver::Cache::RAM->clear_cache(); 84 85 $author = MT::Author->load({ name => 'Chuck D' }); 86 87 ok($author->widgets, "Modified author has widgets"); 88 is_deeply($author->widgets, $default_widgets, "Author's widgets survived being saved accurately"); 89 90 ok($author->favorite_blogs, "Modified author has favorite blogs"); 91 is_deeply($author->favorite_blogs, $fav_blogs, "Author's favorite blogs survived being saved accurately"); 92
