Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 8e405005

Von Moritz Bunkus vor fast 10 Jahren hinzugefügt

  • ID 8e405005059d7957a627be4bd145b68fd945ac1d
  • Vorgänger a34e8502
  • Nachfolger c9589610

GetModels-Filtered: Unterstützung für benutzerdefinierte Variablen

Unterschiede anzeigen:

SL/Controller/Helper/ParseFilter.pm
149 149
  die 'unrecognized filters' if $key =~ /:/;
150 150

  
151 151
  my @tokens     = split /\./, $key;
152
  my $last_token = pop @tokens;
153 152
  my $curr_class = $class->object_class;
154 153

  
155
  for my $token (@tokens) {
154
  # find first token which is not a relationship
155
  my $i = 0;
156
   while ($i < $#tokens) {
156 157
    eval {
157
      $curr_class = $curr_class->meta->relationship($token)->class;
158
      1;
158
      $curr_class = $curr_class->meta->relationship($tokens[$_])->class;
159
      ++$i;
159 160
    } or do {
160
      require Carp;
161
      Carp::croak("Could not resolve the relationship '$token' in '$key' while building the filter request");
161
      last;
162 162
    }
163 163
  }
164 164

  
165 165
  my $manager    = $curr_class->meta->convention_manager->auto_manager_class_name;
166
  my $obj_path   = join '.', @tokens;
167
  my $obj_prefix = join '.', @tokens, '';
166
  my $obj_path   = join '.', @tokens[0..$i-1];
167
  my $obj_prefix = join '.', @tokens[0..$i-1], '';
168
  my $key_token  = $tokens[$i];
169
  my @additional_tokens = @tokens[$i+1..$#tokens];
168 170

  
169 171
  if ($manager->can('filter')) {
170
    ($key, $value, my $obj) = $manager->filter($last_token, $value, $obj_prefix, $obj_path);
172
    ($key, $value, my $obj) = $manager->filter($key_token, $value, $obj_prefix, $obj_path, @additional_tokens);
171 173
    _add_uniq($with_objects, $obj) if $obj;
172 174
  } else {
173 175
    _add_uniq($with_objects, $obj_path) if $obj_path;
SL/DB/CustomVariableConfig.pm
103 103
  return (any { $_ eq $self->default_value } @{ $self->processed_options }) ? $self->default_value : $self->processed_options->[0];
104 104
}
105 105

  
106
sub value_col {
107
  my ($self) = @_;
108

  
109
  my $type = $self->type;
110

  
111
  return {
112
    bool      => 'bool_value',
113
    timestamp => 'timestamp_value',
114
    number    => 'number_value',
115
    integer   => 'number_value',
116
    customer  => 'number_value',
117
    vendor    => 'number_value',
118
    part      => 'number_value',
119
    text      => 'text_value',
120
    textfield => 'text_value',
121
    date      => 'text_value',
122
    select    => 'text_value'
123
  }->{$type};
124
}
125

  
106 126
1;
SL/DB/Helper/CustomVariables.pm
28 28
  make_cvar_by_name($caller_package, %params);
29 29
  make_cvar_as_hashref($caller_package, %params);
30 30
  make_cvar_value_parser($caller_package, %params);
31
  make_cvar_custom_filter($caller_package, %params);
31 32
}
32 33

  
33 34
sub save_meta_info {
......
223 224
  return $column_name;
224 225
}
225 226

  
227
sub make_cvar_custom_filter {
228
  my ($caller_package, %params) = @_;
229

  
230
  my $manager    = $caller_package->meta->convention_manager->auto_manager_class_name;
231

  
232
  return unless $manager->can('filter');
233

  
234
  $manager->add_filter_specs(
235
    cvar => sub {
236
      my ($key, $value, $prefix, $config_id) = @_;
237
      my $config = SL::DB::Manager::CustomVariableConfig->find_by(id => $config_id);
238

  
239
      if (!$config) {
240
        die "invalid config_id in $caller_package\::cvar custom filter: $config_id";
241
      }
242

  
243
      if ($config->module != $params{module}) {
244
        die "invalid config_id in $caller_package\::cvar custom filter: expected module $params{module} - got @{[ $config->module ]}";
245
      }
246

  
247
      my (%query, %bind_vals);
248
      ($query{customized}, $bind_vals{customized}) = Rose::DB::Object::QueryBuilder::build_select(
249
        dbh                  => $config->dbh,
250
        select               => 'trans_id',
251
        tables               => [ 'custom_variables' ],
252
        columns              => { custom_variables => [ qw(trans_id config_id text_value number_value bool_value timestamp_value sub_module) ] },
253
        query                => [
254
          config_id          => $config_id,
255
          sub_module         => $params{sub_module},
256
          $config->value_col => $value,
257
        ],
258
        query_is_sql         => 1,
259
      );
260

  
261
      my $conversion  = $config->type =~ m{^(?:date|timestamp)$}       ? $config->type
262
                      : $config->type =~ m{^(?:customer|vendor|part)$} ? 'integer'
263
                      : $config->type eq 'bool'                        ? 'boolean'
264
                      : $config->type eq 'number'                      ? 'numeric'
265
                      :                                                  '';
266

  
267
      ($query{config}, $bind_vals{config}) = Rose::DB::Object::QueryBuilder::build_select(
268
        dbh             => $config->dbh,
269
        select          => 'id',
270
        tables          => [ 'custom_variable_configs' ],
271
        columns         => { custom_variable_configs => [ qw(id default_value) ] },
272
        query           => [
273
          id            => $config->id,
274
          default_value => $value,
275
        ],
276
        query_is_sql    => 1,
277
      );
278

  
279
      $query{config} =~ s{\bdefault_value\b}{default_value::${conversion}} if $conversion;
280

  
281
      ($query{not_customized}, $bind_vals{not_customized}) = Rose::DB::Object::QueryBuilder::build_select(
282
        dbh          => $config->dbh,
283
        select       => 'trans_id',
284
        tables       => [ 'custom_variables' ],
285
        columns      => { custom_variables => [ qw(trans_id config_id sub_module) ] },
286
        query        => [
287
          config_id  => $config_id,
288
          sub_module => $params{sub_module},
289
        ],
290
        query_is_sql => 1,
291
      );
292

  
293
      foreach my $key (keys %query) {
294
        # remove rose aliases. query builder sadly is not reentrant, and will reuse the same aliases. :(
295
        $query{$key} =~ s{\bt\d+(?:\.)?\b}{}g;
296

  
297
        # manually inline the values. again, rose doen't know how to handly bind params in subqueries :(
298
        $query{$key} =~ s{\?}{ $config->dbh->quote($_) }xe for @{ $bind_vals{$key} };
299

  
300
        $query{$key} =~ s{\n}{ }g;
301
      }
302

  
303
      my $qry_config = "EXISTS (" . $query{config} . ")";
304

  
305
      my @result = (
306
        'or' => [
307
          $prefix . 'id'   => [ \$query{customized} ],
308
          and              => [
309
            "!${prefix}id" => [ \$query{not_customized}  ],
310
            \$qry_config,
311
          ]
312
        ],
313
      );
314

  
315
      return @result;
316
    }
317
  );
318
}
319

  
226 320
1;
227 321

  
228 322
__END__
......
371 465

  
372 466
=back
373 467

  
468
=head1 INSTALLED MANAGER METHODS
469

  
470
=over 4
471

  
472
=item Custom filter for GetModels
473

  
474
If the Manager for the calling C<SL::DB::Object> has included the helper L<SL::DB::Helper::Filtered>, a custom filter for cvars will be added to the specs, with the following syntax:
475

  
476
  filter.cvar.$config_id
477

  
478
=back
479

  
374 480
=head1 AUTHOR
375 481

  
376 482
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>,
SL/DB/Helper/Filtered.pm
10 10
my %filter_spec;
11 11

  
12 12
sub filter {
13
  my ($class, $key, $value, $prefix, $path) = @_;
13
  my ($class, $key, $value, $prefix, $path, @additional_tokens) = @_;
14 14

  
15 15
  my $filters = _get_filters($class);
16 16

  
17 17
  return ($prefix . $key, $value, $path) unless $filters->{$key};
18 18

  
19
  return $filters->{$key}->($key, $value, $prefix);
19
  return $filters->{$key}->($key, $value, $prefix, @additional_tokens);
20 20
}
21 21

  
22 22
sub _get_filters {

Auch abrufbar als: Unified diff