diff options
Diffstat (limited to 'lib/MON/Filter.pm')
| -rw-r--r-- | lib/MON/Filter.pm | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/lib/MON/Filter.pm b/lib/MON/Filter.pm new file mode 100644 index 0000000..d16d1c5 --- /dev/null +++ b/lib/MON/Filter.pm @@ -0,0 +1,166 @@ +package MON::Filter; + +use strict; +use warnings; +use v5.10; +use autodie; + +use Data::Dumper; + +use MON::Display; +use MON::Config; +use MON::Utils; + +our @ISA = ('MON::Display'); + +sub new { + my ( $class, %opts ) = @_; + + my $self = bless \%opts, $class; + + $self->init(); + + return $self; +} + +sub init { + my ($self) = @_; + + $self->{query_string} = ''; + $self->{filters} = {}; + $self->{num_filters} = 0; + $self->{is_computed} = 0; + $self->{or} = []; + + return undef; +} + +# Create filters with params +sub compute { + my ( $self, $params ) = @_; + + $self->debug( 'Computing filter using', $params ); + return undef if $self->{is_computed}; + + my %likes; + + if ( defined $params and ref $params eq 'ARRAY' ) { + while (@$params) { + my $op_token = pop @$params; + given ($op_token) { + when (/^OP_LIKE$/) { + my $arg2 = pop @$params; + my $arg1 = pop @$params; + + if ( exists $likes{$arg1} ) { + $self->error( +"Can not run multiple 'like's on '$arg1', since it is used for the API query_string" + ); + } + else { + $likes{$arg1} = "$arg1=$arg2"; + } + + } + when (/^OP_/) { + $self->{filters}{$_} = [] unless exists $self->{filters}{$_}; + my $arg2 = pop @$params; + my $arg1 = pop @$params; + push @{ $self->{filters}{$_} }, [ $arg1, $arg2 ]; + $self->{num_filters}++; + } + default { + $self->error("Inernal error: Operator expected instead of $_"); + } + } + } + } + + $self->{query_string} = '?' . join( '&', values %likes ); + $self->{is_computed} = 1; + + $self->debug( 'Computed filter:', $self->{filters} ); + $self->verbose( "Computed query string is: " . $self->{query_string} ); + + return undef; +} + +sub filter { + my ( $self, $objects ) = @_; + + my $config = $self->{config}; + my $json = $self->{json}; + + return $objects unless $self->{num_filters}; + + my $num = sub { + my $str = shift; + $str =~ s/\D//g; + $str = 0 if $str eq ''; + return int $str; + }; + + while ( my ( $op, $vals ) = each %{ $self->{filters} } ) { + for my $val (@$vals) { + my ( $key, $val ) = @$val; + + @$objects = grep { + my $object = $_; + + if ( exists $object->{$key} ) { + if ( $op eq 'OP_MATCHES' and $object->{$key} =~ /$val/ ) { + 1; + + } + elsif ( $op eq 'OP_NMATCHES' and $object->{$key} !~ /$val/ ) { + 1; + + } + elsif ( $op eq 'OP_EQ' and $object->{$key} eq $val ) { + 1; + + } + elsif ( $op eq 'OP_NE' and $object->{$key} ne $val ) { + 1; + + } + elsif ( $op eq 'OP_LT' + and $num->( $object->{$key} ) < $num->($val) ) + { + 1; + + } + elsif ( $op eq 'OP_LE' + and $num->( $object->{$key} ) <= $num->($val) ) + { + 1; + + } + elsif ( $op eq 'OP_GT' + and $num->( $object->{$key} ) > $num->($val) ) + { + 1; + + } + elsif ( $op eq 'OP_GE' + and $num->( $object->{$key} ) >= $num->($val) ) + { + 1; + + } + else { + 0; + } + } + else { + 0; + } + } @$objects; + } + } + + return $objects; +} + +1; + |
