#!/usr/bin/perl package main; use strict; use Socket; use Carp; use Time::ParseDate; use Time::CTime; #-----------------------------------------------# # ESTABLISH RELATIVE DIRECTORY VARIABLES # # e.g. $0=/users/dbbrowse/WWW/DEALQUERY/top.cgi # #-----------------------------------------------# BEGIN { use Exporter(); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $baseprog $basedir $pcommon $ppages $pcgibin $pobjects $linkpages $hostname $openicon $closeicon); $VERSION=1.00; @ISA = qw(Exporter); @EXPORT = qw(); %EXPORT_TAGS = (); # your exported package globals go here, # as well as any optionally exported functions @EXPORT_OK = qw( $baseprog $pcommon $pcgibin $pjava $prevsession $hostname $virtualhost $prevsession $resultstring $includestring %clientenv $pagesurl $col_delim %Steps %StepsLabels $JSCRIPT %Menu @UserSequence @AdminSequence $queryname $groupsep @DialogEditVals $DEBUG $unalloc $attrs $openicon $closeicon ); my @path = split("\/",$0); pop(@path); if (@path) { $basedir = join("\/",@path); # e.g. /users/dbbrowse/WWW/DEALQUERY } else { $basedir = "."; } $pcommon = "$basedir/../LIB"; $pcgibin = "$basedir/cgi-bin"; $pobjects = "$basedir/objects"; $hostname = `hostname`; chop($hostname); # remove \n; $ENV{DEFAULTDBALIAS} = 'tracker'; $openicon = '/images/ofolder.gif'; $closeicon = '/images/folder.gif'; } use vars @EXPORT_OK; use FileHandle; use lib "$pcommon"; use CGI; use Querier qw($col_delim); use PerlDynamic; # Set global vars, used by PerlDynamic $ppages = "$basedir/pages"; ## $linkpages = "/var/shares/ip/refacct/hp"; #-----------------------------------------------# # REQUIRED MODULES # #-----------------------------------------------# require "$pcommon/sqlUtils.pl"; require "$pcommon/gettableschema.pl"; require "$pcgibin/queries.pl"; require "$pcgibin/dbobjects.pl"; require "$pcgibin/DBObject.pm"; require "$pcgibin/project.pl"; require "$pcgibin/StepsAndJS.pl"; Querier::defaultdbalias('tracker'); $ENV{DBVENDOR} = "MySQL"; %StepsLabels = (); # created from Steps %Menu = (); # ditto my @SortedSteps; our $ExceptionError; my @PageStack = (); my ($header,$style,$htmloutput,$footer); my $ssn; #-----------------------------------------------------------# # global variables needed to make tableizeArray work # #-----------------------------------------------------------# our $_arrayRef; sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" } #--------------------------------------------------------# # CREATE Labels, menu hashes # #--------------------------------------------------------# foreach my $step (keys %Steps) { $StepsLabels{$step} = $Steps{$step}->{label}; push(@SortedSteps,$step); if (exists($Steps{$step}->{substeps})) { my $hptr = $Steps{$step}->{substeps}; foreach my $substep (keys %$hptr) { $StepsLabels{$substep} = $hptr->{$substep}->{label}; } } } @SortedSteps = sort (@SortedSteps); #-----------------------------------# # DEBUG MODE from command line, with# # cgi params in a .prm file # #-----------------------------------# if (@ARGV) { my $cgifilename= shift; open my $fh, $cgifilename or die "Can't open file $cgifilename for input:$!\n"; local $/; # enable localized slurp mode my $data = <$fh>; close $fh; $session = new CGI(''); $session->addSavedParams($data,"\n"); # \n is separator #--------------------------------------------------------------# # Tell Querier to be verbose: so we see the queries # #--------------------------------------------------------------# &Querier::verbose(1); } #----------------------------------# # Normal mode, from browser # #----------------------------------# else { $session = new CGI; #--------------------------------------------# # SAVE PARAMS TO A FILE FOR AID IN DEBUGGING # #--------------------------------------------# my $paramstr = $session->saveToString(); my $cgifilename = "$basedir/premerge.prm"; open(OUT,">$cgifilename") or die "Can't open $cgifilename for writing:$!\n"; print OUT $paramstr; close OUT; } # Set these global variables for use in pages $virtualhost = $session->virtual_host(); $pagesurl = "http://" . $virtualhost . $session->script_name(); $pagesurl =~ s/tracker\.cgi/pages/; $baseprog = $session->script_name(); eval { #---------------------------------------------------------------# # Load unallocated person object, useful in many circumstances # #---------------------------------------------------------------# &loadUnallocPerson(); #--------------------------------------------------------------# # RETRIEVE SESSION NUMBER FROM URL, OR ASSIGN ONE IF EMPTY # #--------------------------------------------------------------# $ssn = $session->param('SessionNumber'); if (!$ssn) { $ssn = int(rand(128)); $session->param('SessionNumber',$ssn); $session->param('DateLessThan','2050-01-01'); $session->param('DateGreaterThan','1970-01-01'); #-------------------------------------------------------------# # clear previous user's data with same session number, if any # #-------------------------------------------------------------# my $query = qq! delete from session where id=$ssn!; db_retrieve('im',$query); } #---------------------------------------------------------------------------# # add back variables set by forms prior to the form which called this script# #---------------------------------------------------------------------------# my $query = qq! select data from session where id=$ssn and checkpoint=0!; my $data = db_retrieve('mr',$query); $prevsession = new CGI(''); $prevsession->addSavedParams($data,"\n"); # \n is separator #----------------------------------------------------# # ACTIONS NEEDED BEFORE MERGING WITH PREVIOUS PAGE # #----------------------------------------------------# my @StateStack = (); my $fbody; my $dialog = $session->param('dialog'); my $specialAction = $session->param('specialAction'); my $action = length($dialog) ? 'Dialog' : (length($specialAction) ? $specialAction : $session->param('Submit')); #---------------------------------------------------# # NOW MERGE IN THE PARAMETERS FROM PREVIOUS PAGE # #---------------------------------------------------# # First delete any settings for checkboxes, which must # be reset completely - but only if we stay on same # # page. This allows different pages to share settings. #----------------------------------------------------# if ($prevsession->param('CurPage') eq $session->param('CurPage')) { $prevsession->delete('staff'); $prevsession->delete('project'); } $session->mergeParamsFromCGI($prevsession); #--------------------------------------------# # SAVE PARAMS TO A FILE FOR AID IN DEBUGGING # #--------------------------------------------# my $paramstr = $session->saveToString(); my $cgifilename = "$basedir/postmerge.prm"; open(OUT,">$cgifilename") or die "Can't open $cgifilename for writing:$!\n"; print OUT $paramstr; close OUT; #---------------------------------------------------# # Reset Curpage from the merged session, in case the# # original session didn't have a value for it (as is# # the case for dialogs) # #---------------------------------------------------# my $CurPage = $session->param('CurPage'); #--------------------------------------------------# # CHECK FOR EXPIRED SESSION (ACTION + NO USERID # # and we're not on the newuser page # #--------------------------------------------------# if (!length($session->param('userid')) && length($action) && $CurPage ne 'newuser') { $session->param('SessionExpired',1); $session->delete('StateStack'); } #--------------------------------------------------# # DETERMINE OVERALL STATE: [Login|New|Edit] # #--------------------------------------------------# if (!$session->param('StateStack')) # just entering ... { @StateStack = qw(New Login); @PageStack = qw(home login); $session->param(-name=>'StateStack',-values=>\@StateStack); $session->param(-name=>'PageStack',-values=>\@PageStack); $CurPage = 'No Previous Page'; $action = 'No Previous Action'; } #TEMP DEBUG $session->param('basedir',$basedir); $session->param('ppages',$ppages); @StateStack = $session->param('StateStack'); @PageStack = $session->param('PageStack'); #--------------------------------------------------# # Actions from the login page... # #--------------------------------------------------# if ($CurPage eq 'login') { $session->delete('SessionExpired'); if ($session->param('Login')) { $session->delete('Login'); my $res = &login(); if (!$res) { $session->param('BadLogin',1); } else { $session->delete('BadLogin'); pop(@PageStack); pop(@StateStack); } if ($res eq 'newuser') { @PageStack = ('newuserhome'); } } elsif ($session->param('NewUser') eq 'New User') { $session->delete('NewUser'); push(@PageStack,'newuser'); } } #-----------------------------------------------# # Actions from the newuser page... # #-----------------------------------------------# elsif ($CurPage eq 'newuser') { #--------------------------------------------# # REGISTER NEW USER IN DATABASE # #--------------------------------------------# if ($action eq 'RegisterNewUser') { if (®isterNewUser()) { $session->delete('ERROR'); $session->delete('DuplicateUserid'); @PageStack = ('newuserhome'); pop(@StateStack); # remove 'Login' } else { $session->param('DuplicateUserid',1); } } else # Cancel { $session->delete('Cancel'); @PageStack = (); } } #--------------------------------------------------# # Actions from the editprofile page... # #--------------------------------------------------# elsif ($CurPage eq 'editprofile') { if ($action eq 'UpdateUser') { my $res = &updateUser(); if ($res) { $session->delete('UpdateFailed'); @PageStack = $res eq 'newuser' ? ('newuserhome') : ('home'); } else { $session->param('UpdateFailed',1); } } elsif ($session->param('Cancel')) { $session->delete('Cancel'); @PageStack = &login() eq 'newuser' ? ('newuserhome') : ('home'); } } #--------------------------------------------# # Actions from the home page... # #--------------------------------------------# elsif ($CurPage eq 'home') { #--------------------------------------# # JUMP TO NEW PAGE # #--------------------------------------# if ($action =~ /^Jump/) { my ($act,$target) = split('\|',$action); @PageStack = ($target); } } #--------------------------------------------# # Actions from the newuserhome page... # #--------------------------------------------# elsif ($CurPage eq 'newuserhome') { #--------------------------------------# # JUMP TO NEW PAGE # #--------------------------------------# if ($action =~ /^Jump/) { my ($act,$target) = split('\|',$action); @PageStack = ($target); } } #--------------------------------------------------# # Actions from the project funding page... # #--------------------------------------------------# elsif ($CurPage eq 'projectfunding') { #-------------------------------------------# # SHOW DETAIL # #-------------------------------------------# if ($action =~ /^ShowDetail/) { my ($act,$label,$table,$row) = split('\|',$action); my $obj = sessionObject($table,$row); # table == 'project' $session->param('temp_ProjectName',$obj->{synecdoche}); $session->param('temp_ProjectID',$obj->{id}); $session->param('temp_ProjectID',$obj->pk()); @PageStack = ('projfunddetail'); } #--------------------------------------------# # STAY ON PROJECT FUNDING PAGE # #--------------------------------------------# else { @PageStack = ('projectfunding'); } } #--------------------------------------------------# # Actions from the staff project funding page... # #--------------------------------------------------# elsif ($CurPage eq 'stafffunding2') { #-----------------------------------------# # SHOW DETAIL # #-----------------------------------------# if ($action =~ /^ShowDetail/) { my ($act,$label,$table,$row) = split('\|',$action); my $obj = sessionObject($table,$row); # table == 'project' $session->param('temp_ProjectName',$obj->{synecdoche}); $session->param('temp_ProjectID',$obj->pk()); @PageStack = ('stafffunddetail'); } #--------------------------------------------# # STAY ON STAFF FUNDING PAGE # #--------------------------------------------# else { @PageStack = ('stafffunding2'); } } #-----------------------------------------------# # Actions from the invoicing page... # #-----------------------------------------------# elsif ($CurPage eq 'invoicing') { #--------------------------------------------# # SHOW INVOICE/WORK COMPARISON # #--------------------------------------------# if ($action =~ /^InvoiceWorkComparison/) { @PageStack = ('invoiceworkcompare'); } #-----------------------------------------# # SHOW DETAIL # #-----------------------------------------# elsif ($action =~ /^ShowDetail/) { my ($act,$label,$table,$row) = split('\|',$action); my $obj = sessionObject($table,$row); # table == 'accountsrecv' $session->param('temp_InvoiceNumber',$obj->{synecdoche}); $session->param('temp_InvoiceAmount',$obj->{Amount}); @DialogEditVals = (); push(@DialogEditVals,$obj->{budget}->{clientcompany}->forTableFK()); push(@DialogEditVals,$obj->{budget}->{contractedco}->forTableFK()); # $session->param('DialogEditVals',$dlgeditvals); @PageStack = ('invoicedetail'); } #--------------------------------------------# # STAY ON INVOICING PAGE # #--------------------------------------------# else { @PageStack = ('invoicing'); } } #--------------------------------------------------# # Actions from the invoicworkcompare page... # #--------------------------------------------------# elsif ($CurPage eq 'invoiceworkcompare') { if (0) {} #----------------------------------------------# # STAY ON INVOICING PAGE # #----------------------------------------------# else { @PageStack = ('invoiceworkcompare'); } } #-----------------------------------------------# # Actions from the work summary page... # #-----------------------------------------------# elsif ($CurPage eq 'worksummary') { #-------------------------------------------# # SHOW DETAIL # #-------------------------------------------# if ($action =~ /^ShowDetail/) { my ($act,$label,$table,$row) = split('\|',$action); my $obj = sessionObject($table,$row); # table == 'project' $session->param('temp_ProjectName',$obj->{synecdoche}); $session->param('temp_ProjectID',$obj->pk()); @PageStack = ('projectwork'); } #---------------------------------------------------# # STAY ON WORK SUMMARY PAGE # #---------------------------------------------------# else { @PageStack = ('worksummary'); } } #---------------------------------------------------# # Actions from the bug summary page... # #---------------------------------------------------# elsif ($CurPage eq 'bugsummary') { #---------------------------------------------------# # SHOW DETAIL # #---------------------------------------------------# if ($action =~ /^ShowDetail/) { my ($act,$label,$table,$row) = split('\|',$action); my $obj = sessionObject($table,$row); # table == 'project' $session->param('temp_ProjectName',$obj->{synecdoche}); $session->param('temp_ProjectID',$obj->pk()); @PageStack = ('projectbugs'); } #---------------------------------------------------# # STAY ON BUG SUMMARY PAGE # #---------------------------------------------------# else { @PageStack = ('bugsummary'); } } #---------------------------------------------------# # Actions from the reports page... # #---------------------------------------------------# elsif ($CurPage =~ /^report/) { require "$pcgibin/reports.pl"; #---------------------------------------------------# # SHOW REPORT # #---------------------------------------------------# if ($action =~ /^ShowReport/) { my ($act,$report,$date1,$date2,@otherparams) = split('\|',$action); $session->param('temp_Date1',$date1); $session->param('temp_Date2',$date2); $session->param(-name=>'temp_OtherParams',-values=>\@otherparams); @PageStack = ($report); } #-----------------------------------------------# # STAY ON WORK SUMMARY PAGE # #-----------------------------------------------# else { @PageStack = ($CurPage); } } #--------------------------------------------# # DIALOG SUPPORT # #--------------------------------------------# if ($action eq 'Dialog') # about to display dialog... { #--------------------------------------------------------------# # splice trick is needed to reduce PageStack to 1. Reason: # # if user presses Cancel from a dialog, we won't come back to # # the server to pop the PageStack # #--------------------------------------------------------------# splice(@PageStack,1,10,$dialog); # 10 is any large number $paramstr = $session->param('Params'); if (length($paramstr)) { my ($label,$table,$rowid) = split('\|',$paramstr); my $buttonprefix = 'Add'; @DialogEditVals = (); my $dlgeditvals = ''; my $obj; #-------------------# # existing object # #-------------------# if ($rowid ne '-1') # -1 indicates new object, not existing row { $buttonprefix = 'Update'; $obj = sessionObject($table,$rowid); $dlgeditvals = $obj->forTablePK(); } #-------------------------------------------------------# # new object # # initialize with id = new, plus any other preset params# # (e.g., projectid, personid, and companyid preset for # # new work object) # #-------------------------------------------------------# else { my $paramVal = $session->param('NewObjParams'); my $instantiateVals = join($col_delim,'new',$paramVal); $obj = $table->new($instantiateVals); $dlgeditvals = $obj->forTablePK(); } if (ref($dlgeditvals) eq 'HASH') { my @cols = $obj->columns(); foreach my $col (@cols) { push(@DialogEditVals,$dlgeditvals->{$col}); } if ($obj->can('arrays')) { @cols = $obj->arrays(); foreach my $col (@cols) { push(@DialogEditVals,$dlgeditvals->{$col}); } } } else { @DialogEditVals = split('\|',$dlgeditvals); } $session->param('temp_DlgOKButton',$buttonprefix . ' ' . $label); $session->param('DialogEditVals',$dlgeditvals); } } elsif ($action =~ /^Dialog((AddUpdate)|(Delete))/) # no change to CurPage { #-----------------------------------------------------------# # use splice to ensure PageStack length is exactly 1 # #-----------------------------------------------------------# splice(@PageStack,1,10); # 10 is any large number my (@commands) = split('_cmd_', $action); if (@commands) { &processCommands(@commands); } } elsif ($action =~ /^LoggedInRoleUpdate/) # no change to CurPage { #-----------------------------------------------------------# # use splice to ensure PageStack length is exactly 1 # #-----------------------------------------------------------# splice(@PageStack,1,10); # 10 is any large number my ($action_,$roleid) = split('\|',$action); $session->param('userroleid',$roleid); my $obj = sessionObject('companyperson',$roleid); $session->param('authorization',$obj->{role}->{value}); } #-----------------------------------------------# # SUBSTEP SUPPORT # #-----------------------------------------------# #-----------------------------------------------# # CANCEL: discard all editing changes # #-----------------------------------------------# elsif ($action eq 'Home') { # delete all session variables and go to home page &ClearSession(); } #-----------------------------------------------# # ADD # #-----------------------------------------------# elsif ($action =~ /^Add\S/) # no change to CurPage { if ($specialAction =~ /^Add\|/) { my ($act,$target,@keys) = split('\|',$specialAction); my @values = (); foreach my $paramName (@keys) { push(@values,$session->param($paramName)); $session->delete($paramName); } my $paramVal = join('|',@values); $session->append($target, $paramVal); } elsif ($specialAction =~ /^AddHash\|/) # Not used, I believe { my ($paramName); my ($act,$target,@keys) = split('\|',$specialAction); my %hsh = (); foreach $paramName (@keys) { my @vals = $session->param($paramName); if (@vals >= 2) { $hsh{$paramName} = \@vals; } else { $hsh{$paramName} = $vals[0]; } } $session->append(-name=>$target,-values=>[\%hsh]); } } #-----------------------------------------------# # DELETE # #-----------------------------------------------# elsif ($action =~ /^Delete/) # no change to CurPage { my @deletions=(); my ($_action,$target,$deleteName) = split('\|',$specialAction); @deletions = $session->param($deleteName); deleteFromDB($target,@deletions); $session->delete_at_indices(-name=>$target, -values=>\@deletions); $session->delete($deleteName); } #-----------------------------------------------# # RELOAD # #-----------------------------------------------# elsif ($action =~ /^Reload/) # no change to CurPage { &deleteTempVarsk(); } #---------------------------------------------------# # Special Handling for Profile page # #---------------------------------------------------# if ($PageStack[0] eq 'person') { my $personid = $session->param('userpersonid'); my $obj = sessionObject('person',$personid); my $vbarstr = $obj->forTablePK(); @DialogEditVals = split('\|',$vbarstr); } #-----------------------------------------------# # CLOSE CURRENT SUBMISSION & RETURN TO WELCOME # #-----------------------------------------------# if ($action eq 'Home') { &ClearSession(); } my $prevPage = $CurPage; $CurPage = $PageStack[$#PageStack]; my $DisplayPage = $CurPage; ## print "CURPAGE = $CurPage\n"; ## print "PageStack = [" . join(",",@PageStack) . "]"; ## print "StateStack = [" . join(",",@StateStack) . "]"; $session->param('CurPage',$CurPage); $session->param(-name=>'PageStack',-values=>\@PageStack); $session->param(-name=>'StateStack',-values=>\@StateStack); $session->delete('specialAction'); $session->delete('dialog'); # delete all session params beginning with 'add' # $session->deletepattern('/^add/i'); if (length($dialog)) { $fbody = "$ppages/" . $dialog . ".dlg"; } else { my $substep = $session->param($CurPage . 'SubStep'); my $page = length($substep) ? $substep : $CurPage; $fbody = "$ppages/" . $page . ".html"; } my $user_agent = $session->user_agent(); my $goodbrowser = (!$user_agent) || $user_agent =~ /MSIE (\d+\.\d+)/ && $1 >= 4.0; if (0) # !$goodbrowser) { $ExceptionError = <header . $$header; }; if ($@) { $ExceptionError .= $@; } if (!$header) { my $fbody = "$ppages/" . 'exception.html'; ($header,$style,$htmloutput,$footer) = &GenerateOutput($fbody); $$header = $session->header . $$header; } else { #--------------------------------------------# # Save parameters # #--------------------------------------------# $session->delete('draftSaved'); $session->delete('ValidationErrors'); my $paramstr = $session->saveToString(); my $query=qq!select id, checkpoint from session where id=$ssn and checkpoint=0!; my $row = db_retrieve('mr',$query); if ($row) { $query = qq!update session set data='$paramstr' where id=$ssn and checkpoint=0!; } else { $query = qq!insert into session values($ssn,0,'$paramstr')!; } db_retrieve('im',$query); } print $$header; print $$style; print $$htmloutput; print $$footer; #-----------------------------------------------# # General-purpose subroutines # #-----------------------------------------------# sub GenerateOutput { my $fbody = shift; my $xbase = "http://" . $session->virtual_host() . $session->script_name(); my $header = $session->start_html( -title=>'Essential Bits Time Tracking', -xbase=>$xbase, -script=>$JSCRIPT); my $style = < STYLE # FOOTER HTML my $footer = $session->end_html . "\n"; my $htmloutput = ''; ### DEBUGGING ### ## my $paramstr = $session->saveToString; ## $ExceptionError .= $paramstr; # PRINT THE HTML BODY FROM body.html, PROCESSING LINES WITH 'perldynamic'. &PerlDynamic::printBody($fbody,\$htmloutput) if $fbody; return (\$header,\$style,\$htmloutput,\$footer); } #=========================================================== sub deleteSectionVars { my $section = shift; my ($junk,$secnum) = split(/_/,$section); $secnum .= '_'; # distinguish btwn I, II, III my @subParms = grep { $_ =~ /^$secnum/ } $prevsession->param; foreach my $subParam (@subParms) { $prevsession->delete($subParam); } } #=========================================================== sub deleteTempVars { my @subParms = grep { $_ =~ /^temp/ } $session->param; foreach my $subParam (@subParms) { $session->delete($subParam); } } #=========================================================== sub destroySubSteps { my $curstep = @_ ? shift : '###xxx###'; #---------------------------------------------------# # delete all session params ending with 'SubStep' # # except those beginning with $curstep # #---------------------------------------------------# my @subParms = grep { $_ =~ /SubStep$/ } $session->param; foreach my $subParam (@subParms) { $session->delete($subParam) unless $subParam =~ /^$curstep/; } } #=========================================================== sub ClearSession { my $ssn = $session->param('SessionNumber'); my $username = $session->param('username'); my $passwd = $session->param('password'); my $userroleid = $session->param('userroleid'); my $authorization = $session->param('authorization'); $session = new CGI(''); $session->param('SessionNumber',$ssn); $session->param('username',$username); $session->param('password',$passwd); $session->param('userroleid',$userroleid); $session->param('authorization',$authorization); my $res = &login(); # reload user parameters @PageStack = $res eq 'newuser' ? ('newuserhome') : ('home'); #-------------------------------------------------------------# # clear previous user's data with same session number, if any # #-------------------------------------------------------------# my $query = qq! delete from session where id=$ssn!; db_retrieve('im',$query); } #=========================================================== sub EditVal { my ($index,$part) = @_; return '' if !@DialogEditVals; return '' if $index > $#DialogEditVals; my $val = $DialogEditVals[$index]; if (($part =~ /(id)|(synecdoche)/) && $val =~ /$col_delim/) { my ($id,$synecdoche) = split($col_delim,$val); return $id if $part eq 'id'; return $synecdoche; } return $val; } #=========================================================== sub NextEditVal { my $skip = shift; return '' if !@DialogEditVals; while ($skip-- > 0) { shift @DialogEditVals; } return shift @DialogEditVals; } #=========================================================== # preprocess commands, then commit to database in object # dependency order, most independent first. sub processCommands { my @commands = @_; my %objhash; my %newids; while (@commands) { my $cmdstr = pop(@commands); my ($cmd,$rest) = split('\|',$cmdstr,2); SWITCH: { $cmd eq 'DialogAddUpdate' && do { my ($label,$table,$rowid,$paramVal) = split('\|',$rest,4); #-----------------------------------------------------# # $label and $rowid are ignored # # $paramVal must contain object id as first param. # # if object id is 'new' followed by '!', then we # # remember that name after the object is instantiat- # # ed with a new id, and substitute that id for the # # new! name in subsequent commands. We also have to # # save the object immediately: can't wait for later # #-----------------------------------------------------# my $newid; if ($paramVal =~ /^(new!.*?)\|/) { $newid = $1; } $paramVal =~ s/\|/$col_delim/g; foreach my $key (keys %newids) { $paramVal =~ s/$key/$newids{$key}/ge; } my $obj = $table->new($paramVal); #id =~ /^new/ for new objects if ($newid) { saveToDB($table,$obj); $newids{$newid} = $obj->{id}; } #-----------------------------------# # update in-memory session tree # #-----------------------------------# my $clean = $session->cleanobjects(); my $objid = $obj->pk(); $clean->{$table}->{$objid} = $obj; push ( @{ $objhash{$table} }, $obj) unless $newid; last SWITCH; }; $cmd eq 'DialogDelete' && do { my ($target,@deletions) = split('\|',$rest); deleteFromDB($target,@deletions); # $session->delete_at_indices(-name=>$target, -values=>\@deletions); }; # default } } #--------------------------------------------------# # save objects to database, in dependency order, # # most independent first # #--------------------------------------------------# my @objprocseq = DBObject->dependencyOrder(); foreach my $table (@objprocseq) { if (exists($objhash{$table})) { foreach my $obj ( @{ $objhash{$table} }) { saveToDB($table,$obj); } } } } #===============================================# # AUTHORIZATION ROUTINES # #===============================================# # Generate a menu of choices, based on role (admin, staff, contact, newuser) sub Menu { my $level = shift; my @ary = @SortedSteps; my $col = 0; my @rows = (); my $row = ''; while (@ary) { my $item = shift(@ary); my $label = $Steps{$item}->{label}; my @authentry = grep /$level/,@{ $Steps{$item}->{auth} }; next if !@authentry; my ($level_,$auth,$newlabel) = split(',',shift(@authentry)); $label = $newlabel if $newlabel; my $class = ''; my $clickparam = 'readonly'; if ($auth eq 'W') { $class = 'class="edit"'; $clickparam = 'write'; } $row .= qq! $label !; if (++$col == 3) { push(@rows,"$row"); $row = ''; $col = 0; } } if ($col != 0) { push(@rows,"$row"); } $includestring = join("\n",@rows); } #===============================================# # set table type to update_table or table, depending on authorization sub AuthorityTable { my $auth = $session->param('stepAuthorization'); return $auth eq 'write' ? 'update_table' : 'table'; } sub stepAuthorityWriteOK { my $auth = $session->param('stepAuthorization'); return $auth eq 'write'; }