X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FMenu.pm;h=ac8f7280b4bf51e464c018c5223f9a8824c1cc3f;hb=d679bb5b866e0336fb3df96a28cb58de349c9cb0;hp=1ecb52fab7fd47d2eb87071c08e3143985e2b2a2;hpb=fb974d9c26db844c754b75506a28f3ca9f5522ca;p=kivitendo-erp.git diff --git a/SL/Menu.pm b/SL/Menu.pm index 1ecb52fab..ac8f7280b 100644 --- a/SL/Menu.pm +++ b/SL/Menu.pm @@ -12,37 +12,46 @@ BEGIN { $yaml_xs = eval { require YAML::XS }; } +our %menu_cache; + sub new { my ($package, $domain) = @_; - my $path = File::Spec->catdir('menus', $domain); + if (!$menu_cache{$domain}) { + my $path = File::Spec->catdir('menus', $domain); - opendir my $dir, $path or die "can't open $path: $!"; - my @files = sort grep -f "$path/$_", readdir $dir; - close $dir; + opendir my $dir, $path or die "can't open $path: $!"; + my @files = sort grep -f "$path/$_", grep /\.yaml$/, readdir $dir; + close $dir; - my $nodes = []; - my $nodes_by_id = {}; - for my $file (@files) { - my $data; - if ($yaml_xs) { - $data = YAML::XS::LoadFile(File::Spec->catfile($path, $file)); - } else { - $data = YAML::LoadFile(File::Spec->catfile($path, $file)); + my $nodes = []; + my $nodes_by_id = {}; + for my $file (@files) { + my $data; + if ($yaml_xs) { + $data = YAML::XS::LoadFile(File::Spec->catfile($path, $file)); + } else { + $data = YAML::LoadFile(File::Spec->catfile($path, $file)); + } + _merge($nodes, $nodes_by_id, $data); } - _merge($nodes, $nodes_by_id, $data); - } - my $self = bless { - nodes => $nodes, - by_id => $nodes_by_id, - }, $package; + my $self = bless { + nodes => $nodes, + by_id => $nodes_by_id, + }, $package; + + $self->build_tree; + + $menu_cache{$domain} = $self; + } else { + $menu_cache{$domain}->clear_access; + } - $self->build_tree; - $self->set_access; + $menu_cache{$domain}->set_access; - return $self; + return $menu_cache{$domain}; } sub _merge { @@ -88,7 +97,7 @@ sub build_tree { # first, some sanity check. are all parents valid ids or empty? for my $node ($self->nodes) { next if !exists $node->{parent} || !$node->{parent} || $self->{by_id}->{$node->{id}}; - die "menu: node $node->{id} has non-existant parent $node->{parent}"; + die "menu: node $node->{id} has non-existent parent $node->{parent}"; } my %by_parent; @@ -211,13 +220,30 @@ sub parse_instance_conf_string { return $::instance_conf->data->{$setting}; } +sub parse_compare_string { + my ($self, $switch) = @_; + my ($setting, $mode) = split m/=/, $switch, 2; + return $::instance_conf->data->{$setting} eq $mode; +} + +sub clear_access { + my ($self) = @_; + for my $node ($self->tree_walk("all")) { + delete $node->{visible}; + delete $node->{visible_children}; + } +} + sub set_access { my ($self) = @_; - # 1. evaluate access for all - # 2. if a menu has no visible children, its not visible either + # 1. evaluate appearence + # 2. evaluate access for all + # 3. if a menu has no visible children, its not visible either for my $node (reverse $self->tree_walk("all")) { - $node->{visible} = $node->{access} ? $self->parse_access_string($node) + $node->{visible} = $node->{inclusion} ? $self->parse_compare_string($node->{inclusion}) : 1 + && $node->{exclusion} ? !$self->parse_compare_string($node->{exclusion}) : 1 + && $node->{access} ? $self->parse_access_string($node) : !$node->{children} ? 1 : $node->{visible_children} ? 1 : 0;