[Jifty-commit] r4001 - in apps/CASPlus/trunk: lib/CASPlus

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Wed Aug 29 12:49:46 EDT 2007


Author: sterling
Date: Wed Aug 29 12:49:46 2007
New Revision: 4001

Modified:
   apps/CASPlus/trunk/   (props changed)
   apps/CASPlus/trunk/lib/CASPlus/ProfileMixin.pm

Log:
 r8967 at riddle:  andrew | 2007-08-25 19:37:19 -0500
 First attempt at rewriting trigger handling using register_triggers_for_column().


Modified: apps/CASPlus/trunk/lib/CASPlus/ProfileMixin.pm
==============================================================================
--- apps/CASPlus/trunk/lib/CASPlus/ProfileMixin.pm	(original)
+++ apps/CASPlus/trunk/lib/CASPlus/ProfileMixin.pm	Wed Aug 29 12:49:46 2007
@@ -4,6 +4,8 @@
 package CASPlus::ProfileMixin;
 use base qw/ Jifty::DBI::Record::Plugin /;
 
+use Scalar::Util qw/ looks_like_number /;
+
 use Jifty::DBI::Schema;
 use CASPlus::Record schema {
 };
@@ -18,105 +20,224 @@
 
 =cut
 
-# =head2 register_triggers
-# 
-# This is run automatically while the profile is being constructed. It adds a C<after_set_column_name> trigger for each relationship the profile belongs to. This trigger is used to recalculate user role caches when a relationship is added or removed.
-# 
-# =cut
-# 
-# sub register_triggers {
-#     my $self = shift;
-# 
-#     my $profile = CASPlus::Model::Profile->new;
-#     $profile->load_by_profile_object($self);
-# 
-#     my $parent_relationships = $profile->parent_relationships;
-#     while (my $relationship = $parent_relationships->next) {
-#         if ($relationship->roles_propagate_to_children 
-#                 and !$relationship->many_children) {
-# 
-#             $self->add_trigger(
-#                 name     => 'after_' . $relationship->child_column->name,
-#                 callback => \&after_set_child_relationship,
-#             );
-#         }
-#     }
-# 
-#     my $child_relationships  = $profile->child_relationships;
-#     while (my $relationship = $child_relationships->next) {
-#         if ($relationship->roles_propagate_to_children
-#                 and !$relationship->many_parents) {
-# 
-#             $self->add_trigger(
-#                 name     => 'after_' . $relationship->parent_column->name,
-#                 callback => \&after_set_parent_relationship,
-#             );
-#         }
-#     }
-# }
-# 
-# =head2 after_set_child_relationship
-# 
-# This is a hook that is called automatically before modifying a column that points to a child in a relationship. This makes sure that the roles of all children, grandchildren, great-grandchildren, etc. are modified to start inheriting from this object and it's predecessors if the relationship is being added or stop if the relationship is being set to C<undef>.
-# 
-# =cut
-# 
-# sub after_set_child_relationship {
-#     my $self = shift;
-#     my $args = shift;
-# 
-#     my $column    = $args->{column};
-#     my $new_value = $args->{value};
-#     my $old_value = $self->$column;
-# 
-#     $new_value = (ref $new_value ? $new_value->id : $new_value) || 0;
-#     $old_value = (ref $old_value ? $old_value->id : $old_value) || 0;
-# 
-#     return unless $new_value != $old_value;
-# 
-#     my $profile = CASPlus::Model::Profile->new;
-#     $profile->load_by_profile_object($self);
-# 
-#     my $relationship = CASPlus::Model::ProfileRelationship->new;
-#     $relationship->load_by_cols(
-#         relation_parent => $profile,
-#         child_column    => $column,
-#     );
-# 
-#     if ($new_value) {
-#         my $new_child = $relationship->relation_child->record_class->new;
-#         $new_child->load($new_value);
-# 
-#         $new_child->_add_roles_to_child_cache($self);
-#     }
-# 
-#     if ($old_value) {
-#         my $old_child = $relationship->relation_child->record_class->new;
-#         $old_child->load($old_value);
-# 
-#         $self->_remove_roles_from_child_cache($self);
-#     }
-# }
-# 
-# =head2 after_set_parent_relationship
-# 
-# This is a hook that is called automatically before modifying a column that points to a parent in a relationship. This makes sure that the roles of this object, it's children, grandchildren, great-grandchildren, etc. are modified to start inheriting from the parent object and it's predecessors if the relationship is being added or stop if the relationship is being set to C<undef>.
-# 
-# =cut
-# 
-# sub after_set_parent_relationship {
-#     my $self = shift;
-#     my $args = shift;
-# 
-#     my $column    = $args->{column};
-#     my $new_value = $args->{value};
-#     my $old_value = $self->$column;
-# 
-#     $new_value = (ref $new_value ? $new_value->id : $new_value) || 0;
-#     $old_value = (ref $old_value ? $old_value->id : $old_value) || 0;
-# 
-#     $self->_replace_roles_in_child_cache($old_value => $new_value)
-#         if $new_value != $old_value;
-# }
+=head2 register_triggers_for_column
+
+This is run automatically while the profile is being constructed. It adds a C<after_set_column_name> trigger for each relationship the profile belongs to. This trigger is used to recalculate user role caches when a relationship is added or removed.
+
+=cut
+
+sub register_triggers_for_column {
+    my $self   = shift;
+    my $column = shift;
+
+    # Load the profile definition for this object
+    my $profile = CASPlus::Model::Profile->new;
+    $profile->load_by_profile_object($self);
+
+    # Load the model class column record for the column being registered
+    my $model_class_column = Jifty::Model::ModelClassColumn->new;
+    $model_class_column->load_by_cols(
+        model_class => $profile->model_class,
+        name        => $column,
+    );
+    return unless $model_class_column->id; # don't continue if not found
+
+    # Load the parent relationship to see if this is a child column
+    my $parent_relationship = CASPlus::Model::ProfileRelationship->new;
+    $parent_relationship->load_by_cols(
+        relation_child => $profile,
+        child_column   => $model_class_column,
+    );
+
+    # Did we find a relationship? Does it need to track roles? Is this the
+    # one-to-X end of the relationship?
+    if ($parent_relationship->id 
+            and $parent_relationship->roles_propagate_to_children 
+            and !$parent_relationship->many_parents) {
+        
+        $self->add_trigger(
+            name     => 'before_set_' . $column,
+            callback => \&before_set_child_relationship,
+        );
+        $self->add_trigger(
+            name     => 'after_set_' . $column,
+            callback => \&after_set_child_relationship,
+        );
+    }
+
+    # Load the child relationship to see if this is a parent column
+    my $child_relationship = CASPlus::Model::ProfileRelationship->new;
+    $child_relationship->load_by_cols(
+        relation_parent => $profile,
+        parent_column   => $model_class_column,
+    );
+
+    # Did we find a relationship? Does it need to track roles? Is this the
+    # one-to-X end of the relationships?
+    if ($child_relationship->id 
+            and $child_relationship->roles_propagate_to_children
+            and !$child_relationship->many_children) {
+
+        $self->add_trigger(
+            name     => 'before_set_' . $column,
+            callback => \&before_set_parent_relationship,
+        );
+        $self->add_trigger(
+            name     => 'after_set_' . $column,
+            callback => \&after_set_parent_relationship,
+        );
+    }
+}
+
+=head2 before_set_child_relationship
+
+Triggered before setting the child of this object. Saves the old value for reference in L</after_set_child_relationship>.
+
+=cut
+
+sub before_set_child_relationship {
+    my $self = shift;
+    my $args = shift;
+
+    my $column    = $args->{column};
+    my $old_value = $self->$column;
+
+    $self->{"__set_${column}_relationship_old"} = $old_value;
+
+    return 1;
+}
+
+=head2 after_set_child_relationship
+
+Handles updating the role membership cache for the column.
+
+=cut
+
+sub after_set_child_relationship {
+    my $self = shift;
+    my $args = shift;
+
+    my $column    = $args->{column};
+    my $new_value = $args->{value};
+    my $old_value = delete $self->{"__set_${column}_relationship_old"};
+
+    my $profile = CASPlus::Model::Profile->new;
+    $profile->load_by_profile_object($self);
+
+    my $model_class_column = Jifty::Model::ModelClassColumn->new;
+    $model_class_column->load_by_cols(
+        model_class => $profile->model_class,
+        name        => $column,
+    );
+
+    my $relationship = CASPlus::Model::ProfileRelationship->new;
+    $relationship->load_by_cols(
+        relation_child => $profile,
+        child_column   => $model_class_column,
+    );
+
+    if (looks_like_number($new_value)) {
+        my $object = $relationship->relation_child->record_class->new;
+        $object->load($new_value);
+        $new_value = $object;
+    }
+
+    if (defined $old_value and $old_value->id) {
+#        Test::More::diag("CHILD  DEL :@{[$old_value->unique_id]}:\@@{[$relationship->id]}:@{[$self->unique_id]}:");
+        CASPlus::Util::Relationship->remove_relationship(
+            child        => $self,
+            relationship => $relationship,
+            parent       => $old_value,
+        );
+    }
+
+    if (defined $new_value and $new_value->id) {
+#        Test::More::diag("CHILD  ADD :@{[$new_value->unique_id]}:\@@{[$relationship->id]}:@{[$self->unique_id]}:");
+        CASPlus::Util::Relationship->add_relationship(
+            child        => $self,
+            relationship => $relationship,
+            parent       => $new_value,
+        );
+    }
+}
+
+=head2 before_set_parent_relationship
+
+Triggered before setting the child of this object. Saves the old value for reference in L</after_set_parent_relationship>.
+
+=cut
+
+sub before_set_parent_relationship {
+    my $self = shift;
+    my $args = shift;
+
+    my $column    = $args->{column};
+    my $old_value = $self->$column;
+
+    Test::More::diag("new_value = @{[$args->{value}]}");
+
+    $self->{"__set_${column}_relationship_old"} = $old_value;
+
+    return 1;
+}
+
+
+=head2 after_set_parent_relationship
+
+Handles updating the role membership cache for the column.
+
+=cut
+
+sub after_set_parent_relationship {
+    my $self = shift;
+    my $args = shift;
+
+    my $column    = $args->{column};
+    my $new_value = $args->{value};
+    my $old_value = delete $self->{"__set_${column}_relationship_old"};
+
+    Test::More::diag("self = @{[$self->id.'/'.$self->unique_id]}");
+
+    my $profile = CASPlus::Model::Profile->new;
+    $profile->load_by_profile_object($self);
+
+    my $model_class_column = Jifty::Model::ModelClassColumn->new;
+    $model_class_column->load_by_cols(
+        model_class => $profile->model_class,
+        name        => $column,
+    );
+
+    my $relationship = CASPlus::Model::ProfileRelationship->new;
+    $relationship->load_by_cols(
+        relation_parent => $profile,
+        parent_column   => $model_class_column,
+    );
+
+    if (looks_like_number($new_value)) {
+        my $object = $relationship->relation_parent->record_class->new;
+        $object->load($new_value);
+        $new_value = $object;
+    }
+
+    Test::More::diag("new_value = @{[$new_value->id.'/'.$new_value->unique_id]}");
+
+    if (defined $old_value and $old_value->id) {
+#        Test::More::diag("PARENT DEL :@{[$self->unique_id]}:\@@{[$relationship->id]}:@{[$old_value->unique_id]}:");
+        CASPlus::Util::Relationship->remove_relationship(
+            child        => $old_value,
+            relationship => $relationship,
+            parent       => $self,
+        );
+    }
+
+    if (defined $new_value and $new_value->id) {
+#        Test::More::diag("PARENT ADD :@{[$self->unique_id]}:\@@{[$relationship->id]}:@{[$new_value->unique_id]}:");
+        CASPlus::Util::Relationship->add_relationship(
+            child        => $new_value,
+            relationship => $relationship,
+            parent       => $self,
+        );
+    }
+}
 
 1;


More information about the Jifty-commit mailing list