"Fossies" - the Fresh Open Source Software Archive

Member "RT-Extension-Assets-1.05/lib/RT/Assets.pm" (17 Mar 2015, 8409 Bytes) of package /linux/misc/RT-Extension-Assets-1.05.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Assets.pm" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.02_vs_1.04.

    1 # BEGIN BPS TAGGED BLOCK {{{
    2 #
    3 # COPYRIGHT:
    4 #
    5 # This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
    6 #                                          <sales@bestpractical.com>
    7 #
    8 # (Except where explicitly superseded by other copyright notices)
    9 #
   10 #
   11 # LICENSE:
   12 #
   13 # This work is made available to you under the terms of Version 2 of
   14 # the GNU General Public License. A copy of that license should have
   15 # been provided with this software, but in any event can be snarfed
   16 # from www.gnu.org.
   17 #
   18 # This work is distributed in the hope that it will be useful, but
   19 # WITHOUT ANY WARRANTY; without even the implied warranty of
   20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   21 # General Public License for more details.
   22 #
   23 # You should have received a copy of the GNU General Public License
   24 # along with this program; if not, write to the Free Software
   25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   26 # 02110-1301 or visit their web page on the internet at
   27 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
   28 #
   29 #
   30 # CONTRIBUTION SUBMISSION POLICY:
   31 #
   32 # (The following paragraph is not intended to limit the rights granted
   33 # to you to modify and distribute this software under the terms of
   34 # the GNU General Public License and is only of importance to you if
   35 # you choose to contribute your changes and enhancements to the
   36 # community by submitting them to Best Practical Solutions, LLC.)
   37 #
   38 # By intentionally submitting any modifications, corrections or
   39 # derivatives to this work, or any other work intended for use with
   40 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
   41 # you are the copyright holder for those contributions and you grant
   42 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
   43 # royalty-free, perpetual, license to use, copy, create derivative
   44 # works based on those contributions, and sublicense and distribute
   45 # those contributions and any derivatives thereof.
   46 #
   47 # END BPS TAGGED BLOCK }}}
   48 
   49 use strict;
   50 use warnings;
   51 
   52 package RT::Assets;
   53 use base 'RT::SearchBuilder';
   54 
   55 use Role::Basic "with";
   56 with "RT::SearchBuilder::Role::Roles" => { -rename => {RoleLimit => '_RoleLimit'}};
   57 
   58 use Scalar::Util qw/blessed/;
   59 
   60 =head1 NAME
   61 
   62 RT::Assets - a collection of L<RT::Asset> objects
   63 
   64 =head1 METHODS
   65 
   66 Only additional methods or overridden behaviour beyond the L<RT::SearchBuilder>
   67 (itself a L<DBIx::SearchBuilder>) class are documented below.
   68 
   69 =head2 LimitToActiveStatus
   70 
   71 =cut
   72 
   73 sub LimitToActiveStatus {
   74     my $self = shift;
   75 
   76     $self->Limit( FIELD => 'Status', VALUE => $_ )
   77         for RT::Catalog->LifecycleObj->Valid('initial', 'active');
   78 }
   79 
   80 =head2 LimitCatalog
   81 
   82 Limit Catalog
   83 
   84 =cut
   85 
   86 sub LimitCatalog {
   87     my $self = shift;
   88     my %args = (
   89         FIELD    => 'Catalog',
   90         OPERATOR => '=',
   91         @_
   92     );
   93 
   94     if ( $args{OPERATOR} eq '=' ) {
   95         $self->{Catalog} = $args{VALUE};
   96     }
   97     $self->SUPER::Limit(%args);
   98 }
   99 
  100 =head2 Limit
  101 
  102 Defaults CASESENSITIVE to 0
  103 
  104 =cut
  105 
  106 sub Limit {
  107     my $self = shift;
  108     my %args = (
  109         CASESENSITIVE => 0,
  110         @_
  111     );
  112     $self->SUPER::Limit(%args);
  113 }
  114 
  115 =head2 RoleLimit
  116 
  117 Re-uses the underlying JOIN, if possible.
  118 
  119 =cut
  120 
  121 sub RoleLimit {
  122     my $self = shift;
  123     my %args = (
  124         TYPE => '',
  125         SUBCLAUSE => '',
  126         OPERATOR => '=',
  127         @_
  128     );
  129 
  130     my $key = "role-join-".join("-",map {$args{$_}//''} qw/SUBCLAUSE TYPE OPERATOR/);
  131     my @ret = $self->_RoleLimit(%args, BUNDLE => $self->{$key} );
  132     $self->{$key} = \@ret;
  133 }
  134 
  135 =head1 INTERNAL METHODS
  136 
  137 Public methods which encapsulate implementation details.  You shouldn't need to
  138 call these in normal code.
  139 
  140 =head2 AddRecord
  141 
  142 Checks the L<RT::Asset> is readable before adding it to the results
  143 
  144 =cut
  145 
  146 sub AddRecord {
  147     my $self  = shift;
  148     my $asset = shift;
  149     return unless $asset->CurrentUserCanSee;
  150 
  151     return if $asset->__Value('Status') eq 'deleted'
  152         and not $self->{'allow_deleted_search'};
  153 
  154     $self->SUPER::AddRecord($asset, @_);
  155 }
  156 
  157 =head2 NewItem
  158 
  159 Returns a new empty RT::Asset item
  160 
  161 =cut
  162 
  163 sub NewItem {
  164     my $self = shift;
  165     return RT::Asset->new( $self->CurrentUser );
  166 }
  167 
  168 =head1 PRIVATE METHODS
  169 
  170 =head2 _Init
  171 
  172 Sets default ordering by Name ascending.
  173 
  174 =cut
  175 
  176 sub _Init {
  177     my $self = shift;
  178 
  179     $self->OrderBy( FIELD => 'Name', ORDER => 'ASC' );
  180     return $self->SUPER::_Init( @_ );
  181 }
  182 
  183 sub SimpleSearch {
  184     my $self = shift;
  185     my %args = (
  186         Fields      => RT->Config->Get('AssetSearchFields'),
  187         Catalog     => RT->Config->Get('DefaultCatalog'),
  188         Term        => undef,
  189         @_
  190     );
  191 
  192     # XXX: We only search a single catalog so that we can map CF names
  193     # to their ids, as searching CFs by CF name is rather complicated
  194     # and currently fails in odd ways.  Such a mapping obviously assumes
  195     # that names are unique within the catalog, but ids are also
  196     # allowable as well.
  197     my $catalog;
  198     if (ref $args{Catalog}) {
  199         $catalog = $args{Catalog};
  200     } else {
  201         $catalog = RT::Catalog->new( $self->CurrentUser );
  202         $catalog->Load( $args{Catalog} );
  203     }
  204 
  205     my %cfs;
  206     my $cfs = $catalog->AssetCustomFields;
  207     while (my $customfield = $cfs->Next) {
  208         $cfs{$customfield->id} = $cfs{$customfield->Name}
  209             = $customfield;
  210     }
  211 
  212     $self->LimitCatalog( VALUE => $catalog->id );
  213 
  214     while (my ($name, $op) = each %{$args{Fields}}) {
  215         $op = 'STARTSWITH'
  216             unless $op =~ /^(?:LIKE|(?:START|END)SWITH|=|!=)$/i;
  217 
  218         if ($name =~ /^CF\.(?:\{(.*)}|(.*))$/) {
  219             my $cfname = $1 || $2;
  220             $self->LimitCustomField(
  221                 CUSTOMFIELD     => $cfs{$cfname},
  222                 OPERATOR        => $op,
  223                 VALUE           => $args{Term},
  224                 ENTRYAGGREGATOR => 'OR',
  225                 SUBCLAUSE       => 'autocomplete',
  226             ) if $cfs{$cfname};
  227         } elsif ($name eq 'id' and $op =~ /(?:LIKE|(?:START|END)SWITH)$/i) {
  228             $self->Limit(
  229                 FUNCTION        => "CAST( main.$name AS TEXT )",
  230                 OPERATOR        => $op,
  231                 VALUE           => $args{Term},
  232                 ENTRYAGGREGATOR => 'OR',
  233                 SUBCLAUSE       => 'autocomplete',
  234             ) if $args{Term} =~ /^\d+$/;
  235         } else {
  236             $self->Limit(
  237                 FIELD           => $name,
  238                 OPERATOR        => $op,
  239                 VALUE           => $args{Term},
  240                 ENTRYAGGREGATOR => 'OR',
  241                 SUBCLAUSE       => 'autocomplete',
  242             ) unless $args{Term} =~ /\D/ and $name eq 'id';
  243         }
  244     }
  245     return $self;
  246 }
  247 
  248 sub OrderByCols {
  249     my $self = shift;
  250     my @res  = ();
  251 
  252     my $class = $self->_RoleGroupClass;
  253 
  254     for my $row (@_) {
  255         if ($row->{FIELD} =~ /^CF\.(?:\{(.*)\}|(.*))$/) {
  256             my $name = $1 || $2;
  257             my $cf = RT::CustomField->new( $self->CurrentUser );
  258             $cf->LoadByNameAndCatalog(
  259                 Name => $name,
  260                 Catalog => $self->{'Catalog'},
  261             );
  262             if ( $cf->id ) {
  263                 push @res, $self->_OrderByCF( $row, $cf->id, $cf );
  264             }
  265         } elsif ($row->{FIELD} =~ /^(\w+)(?:\.(\w+))?$/) {
  266             my ($role, $subkey) = ($1, $2);
  267             if ($class->HasRole($role)) {
  268                 $self->{_order_by_role}{ $role }
  269                         ||= ( $self->_WatcherJoin( Name => $role, Class => $class) )[2];
  270                 push @res, {
  271                     %$row,
  272                     ALIAS => $self->{_order_by_role}{ $role },
  273                     FIELD => $subkey || 'EmailAddress',
  274                 };
  275             } else {
  276                 push @res, $row;
  277             }
  278         } else {
  279             push @res, $row;
  280         }
  281     }
  282     return $self->SUPER::OrderByCols( @res );
  283 }
  284 
  285 =head2 _DoSearch
  286 
  287 =head2 _DoCount
  288 
  289 Limits to non-deleted assets unless the C<allow_deleted_search> flag is set.
  290 
  291 =cut
  292 
  293 sub _DoSearch {
  294     my $self = shift;
  295     $self->Limit( FIELD => 'Status', OPERATOR => '!=', VALUE => 'deleted', SUBCLAUSE => "not_deleted" )
  296         unless $self->{'allow_deleted_search'};
  297     $self->SUPER::_DoSearch(@_);
  298 }
  299 
  300 sub _DoCount {
  301     my $self = shift;
  302     $self->Limit( FIELD => 'Status', OPERATOR => '!=', VALUE => 'deleted', SUBCLAUSE => "not_deleted" )
  303         unless $self->{'allow_deleted_search'};
  304     $self->SUPER::_DoCount(@_);
  305 }
  306 
  307 sub Table { "RTxAssets" }
  308 
  309 RT::Base->_ImportOverlays();
  310 
  311 1;