View | Details | Raw Unified | Return to bug 33268
Collapse All | Expand All

(-)a/Koha/MarcOverlayRules.pm (-33 / +102 lines)
Lines 16-28 package Koha::MarcOverlayRules; Link Here
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
use List::Util qw(first);
19
use List::Util qw(first any);
20
use Koha::MarcOverlayRule;
20
use Koha::MarcOverlayRule;
21
use Carp;
21
use Carp;
22
22
23
use Koha::Exceptions::MarcOverlayRule;
23
use Koha::Exceptions::MarcOverlayRule;
24
use Try::Tiny;
24
use Try::Tiny;
25
use Scalar::Util qw(looks_like_number);
25
use Scalar::Util qw(looks_like_number);
26
use Clone qw(clone);
26
27
27
use parent qw(Koha::Objects);
28
use parent qw(Koha::Objects);
28
29
Lines 46-51 sub operations { Link Here
46
    return ('add', 'append', 'remove', 'delete');
47
    return ('add', 'append', 'remove', 'delete');
47
}
48
}
48
49
50
=head3 modules
51
52
Returns a list of all modules in order of priority.
53
54
=cut
55
56
sub modules {
57
    return ( 'userid', 'categorycode', 'source' );
58
}
59
49
=head3 context_rules
60
=head3 context_rules
50
61
51
    my $rules = Koha::MarcOverlayRules->context_rules($context);
62
    my $rules = Koha::MarcOverlayRules->context_rules($context);
