[Rt-commit] rt branch, custom_fields_application, updated. rt-3.8.7-166-g268186c

Ruslan Zakirov ruz at bestpractical.com
Wed Feb 17 21:35:59 EST 2010


The branch, custom_fields_application has been updated
       via  268186cfce2dd4801ba16e2032d9f030d79f21c1 (commit)
       via  4040272696bbd568a1f34c4762efb3f34323886a (commit)
       via  c5f14ffaba354a3b63a8449f9d6e64cc73b70bfc (commit)
       via  d6ae7cd6026682acd5c3afb825a1834988f49db5 (commit)
      from  15ec7b4d900ecfe235f4a67e352fc5914715dabc (commit)

Summary of changes:
 lib/RT/CustomField_Overlay.pm              |  152 ++++++++++++++++++++++++----
 share/html/Admin/CustomFields/Objects.html |  138 ++++++++++++-------------
 2 files changed, 198 insertions(+), 92 deletions(-)

- Log -----------------------------------------------------------------
commit d6ae7cd6026682acd5c3afb825a1834988f49db5
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Feb 17 04:50:46 2010 +0300

    move method closer to related

diff --git a/lib/RT/CustomField_Overlay.pm b/lib/RT/CustomField_Overlay.pm
index 9286d7a..7e4a7b1 100755
--- a/lib/RT/CustomField_Overlay.pm
+++ b/lib/RT/CustomField_Overlay.pm
@@ -808,24 +808,6 @@ sub SetTypeComposite {
     );
 }
 
-=head2 SetLookupType
-
-Autrijus: care to doc how LookupTypes work?
-
-=cut
-
-sub SetLookupType {
-    my $self = shift;
-    my $lookup = shift;
-    if ( $lookup ne $self->LookupType ) {
-        # Okay... We need to invalidate our existing relationships
-        my $ObjectCustomFields = RT::ObjectCustomFields->new($self->CurrentUser);
-        $ObjectCustomFields->LimitToCustomField($self->Id);
-        $_->Delete foreach @{$ObjectCustomFields->ItemsArrayRef};
-    }
-    return $self->SUPER::SetLookupType($lookup);
-}
-
 =head2 TypeComposite
 
 Returns a composite value composed of this object's type and maximum values
@@ -849,6 +831,24 @@ sub TypeComposites {
     return grep !/(?:[Tt]ext|Combobox)-0/, map { ("$_-1", "$_-0") } $self->Types;
 }
 
+=head2 SetLookupType
+
+Autrijus: care to doc how LookupTypes work?
+
+=cut
+
+sub SetLookupType {
+    my $self = shift;
+    my $lookup = shift;
+    if ( $lookup ne $self->LookupType ) {
+        # Okay... We need to invalidate our existing relationships
+        my $ObjectCustomFields = RT::ObjectCustomFields->new($self->CurrentUser);
+        $ObjectCustomFields->LimitToCustomField($self->Id);
+        $_->Delete foreach @{$ObjectCustomFields->ItemsArrayRef};
+    }
+    return $self->SUPER::SetLookupType($lookup);
+}
+
 =head2 LookupTypes
 
 Returns an array of LookupTypes available

commit c5f14ffaba354a3b63a8449f9d6e64cc73b70bfc
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 18 03:04:52 2010 +0300

    RT::CustomField->*Applied* methods to get objects a CF is applied to
    
    $CF->AppliedTo - returns collection with objects
        this custom field applied to.
    
    $CF->NotAppliedTo - reversed version.

diff --git a/lib/RT/CustomField_Overlay.pm b/lib/RT/CustomField_Overlay.pm
index 7e4a7b1..6ac2663 100755
--- a/lib/RT/CustomField_Overlay.pm
+++ b/lib/RT/CustomField_Overlay.pm
@@ -867,7 +867,7 @@ my @FriendlyObjectTypes = (
     "[_1]'s [_2]'s [_3] objects",   # loc
 );
 
-=head2 FriendlyTypeLookup
+=head2 FriendlyLookupType
 
 Returns a localized description of the type of this custom field
 
