[Rt-commit] rt branch, 4.0/apply-scrips-to-multiple-queues, created. rt-4.0.4-118-g01a7fc4
Ruslan Zakirov
ruz at bestpractical.com
Mon Dec 12 11:29:30 EST 2011
The branch, 4.0/apply-scrips-to-multiple-queues has been created
at 01a7fc4ca83b77aa23b48906660e345571cc7a7b (commit)
- Log -----------------------------------------------------------------
commit 01a7fc4ca83b77aa23b48906660e345571cc7a7b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date: Mon Dec 12 19:05:31 2011 +0400
extract re-usable code from ObjectCustomField[s]
Two new classes for records and collections
diff --git a/lib/RT/ObjectCustomField.pm b/lib/RT/ObjectCustomField.pm
index 45286ed..f2d47a7 100644
--- a/lib/RT/ObjectCustomField.pm
+++ b/lib/RT/ObjectCustomField.pm
@@ -45,93 +45,23 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
-
-package RT::ObjectCustomField;
-
use strict;
use warnings;
+package RT::ObjectCustomField;
+use base 'RT::Record::ApplyAndSort';
use RT::CustomField;
-use base 'RT::Record';
+use RT::ObjectCustomFields;
sub Table {'ObjectCustomFields'}
-
-
-
-
-
-sub Create {
- my $self = shift;
- my %args = (
- CustomField => 0,
- ObjectId => 0,
- SortOrder => undef,
- @_
- );
-
- my $cf = $self->CustomFieldObj( $args{'CustomField'} );
- unless ( $cf->id ) {
- $RT::Logger->error("Couldn't load '$args{'CustomField'}' custom field");
- return 0;
- }
-
- #XXX: Where is ACL check for 'AssignCustomFields'?
-
- my $ObjectCFs = RT::ObjectCustomFields->new($self->CurrentUser);
- $ObjectCFs->LimitToObjectId( $args{'ObjectId'} );
- $ObjectCFs->LimitToCustomField( $cf->id );
- $ObjectCFs->LimitToLookupType( $cf->LookupType );
- if ( my $first = $ObjectCFs->First ) {
- $self->Load( $first->id );
- return $first->id;
- }
-
- unless ( defined $args{'SortOrder'} ) {
- my $ObjectCFs = RT::ObjectCustomFields->new( RT->SystemUser );
- $ObjectCFs->LimitToObjectId( $args{'ObjectId'} );
- $ObjectCFs->LimitToObjectId( 0 ) if $args{'ObjectId'};
- $ObjectCFs->LimitToLookupType( $cf->LookupType );
- $ObjectCFs->OrderBy( FIELD => 'SortOrder', ORDER => 'DESC' );
- if ( my $first = $ObjectCFs->First ) {
- $args{'SortOrder'} = $first->SortOrder + 1;
- } else {
- $args{'SortOrder'} = 0;
- }
- }
-
- return $self->SUPER::Create(
- CustomField => $args{'CustomField'},
- ObjectId => $args{'ObjectId'},
- SortOrder => $args{'SortOrder'},
- );
-}
-
-sub Delete {
- my $self = shift;
-
- my $ObjectCFs = RT::ObjectCustomFields->new($self->CurrentUser);
- $ObjectCFs->LimitToObjectId($self->ObjectId);
- $ObjectCFs->LimitToLookupType($self->CustomFieldObj->LookupType);
-
- # Move everything below us up
- my $sort_order = $self->SortOrder;
- while (my $OCF = $ObjectCFs->Next) {
- my $this_order = $OCF->SortOrder;
- next if $this_order <= $sort_order;
- $OCF->SetSortOrder($this_order - 1);
- }
-
- $self->SUPER::Delete;
-}
-
+# XXX: Where is ACL check when we create a record?
=head2 CustomFieldObj
Returns the CustomField Object which has the id returned by CustomField
-
=cut
sub CustomFieldObj {
@@ -142,148 +72,17 @@ sub CustomFieldObj {
return $CF;
}
-=head2 Sorting custom fields applications
-
-Custom fields sorted on multiple layers. First of all custom
-fields with different lookup type are sorted independently. All
-global custom fields have fixed order for all objects, but you
-can insert object specific custom fields between them. Object
-specific custom fields can be applied to several objects and
-be on different place. For example you have GCF1, GCF2, LCF1,
-LCF2 and LCF3 that applies to tickets. You can place GCF2
-above GCF1, but they will be in the same order in all queues.
-However, LCF1 and other local can be placed at any place
-for particular queue: above global, between them or below.
-
-=head3 MoveUp
-
-Moves custom field up. See </Sorting custom fields applications>.
-
-=cut
-
-sub MoveUp {
+sub Neighbors {
my $self = shift;
+ my %args = @_;
- my $ocfs = RT::ObjectCustomFields->new( $self->CurrentUser );
-
- my $oid = $self->ObjectId;
- $ocfs->LimitToObjectId( $oid );
- if ( $oid ) {
- $ocfs->LimitToObjectId( 0 );
- }
-
- my $cf = $self->CustomFieldObj;
- $ocfs->LimitToLookupType( $cf->LookupType );
-
- $ocfs->Limit( FIELD => 'SortOrder', OPERATOR => '<', VALUE => $self->SortOrder );
- $ocfs->OrderByCols( { FIELD => 'SortOrder', ORDER => 'DESC' } );
-
- my @above = ($ocfs->Next, $ocfs->Next);
- unless ($above[0]) {
- return (0, "Can not move up. It's already at the top");
- }
-
- my $new_sort_order;
- if ( $above[0]->ObjectId == $self->ObjectId ) {
- $new_sort_order = $above[0]->SortOrder;
- my ($status, $msg) = $above[0]->SetSortOrder( $self->SortOrder );
- unless ( $status ) {
- return (0, "Couldn't move custom field");
- }
- }
- elsif ( $above[1] && $above[0]->SortOrder == $above[1]->SortOrder + 1 ) {
- my $move_ocfs = RT::ObjectCustomFields->new( RT->SystemUser );
- $move_ocfs->LimitToLookupType( $cf->LookupType );
- $move_ocfs->Limit(
- FIELD => 'SortOrder',
- OPERATOR => '>=',
- VALUE => $above[0]->SortOrder,
- );
- $move_ocfs->OrderByCols( { FIELD => 'SortOrder', ORDER => 'DESC' } );
- while ( my $record = $move_ocfs->Next ) {
- my ($status, $msg) = $record->SetSortOrder( $record->SortOrder + 1 );
- unless ( $status ) {
- return (0, "Couldn't move custom field");
- }
- }
- $new_sort_order = $above[0]->SortOrder;
- } else {
- $new_sort_order = $above[0]->SortOrder - 1;
- }
-
- my ($status, $msg) = $self->SetSortOrder( $new_sort_order );
- unless ( $status ) {
- return (0, "Couldn't move custom field");
- }
-
- return (1,"Moved custom field up");
-}
-
-=head3 MoveDown
-
-Moves custom field down. See </Sorting custom fields applications>.
-
-=cut
-
-sub MoveDown {
- my $self = shift;
-
- my $ocfs = RT::ObjectCustomFields->new( $self->CurrentUser );
-
- my $oid = $self->ObjectId;
- $ocfs->LimitToObjectId( $oid );
- if ( $oid ) {
- $ocfs->LimitToObjectId( 0 );
- }
-
- my $cf = $self->CustomFieldObj;
- $ocfs->LimitToLookupType( $cf->LookupType );
-
- $ocfs->Limit( FIELD => 'SortOrder', OPERATOR => '>', VALUE => $self->SortOrder );
- $ocfs->OrderByCols( { FIELD => 'SortOrder', ORDER => 'ASC' } );
-
- my @below = ($ocfs->Next, $ocfs->Next);
- unless ($below[0]) {
- return (0, "Can not move down. It's already at the bottom");
- }
-
- my $new_sort_order;
- if ( $below[0]->ObjectId == $self->ObjectId ) {
- $new_sort_order = $below[0]->SortOrder;
- my ($status, $msg) = $below[0]->SetSortOrder( $self->SortOrder );
- unless ( $status ) {
- return (0, "Couldn't move custom field");
- }
- }
- elsif ( $below[1] && $below[0]->SortOrder + 1 == $below[1]->SortOrder ) {
- my $move_ocfs = RT::ObjectCustomFields->new( RT->SystemUser );
- $move_ocfs->LimitToLookupType( $cf->LookupType );
- $move_ocfs->Limit(
- FIELD => 'SortOrder',
- OPERATOR => '<=',
- VALUE => $below[0]->SortOrder,
- );
- $move_ocfs->OrderByCols( { FIELD => 'SortOrder', ORDER => 'ASC' } );
- while ( my $record = $move_ocfs->Next ) {
- my ($status, $msg) = $record->SetSortOrder( $record->SortOrder - 1 );
- unless ( $status ) {
- return (0, "Couldn't move custom field");
- }
- }
- $new_sort_order = $below[0]->SortOrder;
- } else {
- $new_sort_order = $below[0]->SortOrder + 1;
- }
-
- my ($status, $msg) = $self->SetSortOrder( $new_sort_order );
- unless ( $status ) {
- return (0, "Couldn't move custom field");
- }
-
- return (1,"Moved custom field down");
+ my $res = $self->CollectionClass->new( $self->CurrentUser );
+ $res->LimitToLookupType(
+ ($args{'CustomField'} || $self->CustomFieldObj)->LookupType
+ );
+ return $res;
}
-
=head2 id
Returns the current value of id.
diff --git a/lib/RT/ObjectCustomFields.pm b/lib/RT/ObjectCustomFields.pm
index fa2a69e..bdb6511 100644
--- a/lib/RT/ObjectCustomFields.pm
+++ b/lib/RT/ObjectCustomFields.pm
@@ -45,48 +45,23 @@
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}
-
-package RT::ObjectCustomFields;
-
use strict;
use warnings;
+package RT::ObjectCustomFields;
+use base 'RT::SearchBuilder::ApplyAndSort';
+use RT::CustomField;
use RT::ObjectCustomField;
-use base 'RT::SearchBuilder';
-
sub Table { 'ObjectCustomFields'}
-sub _Init {
- my $self = shift;
-
- # By default, order by SortOrder
- $self->OrderByCols(
- { ALIAS => 'main',
- FIELD => 'SortOrder',
- ORDER => 'ASC' },
- { ALIAS => 'main',
- FIELD => 'id',
- ORDER => 'ASC' },
- );
-
- return ( $self->SUPER::_Init(@_) );
-}
-
-
sub LimitToCustomField {
my $self = shift;
my $id = shift;
$self->Limit( FIELD => 'CustomField', VALUE => $id );
}
-sub LimitToObjectId {
- my $self = shift;
- my $id = shift || 0;
- $self->Limit( FIELD => 'ObjectId', VALUE => $id );
-}
-
sub LimitToLookupType {
my $self = shift;
my $lookup = shift;
@@ -139,17 +114,6 @@ sub _DoSearch {
$self->SUPER::_DoSearch()
}
-
-=head2 NewItem
-
-Returns an empty new RT::ObjectCustomField item
-
-=cut
-
-sub NewItem {
- my $self = shift;
- return(RT::ObjectCustomField->new($self->CurrentUser));
-}
RT::Base->_ImportOverlays();
1;
diff --git a/lib/RT/Record/ApplyAndSort.pm b/lib/RT/Record/ApplyAndSort.pm
new file mode 100644
index 0000000..943417c
--- /dev/null
+++ b/lib/RT/Record/ApplyAndSort.pm
@@ -0,0 +1,227 @@
+use strict;
+use warnings;
+
+package RT::Record::ApplyAndSort;
+use base 'RT::Record';
+
+sub CollectionClass {
+ return (ref($_[0]) || $_[0]).'s';
+}
+
+sub TargetField {
+ my $class = ref($_[0]) || $_[0];
+ $class =~ s/.*::Object// or return undef;
+ return $class;
+}
+
+sub Create {
+ my $self = shift;
+ my %args = (
+ Scrip => 0,
+ ObjectId => 0,
+ SortOrder => undef,
+ @_
+ );
+
+ my $tfield = $self->TargetField;
+
+ my $target = $self->TargetObj( $args{ $tfield } );
+ unless ( $target->id ) {
+ $RT::Logger->error("Couldn't load ". ref($target) ." '$args{'Scrip'}'");
+ return 0;
+ }
+
+ my $exist = $self->new($self->CurrentUser);
+ $exist->LoadByCols( ObjectId => $args{'ObjectId'}, $tfield => $target->id );
+ if ( $exist->id ) {
+ $self->Load( $exist->id );
+ return $self->id;
+ }
+
+ unless ( defined $args{'SortOrder'} ) {
+ $args{'SortOrder'} = $self->NextSortOrder(
+ $tfield => $target,
+ ObjectId => $args{'ObjectId'},
+ );
+ }
+
+ return $self->SUPER::Create(
+ $tfield => $target->id,
+ ObjectId => $args{'ObjectId'},
+ SortOrder => $args{'SortOrder'},
+ );
+}
+
+sub Delete {
+ my $self = shift;
+
+ my $siblings = $self->Neighbors;
+ $siblings->LimitToObjectId( $self->ObjectId );
+ $siblings->Limit( FIELD => 'SortOrder', OPERATOR => '>', VALUE => $self->SortOrder );
+
+ # Move everything below us up
+ my $sort_order = $self->SortOrder;
+ while (my $record = $siblings->Next) {
+ $record->SetSortOrder($record->SortOrder - 1);
+ }
+
+ $self->SUPER::Delete;
+}
+
+=head2 Sorting scrips applications
+
+scrips sorted on multiple layers. First of all custom
+fields with different lookup type are sorted independently. All
+global scrips have fixed order for all objects, but you
+can insert object specific scrips between them. Object
+specific scrips can be applied to several objects and
+be on different place. For example you have GCF1, GCF2, LCF1,
+LCF2 and LCF3 that applies to tickets. You can place GCF2
+above GCF1, but they will be in the same order in all queues.
+However, LCF1 and other local can be placed at any place
+for particular queue: above global, between them or below.
+
+=head3 MoveUp
+
+Moves scrip up. See </Sorting scrips applications>.
+
+=cut
+
+sub MoveUp {
+ my $self = shift;
+
+ my $siblings = $self->Siblings;
+ $siblings->Limit( FIELD => 'SortOrder', OPERATOR => '<', VALUE => $self->SortOrder );
+ $siblings->OrderByCols( { FIELD => 'SortOrder', ORDER => 'DESC' } );
+
+ my @above = ($siblings->Next, $siblings->Next);
+ unless ($above[0]) {
+ return (0, "Can not move up. It's already at the top");
+ }
+
+ my $new_sort_order;
+ if ( $above[0]->ObjectId == $self->ObjectId ) {
+ $new_sort_order = $above[0]->SortOrder;
+ my ($status, $msg) = $above[0]->SetSortOrder( $self->SortOrder );
+ unless ( $status ) {
+ return (0, "Couldn't move scrip");
+ }
+ }
+ elsif ( $above[1] && $above[0]->SortOrder == $above[1]->SortOrder + 1 ) {
+ my $move_siblings = $self->Neighbors;
+ $move_siblings->Limit(
+ FIELD => 'SortOrder',
+ OPERATOR => '>=',
+ VALUE => $above[0]->SortOrder,
+ );
+ $move_siblings->OrderByCols( { FIELD => 'SortOrder', ORDER => 'DESC' } );
+ while ( my $record = $move_siblings->Next ) {
+ my ($status, $msg) = $record->SetSortOrder( $record->SortOrder + 1 );
+ unless ( $status ) {
+ return (0, "Couldn't move scrip");
+ }
+ }
+ $new_sort_order = $above[0]->SortOrder;
+ } else {
+ $new_sort_order = $above[0]->SortOrder - 1;
+ }
+
+ my ($status, $msg) = $self->SetSortOrder( $new_sort_order );
+ unless ( $status ) {
+ return (0, "Couldn't move scrip");
+ }
+
+ return (1,"Moved scrip up");
+}
+
+=head3 MoveDown
+
+Moves scrip down. See </Sorting scrips applications>.
+
+=cut
+
+sub MoveDown {
+ my $self = shift;
+
+ my $siblings = $self->Siblings;
+ $siblings->Limit( FIELD => 'SortOrder', OPERATOR => '>', VALUE => $self->SortOrder );
+ $siblings->OrderByCols( { FIELD => 'SortOrder', ORDER => 'ASC' } );
+
+ my @below = ($siblings->Next, $siblings->Next);
+ unless ($below[0]) {
+ return (0, "Can not move down. It's already at the bottom");
+ }
+
+ my $new_sort_order;
+ if ( $below[0]->ObjectId == $self->ObjectId ) {
+ $new_sort_order = $below[0]->SortOrder;
+ my ($status, $msg) = $below[0]->SetSortOrder( $self->SortOrder );
+ unless ( $status ) {
+ return (0, "Couldn't move scrip");
+ }
+ }
+ elsif ( $below[1] && $below[0]->SortOrder + 1 == $below[1]->SortOrder ) {
+ my $move_siblings = $self->Neighbors;
+ $move_siblings->Limit(
+ FIELD => 'SortOrder',
+ OPERATOR => '<=',
+ VALUE => $below[0]->SortOrder,
+ );
+ $move_siblings->OrderByCols( { FIELD => 'SortOrder', ORDER => 'ASC' } );
+ while ( my $record = $move_siblings->Next ) {
+ my ($status, $msg) = $record->SetSortOrder( $record->SortOrder - 1 );
+ unless ( $status ) {
+ return (0, "Couldn't move scrip");
+ }
+ }
+ $new_sort_order = $below[0]->SortOrder;
+ } else {
+ $new_sort_order = $below[0]->SortOrder + 1;
+ }
+
+ my ($status, $msg) = $self->SetSortOrder( $new_sort_order );
+ unless ( $status ) {
+ return (0, "Couldn't move scrip");
+ }
+
+ return (1,"Moved scrip down");
+}
+
+sub NextSortOrder {
+ my $self = shift;
+ my $siblings = $self->Siblings( @_ );
+ $siblings->OrderBy( FIELD => 'SortOrder', ORDER => 'DESC' );
+ return 0 unless my $first = $siblings->First;
+ return $first->SortOrder + 1;
+}
+
+sub TargetObj {
+ my $self = shift;
+ my $id = shift;
+
+ my $method = $self->TargetField .'Obj';
+ return $self->$method( $id );
+}
+
+sub Neighbors {
+ my $self = shift;
+ return $self->CollectionClass->new( $self->CurrentUser );
+}
+
+sub Siblings {
+ my $self = shift;
+ my %args = @_;
+
+ my $oid = $args{'ObjectId'};
+ $oid = $self->ObjectId unless defined $oid;
+ $oid ||= 0;
+
+ my $res = $self->Neighbors( %args );
+ $res->LimitToObjectId( $oid );
+ $res->LimitToObjectId( 0 ) if $oid;
+ return $res;
+}
+
+RT::Base->_ImportOverlays();
+
+1;
diff --git a/lib/RT/SearchBuilder/ApplyAndSort.pm b/lib/RT/SearchBuilder/ApplyAndSort.pm
new file mode 100644
index 0000000..960eaa7
--- /dev/null
+++ b/lib/RT/SearchBuilder/ApplyAndSort.pm
@@ -0,0 +1,48 @@
+use strict;
+use warnings;
+
+package RT::SearchBuilder::ApplyAndSort;
+use base 'RT::SearchBuilder';
+
+sub RecordClass {
+ my $class = ref($_[0]) || $_[0];
+ $class =~ s/s$// or return undef;
+ return $class;
+}
+
+sub _Init {
+ my $self = shift;
+
+ # By default, order by SortOrder
+ $self->OrderByCols(
+ { ALIAS => 'main',
+ FIELD => 'SortOrder',
+ ORDER => 'ASC' },
+ { ALIAS => 'main',
+ FIELD => 'id',
+ ORDER => 'ASC' },
+ );
+
+ return $self->SUPER::_Init(@_);
+}
+
+sub LimitToObjectId {
+ my $self = shift;
+ my $id = shift || 0;
+ $self->Limit( FIELD => 'ObjectId', VALUE => $id );
+}
+
+=head2 NewItem
+
+Returns an empty new collection's item
+
+=cut
+
+sub NewItem {
+ my $self = shift;
+ return $self->RecordClass->new( $self->CurrentUser );
+}
+
+RT::Base->_ImportOverlays();
+
+1;
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list