Lines 55-115 Gets all MARC overlay rules for the supplied C<$context> (hashref with { module Link Here
55
=cut
66
=cut
56
67
57
sub context_rules {
68
sub context_rules {
58
    my ($self, $context) = @_;
69
    my ( $self, $context ) = @_;
59
70
60
    return unless %{$context};
71
    return unless %{$context};
61
72
62
    my $rules = $cache->get_from_cache('marc_overlay_rules', { unsafe => 1 });
73
    my $rules = $cache->get_from_cache( 'marc_overlay_rules', { unsafe => 1 } );
63
74
64
    if (!$rules) {
75
    if ( !$rules ) {
65
        $rules = {};
76
        $rules = {};
66
        my @rules_rows = $self->_resultset()->search(
77
        my @rules_rows = $self->_resultset()->search(
67
            undef,
78
            undef,
68
            {
79
            { order_by => { -desc => [qw/id/] } }
69
                order_by => { -desc => [qw/id/] }
70
            }
71
        );
80
        );
72
        foreach my $rule_row (@rules_rows) {
81
        foreach my $rule_row (@rules_rows) {
73
            my %rule = $rule_row->get_columns();
82
            my %rule       = $rule_row->get_columns();
74
            my $operations = {};
83
            my $operations = {};
75
84
76
            foreach my $operation ($self->operations) {
85
            foreach my $operation ( $self->operations ) {
77
                $operations->{$operation} = { allow => $rule{$operation}, rule => $rule{id} };
86
                $operations->{$operation} = { allow => $rule{$operation}, rule => $rule{id} };
78
            }
87
            }
79
88
80
            # TODO: Remove unless check and validate on saving rules?
89
            # TODO: Remove unless check and validate on saving rules?
81
            if ($rule{tag} eq '*') {
90
            if ( $rule{tag} eq '*' ) {
82
                unless (exists $rules->{$rule{module}}->{$rule{filter}}->{'*'}) {
91
                unless ( exists $rules->{ $rule{module} }->{ $rule{filter} }->{'*'} ) {
83
                    $rules->{$rule{module}}->{$rule{filter}}->{'*'} = $operations;
92
                    $rules->{ $rule{module} }->{ $rule{filter} }->{'*'} = $operations;
84
                }
93
                }
85
            }
94
            } elsif ( $rule{tag} =~ /^(\d{3})$/ ) {
86
            elsif ($rule{tag} =~ /^(\d{3})$/) {
95
                unless ( exists $rules->{ $rule{module} }->{ $rule{filter} }->{tags}->{ $rule{tag} } ) {
87
                unless (exists $rules->{$rule{module}}->{$rule{filter}}->{tags}->{$rule{tag}}) {
96
                    $rules->{ $rule{module} }->{ $rule{filter} }->{tags}->{ $rule{tag} } = $operations;
88
                    $rules->{$rule{module}}->{$rule{filter}}->{tags}->{$rule{tag}} = $operations;
89
                }
97
                }
90
            }
98
            } else {
91
            else {
99
                my $regexps = ( $rules->{ $rule{module} }->{ $rule{filter} }->{regexps} //= [] );
92
                my $regexps = ($rules->{$rule{module}}->{$rule{filter}}->{regexps} //= []);
100
                push @{$regexps}, [ $rule{tag}, $operations ];
93
                push @{$regexps}, [$rule{tag}, $operations];
94
            }
101
            }
95
        }
102
        }
96
        $cache->set_in_cache('marc_overlay_rules', $rules);
103
        $cache->set_in_cache( 'marc_overlay_rules', $rules );
97
    }
104
    }
98
105
99
    my $context_rules = undef;
106
    my $context_rules;
100
    foreach my $module_name (keys %{$context}) {
107
    my @context_modules = grep { exists $context->{$_} } $self->modules();
101
        if (
108
102
            exists $rules->{$module_name} &&
109
    foreach my $module_name (@context_modules) {
103
            exists $rules->{$module_name}->{$context->{$module_name}}
110
        if (   exists $rules->{$module_name}
104
        ) {
111
            && exists $rules->{$module_name}->{ $context->{$module_name} } )
105
            $context_rules = $rules->{$module_name}->{$context->{$module_name}};
112
        {
113
            $context_rules = $rules->{$module_name}->{ $context->{$module_name} };
114
115
            unless ( exists $rules->{$module_name}->{'*'} ) {
116
117
                # No wildcard filter rules defined
118
                last;
119
            }
120
121
            # Merge in all wildcard filter rules which has not been overridden
122
            # by the matching context
123
            if ( $context_rules->{'*'} ) {
124
125
                # Wildcard tag for matching context will override all rules,
126
                # nothing left to do
127
                last;
128
            }
129
130
            # Clone since we will potentially be modified cached value
131
            # fetched with unsafe => 1
132
            $context_rules = clone($context_rules);
133
134
            if ( exists $rules->{$module_name}->{'*'}->{'*'} ) {
135
136
                # Merge in wildcard filter wildcard tag rule if exists
137
                $context_rules->{'*'} = $rules->{$module_name}->{'*'}->{'*'};
138
            }
139
140
            if ( exists $rules->{$module_name}->{'*'}->{tags} ) {
141
                if ( exists $context_rules->{regexps} ) {
142
143
                    # If the current context has regexp rules, we have to make sure
144
                    # to not only to skip tags already present but also those matching
145
                    # any of those rules
146
147
                    my @regexps = map { qr/^$_->[0]$/ } @{ $context_rules->{regexps} };
148
149
                    foreach my $tag ( keys %{ $rules->{$module_name}->{'*'}->{tags} } ) {
150
                        unless ( ( any { $tag =~ $_ } @regexps ) || exists $context_rules->{tags}->{$tag} ) {
151
                            $context_rules->{tags}->{$tag} = $rules->{$module_name}->{'*'}->{tags}->{$tag};
152
                        }
153
                    }
154
                } else {
155
156
                    # Merge in wildcard filter tag rules not already present
157
                    # in the matching context
158
                    foreach my $tag ( keys %{ $rules->{$module_name}->{'*'}->{tags} } ) {
159
                        unless ( exists $context_rules->{tags}->{$tag} ) {
160
                            $context_rules->{tags}->{$tag} = $rules->{$module_name}->{'*'}->{tags}->{$tag};
161
                        }
162
                    }
163
                }
164
            }
165
166
            if ( exists $rules->{$module_name}->{'*'}->{regexps} ) {
167
168
                # Merge in wildcard filter regexp rules last, making sure rules from the
169
                # matching context have precedence
170
                $context_rules->{regexps} //= [];
171
                push @{ $context_rules->{regexps} }, @{ $rules->{$module_name}->{'*'}->{regexps} };
172
            }
173
106
            last;
174
            last;
107
        }
175
        }
108
    }
176
    }
109
    if (!$context_rules) {
177
110
        # No perms matching specific context conditions found, try wildcard value for each active context
178
    if ( !$context_rules ) {
111
        foreach my $module_name (keys %{$context}) {
179
112
            if (exists $rules->{$module_name}->{'*'}) {
180
        # No rules matching specific context conditions found, try wildcard value for each active context
181
        foreach my $module_name (@context_modules) {
182
            if ( exists $rules->{$module_name}->{'*'} ) {
113
                $context_rules = $rules->{$module_name}->{'*'};
183
                $context_rules = $rules->{$module_name}->{'*'};
114
                last;
184
                last;
115
            }
185
            }
116
- 

Return to bug 33268