Revision 8e405005
Von Moritz Bunkus vor fast 10 Jahren hinzugefügt
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
GetModels-Filtered: Unterstützung für benutzerdefinierte Variablen