@@ -887,6 +887,100 @@ sub FriendlyLookupType {
     return ( $self->loc( $FriendlyObjectTypes[$#types], @types ) );
 }
 
+sub RecordClassFromLookupType {
+    my $self = shift;
+    my ($class) = ($self->LookupType =~ /^([^-]+)/);
+    unless ( $class ) {
+        $RT::Logger->error(
+            "Custom Field #". $self->id 
+            ." has incorrect LookupType '". $self->LookupType ."'"
+        );
+        return undef;
+    }
+    return $class;
+}
+
+sub CollectionClassFromLookupType {
+    my $self = shift;
+
+    my $record_class = $self->RecordClassFromLookupType;
+    return undef unless $record_class;
+
+    my $collection_class;
+    if ( UNIVERSAL::can($record_class.'Collection', 'new') ) {
+        $collection_class = $record_class.'Collection';
+    } elsif ( UNIVERSAL::can($record_class.'es', 'new') ) {
+        $collection_class = $record_class.'es';
+    } elsif ( UNIVERSAL::can($record_class.'s', 'new') ) {
+        $collection_class = $record_class.'s';
+    } else {
+        $RT::Logger->error("Can not find a collection class for record class '$record_class'");
+        return undef;
+    }
+    return $collection_class;
+}
+
+sub AppliedTo {
+    my $self = shift;
+
+    my ($res, $ocfs_alias) = $self->_AppliedTo;
+    return $res unless $res;
+
+    $res->Limit(
+        ALIAS     => $ocfs_alias,
+        FIELD     => 'id',
+        OPERATOR  => 'IS NOT',
+        VALUE     => 'NULL',
+    );
+
+    return $res;
+}
+
+sub NotAppliedTo {
+    my $self = shift;
+
+    my ($res, $ocfs_alias) = $self->_AppliedTo;
+    return $res unless $res;
+
+    $res->Limit(
+        ALIAS     => $ocfs_alias,
+        FIELD     => 'id',
+        OPERATOR  => 'IS',
+        VALUE     => 'NULL',
+    );
+
+    return $res;
+}
+
+sub _AppliedTo {
+    my $self = shift;
+
+    my ($class) = $self->CollectionClassFromLookupType;
+    return undef unless $class;
+
+    my $res = $class->new( $self->CurrentUser );
+
+    # If CF is a Group CF, only display user-defined groups
+    if ( $class eq 'RT::Groups' ) {
+        $res->LimitToUserDefinedGroups;
+    }
+
+    $res->OrderBy( FIELD => 'Name' );
+    my $ocfs_alias = $res->Join(
+        TYPE   => 'LEFT',
+        ALIAS1 => 'main',
+        FIELD1 => 'id',
+        TABLE2 => 'ObjectCustomFields',
+        FIELD2 => 'ObjectId',
+    );
+    $res->Limit(
+        LEFTJOIN => $ocfs_alias,
+        ALIAS    => $ocfs_alias,
+        FIELD    => 'CustomField',
+        VALUE    => $self->id,
+    );
+    return ($res, $ocfs_alias);
+}
 
 =head2 AddToObject OBJECT
 

commit 4040272696bbd568a1f34c4762efb3f34323886a
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 18 03:17:16 2010 +0300

    POD for new functions

diff --git a/lib/RT/CustomField_Overlay.pm b/lib/RT/CustomField_Overlay.pm
index 6ac2663..d29e7fa 100755
--- a/lib/RT/CustomField_Overlay.pm
+++ b/lib/RT/CustomField_Overlay.pm
@@ -920,6 +920,16 @@ sub CollectionClassFromLookupType {
     return $collection_class;
 }
 
+=head1 AppliedTo
+
+Returns collection with objects this custom field is applied to.
+Class of the collection depends on L</LookupType>.
+See all L</NotAppliedTo> .
+
+Doesn't takes into account if object is applied globally.
+
+=cut
+
 sub AppliedTo {
     my $self = shift;
 
@@ -936,6 +946,16 @@ sub AppliedTo {
     return $res;
 }
 
+=head1 NotAppliedTo
+
+Returns collection with objects this custom field is not applied to.
+Class of the collection depends on L</LookupType>.
+See all L</AppliedTo> .
+
+Doesn't takes into account if object is applied globally.
+
+=cut
+
 sub NotAppliedTo {
     my $self = shift;
 

commit 268186cfce2dd4801ba16e2032d9f030d79f21c1
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 18 03:18:44 2010 +0300

    rewrite custom fields application
    
    In this nowaday RT we have...
    * column maps for many objects
    * column maps with check boxes
    * methods to get respctive collections

diff --git a/share/html/Admin/CustomFields/Objects.html b/share/html/Admin/CustomFields/Objects.html
index 20d79b2..ea3f88e 100644
--- a/share/html/Admin/CustomFields/Objects.html
+++ b/share/html/Admin/CustomFields/Objects.html
@@ -56,95 +56,87 @@
 
 <form action="Objects.html" method="post">
 <input type="hidden" class="hidden" name="id" value="<% $id %>" />
-<input type="hidden" class="hidden" name="UpdateObjs" value="1" />
 
 <h2><&|/l&>Selected objects</&></h2>
-<& /Admin/Elements/PickObjects, Objects => \@AssignedObjs, id => $id, Checked => 1 &>
-<h2><&|/l&>Unselected objects</&></h2>
-<& /Admin/Elements/PickObjects, Objects => \@UnassignedObjs, id => $id &>
+<& /Elements/CollectionList,
+    OrderBy => 'id',
+    Order => 'ASC',
+    %ARGS,
+    Collection => $applied,
+    Rows => 0,
+    Page => 1,
+    Format        => $format,
+    DisplayFormat => "'__CheckBox.{RemoveCustomField-". $CF->id ."}__',". $format,
+    AllowSorting => 0,
+    ShowEmpty    => 0,
+    PassArguments => [
+        qw(id Format Rows Page Order OrderBy),
+    ],
+&>
 
-<& /Elements/Submit, CheckAll => 1, ClearAll => 1 &>
+<h2><&|/l&>Unselected objects</&></h2>
+<& /Elements/CollectionList,
+    OrderBy => 'id',
+    Order => 'ASC',
+    %ARGS,
+    Collection => $not_applied,
+    Rows => 50,
+    Format        => $format,
+    DisplayFormat => "'__CheckBox.{AddCustomField-". $CF->id ."}__',". $format,
+    AllowSorting  => 1,
+    ShowEmpty     => 0,
+    PassArguments => [
+        qw(id Format Rows Page Order OrderBy),
+    ],
+&>
+
+<& /Elements/Submit, Name => 'UpdateObjs' &>
 </form>
 
 <%INIT>
 my $CF = RT::CustomField->new($session{'CurrentUser'});
 $CF->Load($id) or Abort(loc("Could not load CustomField [_1]"), $id);
-my $LookupType = $CF->LookupType || '';
-$LookupType =~ /^([^-]+)/ ||
-     Abort(loc("Object of type [_1] cannot take custom fields", $LookupType));
-
-my $Class = $1;
-my $CollectionClass;
-if (UNIVERSAL::can($Class.'Collection', 'new') ) {
-$CollectionClass = $Class.'Collection';
-
-} elsif (UNIVERSAL::can($Class.'es', 'new') ) {
-    $CollectionClass = $Class.'es';
-
-} elsif (UNIVERSAL::can($Class.'s', 'new') ) {
-    $CollectionClass = $Class.'s';
-
-} else {
-    Abort(loc("Can't find a collection class for '[_1]'", $Class));
-}
-
-
-my $title = loc('Modify associated objects for [_1]', $CF->Name);
-
-my $Objects = $CollectionClass->new($session{'CurrentUser'});
 
-# If CF is a Group CF, only display user-defined groups
-if ($Class eq 'RT::Group') {
-    $Objects->LimitToUserDefinedGroups;
-}
+my $class = $CF->RecordClassFromLookupType;
+Abort(loc("Something wrong. Contact system administrator"))
+    unless $class;
 
 my (@results);
-my (@AssignedObjs, @UnassignedObjs);
-
-$Objects->UnLimit;
-$Objects->OrderBy( FIELD => 'Name' );
-
-
-my $ObjectCFs;
-$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
-$ObjectCFs->UnLimit;
-$ObjectCFs->LimitToCustomField($id);
-
-my %seen;
-while (my $OCF = $ObjectCFs->Next) {
-    $seen{$OCF->ObjectId}++;
-}
 
-while (my $obj = $Objects->Next) { 
-    my $obj_id = $obj->Id;
-
-    if ($UpdateObjs) {
-	# Go through and delete all the custom field relationships that this object
-	# no longer has
-	my $key = "Object-$obj_id-CF-$id";
-	if ($ARGS{$key}) {
-	    if (!$seen{$obj_id}) {
-		my ($val, $msg) = $CF->AddToObject($obj);
-		push (@results, $msg);
-		push @UnassignedObjs, $obj if !$val;
-	    }
-	}
-	else {
-	    push @UnassignedObjs, $obj;
-	    if ($seen{$obj_id}) {
-		my ($val, $msg) = $CF->RemoveFromObject($obj);
-		push (@results, $msg);
-		pop @UnassignedObjs if !$val;
-	    }
-	}
+if ( $UpdateObjs ) {
+    if ( my $add = $ARGS{'AddCustomField-'.$CF->id} ) {
+        foreach my $id ( ref $add? (@$add) : ($add) ) {
+            my $object = $class->new( $session{'CurrentUser'} );
+            $object->Load( $id );
+            unless ( $object->id ) {
+                next;
+            }
+
+            my ($status, $msg) = $CF->AddToObject( $object );
+            push @results, $msg;
+        }
     }
-    elsif (!$seen{$obj_id}) {
-	push @UnassignedObjs, $obj;
+    if ( my $del = $ARGS{'RemoveCustomField-'.$CF->id} ) {
+        foreach my $id ( ref $del? (@$del) : ($del) ) {
+            my $object = $class->new( $session{'CurrentUser'} );
+            $object->Load( $id );
+            unless ( $object->id ) {
+                next;
+            }
+
+            my ($status, $msg) = $CF->RemoveFromObject( $object );
+            push @results, $msg;
+        }
     }
-    next if @UnassignedObjs and $UnassignedObjs[-1] == $obj;
-    push @AssignedObjs, $obj;
 }
 
+my $applied = $CF->AppliedTo;
+my $not_applied = $CF->NotAppliedTo;
+
+my $format = '__id__,__Name__';
+
+my $title = loc('Modify associated objects for [_1]', $CF->Name);
+
 </%INIT>
 <%ARGS>
 $id => undef

-----------------------------------------------------------------------


More information about the Rt-commit mailing list