diff options
Diffstat (limited to 'LedgerSMB/Menufile.pm')
-rw-r--r-- | LedgerSMB/Menufile.pm | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/LedgerSMB/Menufile.pm b/LedgerSMB/Menufile.pm new file mode 100644 index 00000000..85674efd --- /dev/null +++ b/LedgerSMB/Menufile.pm @@ -0,0 +1,271 @@ + +=head1 NAME + +LedgerSMB::Menufile Routines to handle LedgerSMB menu files and format entries +for display. + +=head1 SYNOPSIS + +Routines to handle LedgerSMB menu files and conversion of menu entries into a +form usable by a web browser. LedgerSMB menu files are a specific form of ini +file. + +Files use both ';' and '#' to denote line comments. Any text after a line that +starts with '.' (i.e. ".foo") is ignored. Menu items are denoted as [section], +with the sections containing key=value pairs. The keys 'module', 'action', +'target', 'href', and 'submenu' are specially treated, while other keys are +output as arguments to the destination link. Blank lines are ignored. + +=head2 Special key treatment + +=over + +=item action + +This key is deleted on menuitem calls if there is no href value. + +=item module + +This is the Perl script that the menu item will call if the href attribute is +not set. This key is always deleted on a menuitem call. + +=item target + +The value given for target will be passed as the target attribute for the tag. +This key is always deleted on a menuitem call. + +=item href + +When set, this key's value becomes the base URL for the menu item. This key is +always deleted on a menuitem call. + +=item submenu + +This key is not displayed in output, but is deleted from the Menufile object +when menuitem is called on the item. + +=back + +=head2 Value Interpolation + +If a value for a regular key includes an equals sign (=), values from the user's +configuration are substituted into the place of the string preceding and the +first encountered equals sign in the value. So a menu entry of 'apples=login=' +would have the substition of 'apples=$myconfig->{login}' on generation of the +menu link. + +=head1 METHODS + +=over + +=item new ([$filename]) + +Create a new Menufile object. If a filename is specified, load the file with +add_file. + +=item add_file ($filename) + +Load the contents of the specified file into the Menufile object. If the file +cannot be read, Form->error will be called with the failure message. Attempts +to load already loaded items will result in the newer item merging with and +overwriting stored data from the previous load. + +Menu item titles are stored as keys in the Menufile object, and a special key, +ORDER maintains a list of the order in which menu items were first seen. + +=item menuitem ($myconfig, $form, $item) + +Formats the menu item for the given key $item as an HTML <a href=""> open tag. +Returns the tag and deletes the module, target, href, action, and submenu +attributes for the item from the Menufile object. + +If the menubar attribute of the passed in Form attribute is set, no style will +be set for the tag, otherwise the style is set to "display:block". + +=item access_control ($myconfig, [$menulevel]) + +Returns the list of menu items that can be displayed with $myconfig->{acs} at +the selected menu level. $menulevel is the string corresponding to a displayed +menu, such as 'AR' or 'AR--Reports'. A blank level corresponds to the top +level. Merely excluding a top-level element does not exclude corresponding +lower level elements, i.e. excluding 'AR' will not block 'AR--Reports'. + +$myconfig->{acs} is a semicolon seperated list of menu items to exclude. + +This is only a cosmetic form of access_control. Users can still access +"disallowed" sections of the application by manually entering in the URL. + +=back + +=head1 Copyright (C) 2006, The LedgerSMB core team. + + #==================================================================== + # LedgerSMB + # Small Medium Business Accounting software + # http://www.ledgersmb.org/ + # + # Copyright (C) 2006 + # This work contains copyrighted information from a number of sources + # all used with permission. + # + # This file contains source code included with or based on SQL-Ledger + # which is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 + # and licensed under the GNU General Public License version 2 or, at + # your option, any later version. For a full list including contact + # information of contributors, maintainers, and copyright holders, + # see the CONTRIBUTORS file. + # + # Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork): + # Copyright (C) 2002 + # + # Author: DWS Systems Inc. + # Web: http://www.sql-ledger.org + # + # Contributors: + # Tony Fraser <tony@sybaspace.com> + # + #===================================================================== +=cut + +package LedgerSMB::Menufile; + +use LedgerSMB::Form; + +sub new { + my ( $type, $file ) = @_; + + warn "$type has no copy constructor! creating a new object." + if ref($type); + $type = ref($type) || $type; + my $self = bless {}, $type; + $self->add_file($file) if defined $file; + + return $self; +} + +sub add_file { + my ( $self, $file ) = @_; + + my $id = ""; + my %menuorder = (); + + for ( @{ $self->{ORDER} } ) { $menuorder{$_} = 1 } + + open FH, '<', "$file" or Form->error("$file : $!"); + + while (<FH>) { + next if /^(#|;|\s)/; + last if /^\./; + + chop; + + # strip comments + s/\s*(#|;).*//g; + + # remove any trailing whitespace + s/^\s*(.*?)\s*$/$1/; + + if (/^\[/) { + s/(\[|\])//g; + $id = $_; + push @{ $self->{ORDER} }, $_ if !$menuorder{$_}; + $menuorder{$_} = 1; + next; + } + + # add key=value to $id + my ( $key, $value ) = split /=/, $_, 2; + + $self->{$id}{$key} = $value; + + } + close FH; + +} + +sub menuitem { + my ( $self, $myconfig, $form, $item ) = @_; + + my $module = + ( $self->{$item}{module} ) ? $self->{$item}{module} : $form->{script}; + my $action = + ( $self->{$item}{action} ) ? $self->{$item}{action} : "section_menu"; + my $target = ( $self->{$item}{target} ) ? $self->{$item}{target} : ""; + + my $level = $form->escape($item); + my $style; + if ( $form->{menubar} ) { + $style = ""; + } + else { + $style = "display:block;"; + } + my $str = + qq|<a style="$style"| + . qq|href="$module?path=$form->{path}&action=$action&| + . qq|level=$level&login=$form->{login}&| + . qq|timeout=$form->{timeout}&sessionid=$form->{sessionid}| + . qq|&js=$form->{js}|; + + my @vars = qw(module action target href); + + if ( $self->{$item}{href} ) { + $str = qq|<a href="$self->{$item}{href}|; + @vars = qw(module target href); + } + + for (@vars) { delete $self->{$item}{$_} } + + delete $self->{$item}{submenu}; + + # add other params + foreach my $key ( keys %{ $self->{$item} } ) { + $str .= "&" . $form->escape($key) . "="; + ( $value, $conf ) = split /=/, $self->{$item}{$key}, 2; + $value = "$myconfig->{$value}$conf" + if $self->{$item}{$key} =~ /=/; + + $str .= $form->escape($value); + } + + $str .= qq|#id$form->{tag}| if $target eq 'acc_menu'; + + if ($target) { + $str .= qq|" target="$target"|; + } + else { + $str .= '"'; + } + + $str .= qq|>|; + +} + +sub access_control { + my ( $self, $myconfig, $menulevel ) = @_; + + my @menu = (); + + if ( $menulevel eq "" ) { + @menu = grep { !/--/ } @{ $self->{ORDER} }; + } + else { + @menu = grep { /^${menulevel}--/; } @{ $self->{ORDER} }; + } + + my @a = split /;/, $myconfig->{acs}; + my %excl = (); + + # remove --AR, --AP from array + grep { ( $a, $b ) = split /--/; s/--$a$//; } @a; + + for (@a) { $excl{$_} = 1 } + + @a = (); + for (@menu) { push @a, $_ unless $excl{$_} } + + @a; + +} + +1; |