X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FMenu.pm;h=0c6df2247a976d6efb2939b9fd710bfa7d26e61e;hb=fa31a7e0c6a8d00e35511f5052145ab2156a8160;hp=08727ce3664c58941bc58fddef04e53860bf2817;hpb=6f4fcf7bf0276763d3bdc3ac38459a962ff4635a;p=kivitendo-erp.git diff --git a/SL/Menu.pm b/SL/Menu.pm index 08727ce36..0c6df2247 100644 --- a/SL/Menu.pm +++ b/SL/Menu.pm @@ -3,14 +3,9 @@ package SL::Menu; use strict; use SL::Auth; -use YAML (); use File::Spec; use SL::MoreCommon qw(uri_encode); - -our $yaml_xs; -BEGIN { - $yaml_xs = eval { require YAML::XS }; -} +use SL::YAML; our %menu_cache; @@ -29,11 +24,7 @@ sub new { for my $file (@files) { my $data; eval { - if ($yaml_xs) { - $data = YAML::XS::LoadFile(File::Spec->catfile($path, $file)); - } else { - $data = YAML::LoadFile(File::Spec->catfile($path, $file)); - } + $data = SL::YAML::LoadFile(File::Spec->catfile($path, $file)); 1; } or do { die "Error while parsing $file: $@"; @@ -73,6 +64,8 @@ sub _merge { for my $node (@$data) { my $id = $node->{id}; + die "menu: node with name '$node->{name}' does not have an id" if !$id; + my $merge_to = $by_id->{$id}; if (!$merge_to) { @@ -117,6 +110,19 @@ sub build_tree { push @{ $by_parent{ $node->{parent} // '' } //= [] }, $node; } + # autovivify order in by_parent, so that numerical sorting for entries without order + # preserves their order and position with respect to entries with order. + for (values %by_parent) { + my $last_order = 0; + for my $node (@$_) { + if (defined $node->{order} && $node->{order} * 1) { + $last_order = $node->{order}; + } else { + $node->{order} = ++$last_order; + } + } + } + my $tree = { }; $self->{by_id}{''} = $tree; @@ -165,7 +171,7 @@ sub parse_access_string { my $access = $node->{access}; - while ($access =~ m/^([a-z_\/]+|\||\&|\(|\)|\s+)/) { + while ($access =~ m/^([a-z_\/]+|\!|\||\&|\(|\)|\s+)/) { my $token = $1; substr($access, 0, length($1)) = ""; @@ -184,7 +190,7 @@ sub parse_access_string { } $cur_ary = $stack[-1]; - } elsif (($token eq "|") || ($token eq "&")) { + } elsif (($token eq "|") || ($token eq "&") || ($token eq "!")) { push @{$cur_ary}, $token; } else { @@ -212,14 +218,16 @@ sub href_for_node { return undef if !$node->{href} && !$node->{module} && !$node->{params}; - my $href = $node->{href} || $node->{module} || 'controller.pl'; - my @tokens; + return $node->{href_for_node} ||= do { + my $href = $node->{href} || $node->{module} || 'controller.pl'; + my @tokens; - while (my ($key, $value) = each %{ $node->{params} }) { - push @tokens, uri_encode($key, 1) . "=" . uri_encode($value, 1); - } + while (my ($key, $value) = each %{ $node->{params} }) { + push @tokens, uri_encode($key, 1) . "=" . uri_encode($value, 1); + } - return join '?', $href, grep $_, join '&', @tokens; + join '?', $href, grep $_, join '&', @tokens; + } } sub name_for_node { @@ -256,4 +264,3 @@ sub set_access { } 1; -